UI - terra support
This commit is contained in:
parent
0c50e93dc0
commit
1c3b6908a9
|
@ -14,6 +14,7 @@
|
|||
"@material-ui/icons": "^4.11.2",
|
||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||
"@metamask/detect-provider": "^1.2.0",
|
||||
"@terra-money/wallet-provider": "^2.2.0",
|
||||
"@types/node": "^16.11.19",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
@ -4464,34 +4465,17 @@
|
|||
"react-dom": "^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@terra-dev/web-connector-controller": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.8.1.tgz",
|
||||
"integrity": "sha512-TIwFtta7vN2GdDUy8SbIIsfTd9XWiU+U6yjizd82yUAhlOJNAGHshG0r1j0irkA5MycYG1duAlr7foeKRu4PGA==",
|
||||
"node_modules/@terra-dev/web-extension": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-extension/-/web-extension-0.6.0.tgz",
|
||||
"integrity": "sha512-IyIWHLfweZCb5nHuMyzavnMYposnZMvpsA/89zZPIgIooxhxE//uZD+Ty+ptt4nvkbOgEFKdKIKe5rIHqgVLpA==",
|
||||
"dependencies": {
|
||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
||||
"@terra-money/terra.js": "^1.8.0 || ^2.0.0",
|
||||
"bowser": "^2.11.0",
|
||||
"rxjs": "^7.4.0"
|
||||
"rxjs": "^7.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"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": {
|
||||
|
@ -4536,27 +4520,26 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@terra-money/wallet-provider": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.5.3.tgz",
|
||||
"integrity": "sha512-v/5Z35gCo4nZyZCu3nYDFvhwuvlyDeNSSYmN9KUc9ewoIO9K/2fi3vxcOLcvqq5PYowwwod21vgaQ9QHFV+8eA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.2.0.tgz",
|
||||
"integrity": "sha512-K8NLpJ/yak8Pq6jQpjVr7yWDIbxjTp42OXaAS+xlTufqQwWbCR7coAGbm2FpYX43j4uymuSAICZvsOS1qrFeYA==",
|
||||
"dependencies": {
|
||||
"@terra-dev/browser-check": "^2.5.3",
|
||||
"@terra-dev/chrome-extension": "^2.5.3",
|
||||
"@terra-dev/readonly-wallet": "^2.5.3",
|
||||
"@terra-dev/readonly-wallet-modal": "^2.5.3",
|
||||
"@terra-dev/use-wallet": "^2.5.3",
|
||||
"@terra-dev/wallet-types": "^2.5.3",
|
||||
"@terra-dev/walletconnect": "^2.5.3",
|
||||
"@terra-dev/web-connector-controller": "^0.8.1",
|
||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
||||
"@terra-dev/browser-check": "^2.2.0",
|
||||
"@terra-dev/chrome-extension": "^2.2.0",
|
||||
"@terra-dev/readonly-wallet": "^2.2.0",
|
||||
"@terra-dev/readonly-wallet-modal": "^2.2.0",
|
||||
"@terra-dev/use-wallet": "^2.2.0",
|
||||
"@terra-dev/wallet-types": "^2.2.0",
|
||||
"@terra-dev/walletconnect": "^2.2.0",
|
||||
"@terra-dev/web-extension": "^0.6.0",
|
||||
"@terra-money/terra.js": "^2.0.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"rxjs": "^7.4.0"
|
||||
"rxjs": "^7.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@terra-money/terra.js": "^2.0.0",
|
||||
"react": "^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
|
@ -29130,22 +29113,14 @@
|
|||
"styled-components": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"@terra-dev/web-connector-controller": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.8.1.tgz",
|
||||
"integrity": "sha512-TIwFtta7vN2GdDUy8SbIIsfTd9XWiU+U6yjizd82yUAhlOJNAGHshG0r1j0irkA5MycYG1duAlr7foeKRu4PGA==",
|
||||
"@terra-dev/web-extension": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-extension/-/web-extension-0.6.0.tgz",
|
||||
"integrity": "sha512-IyIWHLfweZCb5nHuMyzavnMYposnZMvpsA/89zZPIgIooxhxE//uZD+Ty+ptt4nvkbOgEFKdKIKe5rIHqgVLpA==",
|
||||
"requires": {
|
||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
||||
"@terra-money/terra.js": "^1.8.0 || ^2.0.0",
|
||||
"bowser": "^2.11.0",
|
||||
"rxjs": "^7.4.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"
|
||||
"rxjs": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@terra-money/terra.js": {
|
||||
|
@ -29189,21 +29164,21 @@
|
|||
}
|
||||
},
|
||||
"@terra-money/wallet-provider": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.5.3.tgz",
|
||||
"integrity": "sha512-v/5Z35gCo4nZyZCu3nYDFvhwuvlyDeNSSYmN9KUc9ewoIO9K/2fi3vxcOLcvqq5PYowwwod21vgaQ9QHFV+8eA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.2.0.tgz",
|
||||
"integrity": "sha512-K8NLpJ/yak8Pq6jQpjVr7yWDIbxjTp42OXaAS+xlTufqQwWbCR7coAGbm2FpYX43j4uymuSAICZvsOS1qrFeYA==",
|
||||
"requires": {
|
||||
"@terra-dev/browser-check": "^2.5.3",
|
||||
"@terra-dev/chrome-extension": "^2.5.3",
|
||||
"@terra-dev/readonly-wallet": "^2.5.3",
|
||||
"@terra-dev/readonly-wallet-modal": "^2.5.3",
|
||||
"@terra-dev/use-wallet": "^2.5.3",
|
||||
"@terra-dev/wallet-types": "^2.5.3",
|
||||
"@terra-dev/walletconnect": "^2.5.3",
|
||||
"@terra-dev/web-connector-controller": "^0.8.1",
|
||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
||||
"@terra-dev/browser-check": "^2.2.0",
|
||||
"@terra-dev/chrome-extension": "^2.2.0",
|
||||
"@terra-dev/readonly-wallet": "^2.2.0",
|
||||
"@terra-dev/readonly-wallet-modal": "^2.2.0",
|
||||
"@terra-dev/use-wallet": "^2.2.0",
|
||||
"@terra-dev/wallet-types": "^2.2.0",
|
||||
"@terra-dev/walletconnect": "^2.2.0",
|
||||
"@terra-dev/web-extension": "^0.6.0",
|
||||
"@terra-money/terra.js": "^2.0.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"rxjs": "^7.4.0"
|
||||
"rxjs": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"@material-ui/icons": "^4.11.2",
|
||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||
"@metamask/detect-provider": "^1.2.0",
|
||||
"@terra-money/wallet-provider": "^2.2.0",
|
||||
"@types/node": "^16.11.19",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
|
|
@ -16,17 +16,21 @@ const useStyles = makeStyles((theme) => ({
|
|||
export default function TransactionProgress({
|
||||
chainId,
|
||||
txBlockNumber,
|
||||
step,
|
||||
isSourceSwapComplete,
|
||||
hasSignedVAA,
|
||||
isTargetSwapComplete,
|
||||
}: {
|
||||
chainId: ChainId;
|
||||
txBlockNumber: number | undefined;
|
||||
step: number;
|
||||
isSourceSwapComplete: boolean;
|
||||
hasSignedVAA: boolean;
|
||||
isTargetSwapComplete: boolean;
|
||||
}) {
|
||||
const classes = useStyles();
|
||||
const { provider } = useEthereumProvider();
|
||||
const [currentBlock, setCurrentBlock] = useState(0);
|
||||
useEffect(() => {
|
||||
if (step !== 1 || !txBlockNumber) return;
|
||||
if (hasSignedVAA || !txBlockNumber) return;
|
||||
if (isEVMChain(chainId) && provider) {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
|
@ -46,7 +50,7 @@ export default function TransactionProgress({
|
|||
cancelled = true;
|
||||
};
|
||||
}
|
||||
}, [step, chainId, provider, txBlockNumber]);
|
||||
}, [hasSignedVAA, chainId, provider, txBlockNumber]);
|
||||
const blockDiff =
|
||||
txBlockNumber !== undefined && txBlockNumber && currentBlock
|
||||
? currentBlock - txBlockNumber
|
||||
|
@ -55,24 +59,20 @@ export default function TransactionProgress({
|
|||
let value;
|
||||
let valueBuffer;
|
||||
let message;
|
||||
switch (step) {
|
||||
case 1:
|
||||
if (!hasSignedVAA) {
|
||||
value = (blockDiff / expectedBlocks) * 50;
|
||||
valueBuffer = 50;
|
||||
message = `Waiting for ${blockDiff} / ${expectedBlocks} confirmations on ${
|
||||
chainId === CHAIN_ID_POLYGON ? "Polygon" : "Ethereum"
|
||||
}...`;
|
||||
break;
|
||||
case 2:
|
||||
} else if (!isTargetSwapComplete) {
|
||||
value = 50;
|
||||
valueBuffer = 100;
|
||||
message = "Waiting for relayer to complete swap...";
|
||||
break;
|
||||
case 3:
|
||||
} else {
|
||||
value = 100;
|
||||
valueBuffer = 100;
|
||||
message = "";
|
||||
break;
|
||||
message = "Success!";
|
||||
}
|
||||
return (
|
||||
<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 { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||
// import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
||||
|
@ -31,6 +37,8 @@ function useIsWalletReady(
|
|||
const autoSwitch = enableNetworkAutoswitch;
|
||||
// const solanaWallet = useSolanaWallet();
|
||||
// const solPK = solanaWallet?.publicKey;
|
||||
const terraWallet = useConnectedWallet();
|
||||
const hasTerraWallet = !!terraWallet;
|
||||
const {
|
||||
provider,
|
||||
signerAddress,
|
||||
|
@ -54,6 +62,20 @@ function useIsWalletReady(
|
|||
}, [provider, correctEvmNetwork, chainId]);
|
||||
|
||||
return useMemo(() => {
|
||||
if (
|
||||
chainId === CHAIN_ID_TERRA &&
|
||||
hasTerraWallet &&
|
||||
terraWallet?.walletAddress
|
||||
) {
|
||||
// TODO: terraWallet does not update on wallet changes
|
||||
return createWalletStatus(
|
||||
true,
|
||||
undefined,
|
||||
forceNetworkSwitch,
|
||||
terraWallet.walletAddress
|
||||
);
|
||||
}
|
||||
if (isEVMChain(chainId) && hasEthInfo && signerAddress) {
|
||||
//if (chainId === CHAIN_ID_SOLANA && solPK) {
|
||||
// return createWalletStatus(
|
||||
// true,
|
||||
|
@ -62,7 +84,6 @@ function useIsWalletReady(
|
|||
// solPK.toString()
|
||||
// );
|
||||
//}
|
||||
if (isEVMChain(chainId) && hasEthInfo && signerAddress) {
|
||||
if (hasCorrectEvmNetwork) {
|
||||
return createWalletStatus(
|
||||
true,
|
||||
|
@ -93,12 +114,14 @@ function useIsWalletReady(
|
|||
chainId,
|
||||
autoSwitch,
|
||||
forceNetworkSwitch,
|
||||
hasTerraWallet,
|
||||
// solPK,
|
||||
hasEthInfo,
|
||||
correctEvmNetwork,
|
||||
hasCorrectEvmNetwork,
|
||||
provider,
|
||||
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 ErrorBoundary from "./components/ErrorBoundary";
|
||||
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
|
||||
import { TerraWalletProvider } from "./contexts/TerraWalletContext";
|
||||
import { theme } from "./muiTheme";
|
||||
|
||||
ReactDOM.render(
|
||||
|
@ -12,9 +13,11 @@ ReactDOM.render(
|
|||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline>
|
||||
<EthereumProviderProvider>
|
||||
<TerraWalletProvider>
|
||||
<SnackbarProvider maxSnack={3}>
|
||||
<App />
|
||||
</SnackbarProvider>
|
||||
</TerraWalletProvider>
|
||||
</EthereumProviderProvider>
|
||||
</CssBaseline>
|
||||
</ThemeProvider>
|
||||
|
|
|
@ -7,9 +7,6 @@ import {
|
|||
WETH_TOKEN_INFO,
|
||||
WMATIC_TOKEN_INFO,
|
||||
UST_TOKEN_INFO,
|
||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
WORMHOLE_CHAIN_ID_POLYGON,
|
||||
WORMHOLE_CHAIN_ID_TERRA,
|
||||
} from "../utils/consts";
|
||||
import { addFixedAmounts, subtractFixedAmounts } from "../utils/math";
|
||||
import { UstLocation } from "./generic";
|
||||
|
@ -19,7 +16,12 @@ import {
|
|||
makeExactInParameters,
|
||||
makeExactOutParameters,
|
||||
} 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_V3 } from "./uniswap-v3";
|
||||
|
@ -57,13 +59,13 @@ export function makeEvmProviderFromAddress(tokenAddress: string) {
|
|||
export function getChainIdFromAddress(tokenAddress: string) {
|
||||
switch (tokenAddress) {
|
||||
case WETH_TOKEN_INFO.address: {
|
||||
return WORMHOLE_CHAIN_ID_ETHEREUM;
|
||||
return CHAIN_ID_ETH;
|
||||
}
|
||||
case WMATIC_TOKEN_INFO.address: {
|
||||
return WORMHOLE_CHAIN_ID_POLYGON;
|
||||
return CHAIN_ID_POLYGON;
|
||||
}
|
||||
case UST_TOKEN_INFO.address: {
|
||||
return WORMHOLE_CHAIN_ID_TERRA;
|
||||
return CHAIN_ID_TERRA;
|
||||
}
|
||||
default: {
|
||||
throw Error("unrecognized evm token address");
|
||||
|
@ -110,16 +112,16 @@ export interface RelayerFee {
|
|||
export interface ExactInCrossParameters {
|
||||
amountIn: string;
|
||||
minAmountOut: string;
|
||||
src: ExactInParameters;
|
||||
dst: ExactInParameters;
|
||||
src: ExactInParameters | undefined;
|
||||
dst: ExactInParameters | undefined;
|
||||
relayerFee: RelayerFee;
|
||||
}
|
||||
|
||||
export interface ExactOutCrossParameters {
|
||||
amountOut: string;
|
||||
maxAmountIn: string;
|
||||
src: ExactOutParameters;
|
||||
dst: ExactOutParameters;
|
||||
src: ExactOutParameters | undefined;
|
||||
dst: ExactOutParameters | undefined;
|
||||
relayerFee: RelayerFee;
|
||||
}
|
||||
|
||||
|
@ -132,22 +134,16 @@ export class UniswapToUniswapQuoter {
|
|||
srcRouter: UstRouter | EthRouter | MaticRouter;
|
||||
dstRouter: UstRouter | EthRouter | MaticRouter;
|
||||
|
||||
constructor() {}
|
||||
|
||||
async initialize(
|
||||
tokenInAddress: string,
|
||||
tokenOutAddress: string
|
||||
): Promise<void> {
|
||||
async initialize(tokenInAddress: string, tokenOutAddress: string) {
|
||||
if (tokenInAddress !== this.tokenInAddress) {
|
||||
this.tokenInAddress = tokenInAddress;
|
||||
this.srcRouter = await makeRouter(tokenInAddress, UstLocation.Out);
|
||||
}
|
||||
|
||||
if (tokenOutAddress != this.tokenOutAddress) {
|
||||
if (tokenOutAddress !== this.tokenOutAddress) {
|
||||
this.tokenOutAddress = tokenOutAddress;
|
||||
this.dstRouter = await makeRouter(tokenOutAddress, UstLocation.In);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
async computeAndVerifySrcPoolAddress(): Promise<string> {
|
||||
|
@ -158,7 +154,7 @@ export class UniswapToUniswapQuoter {
|
|||
return this.dstRouter.computeAndVerifyPoolAddress();
|
||||
}
|
||||
|
||||
computeSwapSlippage(slippage): string {
|
||||
computeSwapSlippage(slippage: string): string {
|
||||
if (this.isSrcUst() || this.isDstUst()) {
|
||||
return slippage;
|
||||
}
|
||||
|
@ -184,7 +180,7 @@ export class UniswapToUniswapQuoter {
|
|||
makeSrcExactInParameters(
|
||||
amountIn: string,
|
||||
minAmountOut: string
|
||||
): ExactInParameters {
|
||||
): ExactInParameters | undefined {
|
||||
if (this.isSrcUst()) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -195,7 +191,7 @@ export class UniswapToUniswapQuoter {
|
|||
makeDstExactInParameters(
|
||||
amountIn: string,
|
||||
minAmountOut: string
|
||||
): ExactInParameters {
|
||||
): ExactInParameters | undefined {
|
||||
if (this.isDstUst()) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -251,9 +247,9 @@ export class UniswapToUniswapQuoter {
|
|||
makeSrcExactOutParameters(
|
||||
amountOut: string,
|
||||
maxAmountIn: string
|
||||
): ExactOutParameters {
|
||||
): ExactOutParameters | undefined {
|
||||
if (this.isSrcUst()) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
// @ts-ignore
|
||||
return makeExactOutParameters(this.srcRouter, amountOut, maxAmountIn);
|
||||
|
@ -262,9 +258,9 @@ export class UniswapToUniswapQuoter {
|
|||
makeDstExactOutParameters(
|
||||
amountOut: string,
|
||||
maxAmountIn: string
|
||||
): ExactOutParameters {
|
||||
): ExactOutParameters | undefined {
|
||||
if (this.isDstUst()) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
// @ts-ignore
|
||||
return makeExactOutParameters(this.dstRouter, amountOut, maxAmountIn);
|
||||
|
@ -337,7 +333,7 @@ export class UniswapToUniswapQuoter {
|
|||
return this.tokenOutAddress === TERRA_UST;
|
||||
}
|
||||
|
||||
getSrcEvmProvider(): ethers.providers.Provider {
|
||||
getSrcEvmProvider(): ethers.providers.Provider | undefined {
|
||||
if (this.isSrcUst()) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -345,7 +341,7 @@ export class UniswapToUniswapQuoter {
|
|||
return this.srcRouter.getProvider();
|
||||
}
|
||||
|
||||
getDstEvmProvider(): ethers.providers.Provider {
|
||||
getDstEvmProvider(): ethers.providers.Provider | undefined {
|
||||
if (this.isDstUst()) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ethers } from "ethers";
|
|||
import { GenericToken } from "./generic";
|
||||
|
||||
// erc20 spec
|
||||
import { abi as Erc20Abi } from "../../abi/erc20.json";
|
||||
import { abi as Erc20Abi } from "../abi/erc20.json";
|
||||
import {
|
||||
TransactionReceipt,
|
||||
TransactionRequest,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//@ts-nocheck
|
||||
import { ethers } from "ethers";
|
||||
import { CurrencyAmount, Token } from "@uniswap/sdk-core";
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
//@ts-nocheck
|
||||
import { ethers } from "ethers";
|
||||
import { TransactionReceipt } from "@ethersproject/abstract-provider";
|
||||
import {
|
||||
ChainId,
|
||||
CHAIN_ID_ETH,
|
||||
CHAIN_ID_POLYGON,
|
||||
CHAIN_ID_TERRA,
|
||||
getEmitterAddressEth,
|
||||
hexToUint8Array,
|
||||
nativeToHexString,
|
||||
parseSequenceFromLogEth,
|
||||
//getSignedVAAWithRetry,
|
||||
getSignedVAAWithRetry,
|
||||
} from "@certusone/wormhole-sdk";
|
||||
import getSignedVAAWithRetry from "@certusone/wormhole-sdk/lib/cjs/rpc/getSignedVAAWithRetry";
|
||||
import { grpc } from "@improbable-eng/grpc-web";
|
||||
import { UniEvmToken } from "../route/uniswap-core";
|
||||
import {
|
||||
|
@ -26,9 +29,6 @@ import {
|
|||
CORE_BRIDGE_ADDRESS_ETHEREUM,
|
||||
CORE_BRIDGE_ADDRESS_POLYGON,
|
||||
CORE_BRIDGE_ADDRESS_TERRA,
|
||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
WORMHOLE_CHAIN_ID_POLYGON,
|
||||
WORMHOLE_CHAIN_ID_TERRA,
|
||||
WORMHOLE_RPC_HOSTS,
|
||||
//ETH_NETWORK_CHAIN_ID,
|
||||
//POLYGON_NETWORK_CHAIN_ID,
|
||||
|
@ -44,10 +44,10 @@ import {
|
|||
swapExactOutFromVaaNative,
|
||||
swapExactOutFromVaaToken,
|
||||
} from "./util";
|
||||
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 { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM } from "../../scripts/contract-addresses/goerli";
|
||||
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON } from "../../scripts/contract-addresses/mumbai";
|
||||
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 { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM } from "../addresses/goerli";
|
||||
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON } from "../addresses/mumbai";
|
||||
|
||||
// placeholders
|
||||
const CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA = "";
|
||||
|
@ -72,7 +72,7 @@ const EXECUTION_PARAMETERS_ETHEREUM: ExecutionParameters = {
|
|||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM,
|
||||
},
|
||||
wormhole: {
|
||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
chainId: CHAIN_ID_ETH,
|
||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_ETHEREUM,
|
||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_ETHEREUM,
|
||||
},
|
||||
|
@ -83,7 +83,7 @@ const EXECUTION_PARAMETERS_POLYGON: ExecutionParameters = {
|
|||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON,
|
||||
},
|
||||
wormhole: {
|
||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
||||
chainId: CHAIN_ID_POLYGON,
|
||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_POLYGON,
|
||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_POLYGON,
|
||||
},
|
||||
|
@ -94,7 +94,7 @@ const EXECUTION_PARAMETERS_TERRA: ExecutionParameters = {
|
|||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA,
|
||||
},
|
||||
wormhole: {
|
||||
chainId: WORMHOLE_CHAIN_ID_TERRA,
|
||||
chainId: CHAIN_ID_TERRA,
|
||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_TERRA,
|
||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_TERRA,
|
||||
},
|
||||
|
@ -102,13 +102,13 @@ const EXECUTION_PARAMETERS_TERRA: ExecutionParameters = {
|
|||
|
||||
function makeExecutionParameters(chainId: ChainId): ExecutionParameters {
|
||||
switch (chainId) {
|
||||
case WORMHOLE_CHAIN_ID_ETHEREUM: {
|
||||
case CHAIN_ID_ETH: {
|
||||
return EXECUTION_PARAMETERS_ETHEREUM;
|
||||
}
|
||||
case WORMHOLE_CHAIN_ID_POLYGON: {
|
||||
case CHAIN_ID_POLYGON: {
|
||||
return EXECUTION_PARAMETERS_POLYGON;
|
||||
}
|
||||
case WORMHOLE_CHAIN_ID_TERRA: {
|
||||
case CHAIN_ID_TERRA: {
|
||||
return EXECUTION_PARAMETERS_TERRA;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
import {
|
||||
ChainId,
|
||||
CHAIN_ID_ETH as WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
CHAIN_ID_POLYGON as WORMHOLE_CHAIN_ID_POLYGON,
|
||||
CHAIN_ID_TERRA as WORMHOLE_CHAIN_ID_TERRA,
|
||||
CHAIN_ID_ETH,
|
||||
CHAIN_ID_POLYGON,
|
||||
CHAIN_ID_TERRA,
|
||||
} from "@certusone/wormhole-sdk";
|
||||
//import ethIcon from "../icons/eth.svg";
|
||||
//import polygonIcon from "../icons/polygon.svg";
|
||||
|
||||
const ethIcon = undefined;
|
||||
const polygonIcon = undefined;
|
||||
const ustIcon = undefined;
|
||||
|
||||
export {
|
||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
WORMHOLE_CHAIN_ID_POLYGON,
|
||||
WORMHOLE_CHAIN_ID_TERRA,
|
||||
};
|
||||
import ethIcon from "../icons/eth.svg";
|
||||
import polygonIcon from "../icons/polygon.svg";
|
||||
import terraIcon from "../icons/terra.svg";
|
||||
|
||||
export interface TokenInfo {
|
||||
name: string;
|
||||
|
@ -24,13 +15,13 @@ export interface TokenInfo {
|
|||
logo: string;
|
||||
isNative: boolean;
|
||||
maxAmount: number;
|
||||
ustPairedAddress: string;
|
||||
ustPairedAddress: string | undefined;
|
||||
}
|
||||
|
||||
export const MATIC_TOKEN_INFO: TokenInfo = {
|
||||
name: "MATIC",
|
||||
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889", // used to compute quote
|
||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
||||
chainId: CHAIN_ID_POLYGON,
|
||||
logo: polygonIcon,
|
||||
isNative: true,
|
||||
maxAmount: 0.1,
|
||||
|
@ -40,7 +31,7 @@ export const MATIC_TOKEN_INFO: TokenInfo = {
|
|||
export const WMATIC_TOKEN_INFO: TokenInfo = {
|
||||
name: "WMATIC",
|
||||
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889",
|
||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
||||
chainId: CHAIN_ID_POLYGON,
|
||||
logo: polygonIcon,
|
||||
isNative: false,
|
||||
maxAmount: 0.1,
|
||||
|
@ -50,7 +41,7 @@ export const WMATIC_TOKEN_INFO: TokenInfo = {
|
|||
export const ETH_TOKEN_INFO: TokenInfo = {
|
||||
name: "ETH",
|
||||
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", // used to compute quote
|
||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
chainId: CHAIN_ID_ETH,
|
||||
logo: ethIcon,
|
||||
isNative: true,
|
||||
maxAmount: 0.01,
|
||||
|
@ -60,7 +51,7 @@ export const ETH_TOKEN_INFO: TokenInfo = {
|
|||
export const WETH_TOKEN_INFO: TokenInfo = {
|
||||
name: "WETH",
|
||||
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
|
||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
||||
chainId: CHAIN_ID_ETH,
|
||||
logo: ethIcon,
|
||||
isNative: false,
|
||||
maxAmount: 0.01,
|
||||
|
@ -70,9 +61,9 @@ export const WETH_TOKEN_INFO: TokenInfo = {
|
|||
export const UST_TOKEN_INFO: TokenInfo = {
|
||||
name: "UST",
|
||||
address: "uusd",
|
||||
chainId: WORMHOLE_CHAIN_ID_TERRA,
|
||||
logo: ustIcon,
|
||||
isNative: false,
|
||||
chainId: CHAIN_ID_TERRA,
|
||||
logo: terraIcon,
|
||||
isNative: true, // TODO: change?
|
||||
maxAmount: 10.0,
|
||||
ustPairedAddress: undefined,
|
||||
};
|
||||
|
@ -85,18 +76,33 @@ export const TOKEN_INFOS = [
|
|||
UST_TOKEN_INFO,
|
||||
];
|
||||
|
||||
// evm handling
|
||||
export const EVM_ETH_NETWORK_CHAIN_ID = 5;
|
||||
export const EVM_POLYGON_NETWORK_CHAIN_ID = 80001;
|
||||
export const getSupportedSwaps = (tokenInfo: TokenInfo) => {
|
||||
switch (tokenInfo) {
|
||||
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) =>
|
||||
chainId === WORMHOLE_CHAIN_ID_ETHEREUM
|
||||
? EVM_ETH_NETWORK_CHAIN_ID
|
||||
: chainId === WORMHOLE_CHAIN_ID_POLYGON
|
||||
? EVM_POLYGON_NETWORK_CHAIN_ID
|
||||
chainId === CHAIN_ID_ETH
|
||||
? ETH_NETWORK_CHAIN_ID
|
||||
: chainId === CHAIN_ID_POLYGON
|
||||
? POLYGON_NETWORK_CHAIN_ID
|
||||
: undefined;
|
||||
|
||||
// misc
|
||||
export const RELAYER_FEE_UST = "0.25";
|
||||
|
||||
export const WORMHOLE_RPC_HOSTS = [
|
||||
|
|
|
@ -6,7 +6,7 @@ export function addFixedAmounts(
|
|||
decimals: number
|
||||
): string {
|
||||
const sum = FixedNumber.from(left).addUnsafe(FixedNumber.from(right));
|
||||
return sum.round(this.getDecimals()).toString();
|
||||
return sum.round(decimals).toString();
|
||||
}
|
||||
|
||||
export function subtractFixedAmounts(
|
||||
|
|
|
@ -7,7 +7,12 @@ import {
|
|||
TextField,
|
||||
Typography,
|
||||
} 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 ButtonWithLoader from "../components/ButtonWithLoader";
|
||||
import EthereumSignerKey from "../components/EthereumSignerKey";
|
||||
|
@ -16,11 +21,11 @@ import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
|||
import {
|
||||
ETH_TOKEN_INFO,
|
||||
getEvmChainId,
|
||||
getSupportedSwaps,
|
||||
MATIC_TOKEN_INFO,
|
||||
RELAYER_FEE_UST,
|
||||
TokenInfo,
|
||||
TOKEN_INFOS,
|
||||
WETH_TOKEN_INFO,
|
||||
WMATIC_TOKEN_INFO,
|
||||
WORMHOLE_RPC_HOSTS,
|
||||
} from "../utils/consts";
|
||||
import { COLORS } from "../muiTheme";
|
||||
|
@ -34,9 +39,15 @@ import parseError from "../utils/parseError";
|
|||
import Settings from "../components/Settings";
|
||||
import getIsTransferCompletedEvmWithRetry from "../utils/getIsTransferCompletedWithRetry";
|
||||
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 Footer from "../components/Footer";
|
||||
import TerraWalletKey from "../components/TerraWalletKey";
|
||||
import useIsWalletReady from "../hooks/useIsWalletReady";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
bg: {
|
||||
|
@ -135,7 +146,7 @@ const useStyles = makeStyles((theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
const switchProviderNetwork = async (
|
||||
const switchEvmProviderNetwork = async (
|
||||
provider: Web3Provider,
|
||||
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() {
|
||||
const classes = useStyles();
|
||||
const [sourceTokenInfo, setSourceTokenInfo] = useState(MATIC_TOKEN_INFO);
|
||||
|
@ -169,14 +248,16 @@ export default function Home() {
|
|||
const [hasQuote, setHasQuote] = useState(false);
|
||||
const { provider, signer } = useEthereumProvider();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const [isFirstSwapComplete, setIsFirstSwapComplete] = useState(false);
|
||||
const [isSecondSwapComplete, setIsSecondSwapComplete] = useState(false);
|
||||
const [isSourceSwapComplete, setIsSourceSwapComplete] = useState(false);
|
||||
const [isTargetSwapComplete, setIsTargetSwapComplete] = useState(false);
|
||||
const [sourceTxBlockNumber, setSourceTxBlockNumber] = useState<
|
||||
number | undefined
|
||||
>(undefined);
|
||||
const [hasSignedVAA, setHasSignedVAA] = useState(false);
|
||||
const [relayerTimeoutString, setRelayerTimeoutString] = useState("");
|
||||
|
||||
const foo = useIsWalletReady(sourceTokenInfo.chainId);
|
||||
|
||||
const computeQuote = useCallback(() => {
|
||||
(async () => {
|
||||
setHasQuote(false);
|
||||
|
@ -205,10 +286,15 @@ export default function Home() {
|
|||
executor.setSlippage((parseFloat(slippage) / 100).toString());
|
||||
executor.setRelayerFee(RELAYER_FEE_UST);
|
||||
const quote = await executor.computeQuoteExactIn(amountIn);
|
||||
// TODO: FIX
|
||||
if (!quote || !quote.dst) {
|
||||
throw new Error("failed to compute quote");
|
||||
}
|
||||
setExecutor(executor);
|
||||
setAmountOut(
|
||||
parseFloat(
|
||||
executor.tokens.dstOut.formatAmount(quote.dst.minAmountOut)
|
||||
// executor.tokens.dstOut.formatAmount(quote.dst.minAmountOut)
|
||||
quote.minAmountOut
|
||||
).toFixed(8)
|
||||
);
|
||||
setAmountInUST(
|
||||
|
@ -260,30 +346,38 @@ export default function Home() {
|
|||
setDeadline(deadline);
|
||||
}, []);
|
||||
|
||||
const handleSourceChange = useCallback((event) => {
|
||||
// NOTE: only native-to-native or wrapped-to-wrapped swaps are currently supported
|
||||
if (event.target.value === WMATIC_TOKEN_INFO.name) {
|
||||
setSourceTokenInfo(WMATIC_TOKEN_INFO);
|
||||
setTargetTokenInfo(WETH_TOKEN_INFO);
|
||||
} else if (event.target.value === WETH_TOKEN_INFO.name) {
|
||||
setSourceTokenInfo(WETH_TOKEN_INFO);
|
||||
setTargetTokenInfo(WMATIC_TOKEN_INFO);
|
||||
} else if (event.target.value === ETH_TOKEN_INFO.name) {
|
||||
setSourceTokenInfo(ETH_TOKEN_INFO);
|
||||
setTargetTokenInfo(MATIC_TOKEN_INFO);
|
||||
} else {
|
||||
setSourceTokenInfo(MATIC_TOKEN_INFO);
|
||||
setTargetTokenInfo(ETH_TOKEN_INFO);
|
||||
const handleSourceChange = useCallback(
|
||||
(event) => {
|
||||
const tokenInfo = TOKEN_INFOS.find((x) => x.name === event.target.value);
|
||||
if (tokenInfo) {
|
||||
const supportedSwaps = getSupportedSwaps(tokenInfo);
|
||||
console.log(supportedSwaps);
|
||||
if (supportedSwaps) {
|
||||
setSourceTokenInfo(tokenInfo);
|
||||
if (!supportedSwaps.find((x) => x.name === targetTokenInfo.name)) {
|
||||
setTargetTokenInfo(supportedSwaps[0]);
|
||||
}
|
||||
setAmountIn("");
|
||||
setAmountOut("");
|
||||
}
|
||||
}
|
||||
},
|
||||
[targetTokenInfo]
|
||||
);
|
||||
|
||||
const handleTargetChange = useCallback((event) => {
|
||||
const tokenInfo = TOKEN_INFOS.find((x) => x.name === event.target.value);
|
||||
if (tokenInfo) {
|
||||
setTargetTokenInfo(tokenInfo);
|
||||
setAmountOut("");
|
||||
}
|
||||
}, []);
|
||||
|
||||
const reset = useCallback(() => {
|
||||
setIsSwapping(false);
|
||||
setHasQuote(false);
|
||||
setIsFirstSwapComplete(false);
|
||||
setIsSecondSwapComplete(false);
|
||||
setIsSourceSwapComplete(false);
|
||||
setIsTargetSwapComplete(false);
|
||||
setAmountIn("");
|
||||
setAmountOut("");
|
||||
setSourceTxBlockNumber(undefined);
|
||||
|
@ -294,18 +388,19 @@ export default function Home() {
|
|||
if (provider && signer && executor) {
|
||||
try {
|
||||
setIsSwapping(true);
|
||||
setIsFirstSwapComplete(false);
|
||||
setIsSourceSwapComplete(false);
|
||||
setHasSignedVAA(false);
|
||||
setIsSecondSwapComplete(false);
|
||||
setIsTargetSwapComplete(false);
|
||||
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(
|
||||
"firstSwapTransactionHash:",
|
||||
sourceReceipt.transactionHash
|
||||
);
|
||||
setIsFirstSwapComplete(true);
|
||||
setIsSourceSwapComplete(true);
|
||||
setSourceTxBlockNumber(sourceReceipt.blockNumber);
|
||||
|
||||
// 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
|
||||
const isCompleted = await getIsTransferCompletedEvmWithRetry(
|
||||
executor.dstExecutionParams.wormhole.tokenBridgeAddress,
|
||||
executor.quoter.dstProvider,
|
||||
// TODO: fix
|
||||
//@ts-ignore
|
||||
executor.quoter.getDstEvmProvider(),
|
||||
vaaBytes,
|
||||
// retry for two minutes
|
||||
3000,
|
||||
|
@ -330,14 +427,14 @@ export default function Home() {
|
|||
setRelayerTimeoutString(
|
||||
"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);
|
||||
console.info(
|
||||
"secondSwapTransactionHash:",
|
||||
targetReceipt.transactionHash
|
||||
);
|
||||
}
|
||||
setIsSecondSwapComplete(true);
|
||||
setIsTargetSwapComplete(true);
|
||||
} catch (e: any) {
|
||||
reset();
|
||||
console.error(e);
|
||||
|
@ -357,6 +454,7 @@ export default function Home() {
|
|||
]);
|
||||
|
||||
const readyToSwap = provider && signer && hasQuote;
|
||||
const disableSelect = isSwapping || isComputingQuote;
|
||||
|
||||
return (
|
||||
<div className={classes.bg}>
|
||||
|
@ -367,9 +465,9 @@ export default function Home() {
|
|||
</Typography>
|
||||
<div className={classes.spacer} />
|
||||
<Paper className={classes.mainPaper}>
|
||||
<Collapse in={!isFirstSwapComplete}>
|
||||
<Collapse in={!isSourceSwapComplete}>
|
||||
<Settings
|
||||
disabled={isSwapping || isComputingQuote}
|
||||
disabled={disableSelect}
|
||||
slippage={slippage}
|
||||
deadline={deadline}
|
||||
onSlippageChange={handleSlippageChange}
|
||||
|
@ -379,13 +477,13 @@ export default function Home() {
|
|||
tokens={TOKEN_INFOS}
|
||||
value={sourceTokenInfo.name}
|
||||
onChange={handleSourceChange}
|
||||
disabled={isSwapping || isComputingQuote}
|
||||
disabled={disableSelect}
|
||||
></TokenSelect>
|
||||
<Typography variant="subtitle1">Send</Typography>
|
||||
<TextField
|
||||
type="number"
|
||||
value={amountIn}
|
||||
disabled={isSwapping || isComputingQuote}
|
||||
disabled={disableSelect}
|
||||
InputProps={{ disableUnderline: true }}
|
||||
className={classes.numberField}
|
||||
onChange={handleAmountChange}
|
||||
|
@ -397,12 +495,13 @@ export default function Home() {
|
|||
color="error"
|
||||
>{`The max input amount is ${sourceTokenInfo.maxAmount} ${sourceTokenInfo.name}`}</Typography>
|
||||
) : null}
|
||||
<ConnectedWalletAddress chainId={sourceTokenInfo.chainId} />
|
||||
<div className={classes.spacer} />
|
||||
<TokenSelect
|
||||
tokens={TOKEN_INFOS}
|
||||
tokens={getSupportedSwaps(sourceTokenInfo)}
|
||||
value={targetTokenInfo.name}
|
||||
onChange={() => {}}
|
||||
disabled={true}
|
||||
onChange={handleTargetChange}
|
||||
disabled={disableSelect}
|
||||
></TokenSelect>
|
||||
<Typography variant="subtitle1">Receive (estimated)</Typography>
|
||||
<TextField
|
||||
|
@ -414,10 +513,20 @@ export default function Home() {
|
|||
inputProps={{ readOnly: true }}
|
||||
placeholder="0.0"
|
||||
></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">{`Relayer fee: ${RELAYER_FEE_UST} UST`}</Typography>
|
||||
{!isSwapping && <EthereumSignerKey />}
|
||||
<ButtonWithLoader
|
||||
<SwapButton
|
||||
source={sourceTokenInfo}
|
||||
target={targetTokenInfo}
|
||||
disabled={
|
||||
!readyToSwap ||
|
||||
isSwapping ||
|
||||
|
@ -425,11 +534,9 @@ export default function Home() {
|
|||
}
|
||||
showLoader={isSwapping}
|
||||
onClick={handleSwapClick}
|
||||
>
|
||||
Swap
|
||||
</ButtonWithLoader>
|
||||
/>
|
||||
</Collapse>
|
||||
<Collapse in={isFirstSwapComplete && !isSecondSwapComplete}>
|
||||
<Collapse in={isSourceSwapComplete && !isTargetSwapComplete}>
|
||||
<div className={classes.loaderHolder}>
|
||||
<CircleLoader />
|
||||
<div className={classes.spacer} />
|
||||
|
@ -438,14 +545,14 @@ export default function Home() {
|
|||
</Typography>
|
||||
</div>
|
||||
</Collapse>
|
||||
<Collapse in={isSecondSwapComplete}>
|
||||
<Collapse in={isTargetSwapComplete}>
|
||||
<div className={classes.loaderHolder}>
|
||||
<CheckCircleOutlineRounded
|
||||
className={classes.successIcon}
|
||||
fontSize={"inherit"}
|
||||
/>
|
||||
<Typography>Swap completed!</Typography>
|
||||
<ButtonWithLoader onClick={() => reset()}>
|
||||
<ButtonWithLoader onClick={reset}>
|
||||
Swap more tokens!
|
||||
</ButtonWithLoader>
|
||||
</div>
|
||||
|
@ -460,19 +567,23 @@ export default function Home() {
|
|||
{`${amountOut} ${targetTokenInfo.name}`}
|
||||
</Typography>
|
||||
)}
|
||||
{isFirstSwapComplete &&
|
||||
!isSecondSwapComplete &&
|
||||
{isSourceSwapComplete &&
|
||||
!isTargetSwapComplete &&
|
||||
!relayerTimeoutString && (
|
||||
<>
|
||||
<SwapProgress
|
||||
chainId={sourceTokenInfo.chainId}
|
||||
txBlockNumber={sourceTxBlockNumber}
|
||||
step={!hasSignedVAA ? 1 : !isSecondSwapComplete ? 2 : 3}
|
||||
isSourceSwapComplete={isSourceSwapComplete}
|
||||
hasSignedVAA={hasSignedVAA}
|
||||
isTargetSwapComplete={isTargetSwapComplete}
|
||||
/>
|
||||
<div className={classes.spacer} />
|
||||
</>
|
||||
)}
|
||||
{relayerTimeoutString && (
|
||||
<Typography variant="subtitle1">{relayerTimeoutString}</Typography>
|
||||
)}
|
||||
<div className={classes.spacer} />
|
||||
<Typography variant="subtitle2" color="error">
|
||||
WARNING: this is a Testnet release only
|
||||
</Typography>
|
||||
|
|
Loading…
Reference in New Issue