bridge_ui: wrapped to wrapped
Change-Id: Icb12978ce7be6cc468d650039f508fc8ad19babe
This commit is contained in:
parent
a79ef81721
commit
42702dfbe8
|
@ -10,29 +10,32 @@ import {
|
|||
} from "../../store/attestSlice";
|
||||
import {
|
||||
selectAttestSignedVAAHex,
|
||||
selectTransferSourceAsset,
|
||||
selectTransferSourceChain,
|
||||
selectTransferOriginAsset,
|
||||
selectTransferOriginChain,
|
||||
selectTransferTargetChain,
|
||||
} from "../../store/selectors";
|
||||
import { hexToNativeString } from "../../utils/array";
|
||||
|
||||
export default function RegisterNowButton() {
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const sourceChain = useSelector(selectTransferSourceChain);
|
||||
const sourceAsset = useSelector(selectTransferSourceAsset);
|
||||
const originChain = useSelector(selectTransferOriginChain);
|
||||
const originAsset = useSelector(selectTransferOriginAsset);
|
||||
const targetChain = useSelector(selectTransferTargetChain);
|
||||
// user might be in the middle of a different attest
|
||||
const signedVAAHex = useSelector(selectAttestSignedVAAHex);
|
||||
const canSwitch = sourceAsset && !signedVAAHex;
|
||||
const canSwitch = originChain && originAsset && !signedVAAHex;
|
||||
const handleClick = useCallback(() => {
|
||||
if (sourceAsset && canSwitch) {
|
||||
dispatch(setSourceChain(sourceChain));
|
||||
dispatch(setSourceAsset(sourceAsset));
|
||||
const nativeAsset =
|
||||
originChain && hexToNativeString(originAsset, originChain);
|
||||
if (originChain && originAsset && nativeAsset && canSwitch) {
|
||||
dispatch(setSourceChain(originChain));
|
||||
dispatch(setSourceAsset(nativeAsset));
|
||||
dispatch(setTargetChain(targetChain));
|
||||
dispatch(setStep(2));
|
||||
history.push("/register");
|
||||
}
|
||||
}, [dispatch, canSwitch, sourceChain, sourceAsset, targetChain, history]);
|
||||
}, [dispatch, canSwitch, originChain, originAsset, targetChain, history]);
|
||||
if (!canSwitch) return null;
|
||||
return (
|
||||
<Button
|
||||
|
|
|
@ -24,7 +24,7 @@ export const SolanaWalletProvider: FC = (props) => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<WalletProvider wallets={wallets} autoConnect>
|
||||
<WalletProvider wallets={wallets}>
|
||||
<WalletDialogProvider>{props.children}</WalletDialogProvider>
|
||||
</WalletProvider>
|
||||
);
|
||||
|
|
|
@ -10,8 +10,6 @@ import {
|
|||
selectTransferIsSourceAssetWormholeWrapped,
|
||||
selectTransferOriginAsset,
|
||||
selectTransferOriginChain,
|
||||
selectTransferSourceAsset,
|
||||
selectTransferSourceChain,
|
||||
selectTransferTargetChain,
|
||||
} from "../store/selectors";
|
||||
import { setTargetAsset } from "../store/transferSlice";
|
||||
|
@ -24,8 +22,6 @@ import {
|
|||
|
||||
function useFetchTargetAsset() {
|
||||
const dispatch = useDispatch();
|
||||
const sourceChain = useSelector(selectTransferSourceChain);
|
||||
const sourceAsset = useSelector(selectTransferSourceAsset);
|
||||
const isSourceAssetWormholeWrapped = useSelector(
|
||||
selectTransferIsSourceAssetWormholeWrapped
|
||||
);
|
||||
|
@ -33,7 +29,6 @@ function useFetchTargetAsset() {
|
|||
const originAsset = useSelector(selectTransferOriginAsset);
|
||||
const targetChain = useSelector(selectTransferTargetChain);
|
||||
const { provider } = useEthereumProvider();
|
||||
// TODO: this may not cover wrapped to wrapped, should always use origin?
|
||||
useEffect(() => {
|
||||
if (isSourceAssetWormholeWrapped && originChain === targetChain) {
|
||||
dispatch(setTargetAsset(hexToNativeString(originAsset, originChain)));
|
||||
|
@ -43,19 +38,24 @@ function useFetchTargetAsset() {
|
|||
dispatch(setTargetAsset(undefined));
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
if (targetChain === CHAIN_ID_ETH && provider && sourceAsset) {
|
||||
if (
|
||||
targetChain === CHAIN_ID_ETH &&
|
||||
provider &&
|
||||
originChain &&
|
||||
originAsset
|
||||
) {
|
||||
const asset = await getForeignAssetEth(
|
||||
provider,
|
||||
sourceChain,
|
||||
sourceAsset
|
||||
originChain,
|
||||
originAsset
|
||||
);
|
||||
if (!cancelled) {
|
||||
dispatch(setTargetAsset(asset));
|
||||
}
|
||||
}
|
||||
if (targetChain === CHAIN_ID_SOLANA && sourceAsset) {
|
||||
if (targetChain === CHAIN_ID_SOLANA && originChain && originAsset) {
|
||||
try {
|
||||
const asset = await getForeignAssetSol(sourceChain, sourceAsset);
|
||||
const asset = await getForeignAssetSol(originChain, originAsset);
|
||||
if (!cancelled) {
|
||||
dispatch(setTargetAsset(asset));
|
||||
}
|
||||
|
@ -65,9 +65,9 @@ function useFetchTargetAsset() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (targetChain === CHAIN_ID_TERRA && sourceAsset) {
|
||||
if (targetChain === CHAIN_ID_TERRA && originChain && originAsset) {
|
||||
try {
|
||||
const asset = await getForeignAssetTerra(sourceChain, sourceAsset);
|
||||
const asset = await getForeignAssetTerra(originChain, originAsset);
|
||||
if (!cancelled) {
|
||||
dispatch(setTargetAsset(asset));
|
||||
}
|
||||
|
@ -87,8 +87,6 @@ function useFetchTargetAsset() {
|
|||
originChain,
|
||||
originAsset,
|
||||
targetChain,
|
||||
sourceChain,
|
||||
sourceAsset,
|
||||
provider,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ export const transferSlice = createSlice({
|
|||
state.targetAddressHex = undefined;
|
||||
// clear targetAsset so that components that fire before useFetchTargetAsset don't get stale data
|
||||
state.targetAsset = undefined;
|
||||
state.targetParsedTokenAccount = undefined;
|
||||
}
|
||||
},
|
||||
setSourceWormholeWrappedInfo: (
|
||||
|
@ -158,6 +159,7 @@ export const transferSlice = createSlice({
|
|||
state.targetAddressHex = undefined;
|
||||
// clear targetAsset so that components that fire before useFetchTargetAsset don't get stale data
|
||||
state.targetAsset = undefined;
|
||||
state.targetParsedTokenAccount = undefined;
|
||||
if (state.sourceChain === action.payload) {
|
||||
state.sourceChain = prevTargetChain;
|
||||
state.activeStep = 0;
|
||||
|
@ -196,6 +198,7 @@ export const transferSlice = createSlice({
|
|||
},
|
||||
setRedeemTx: (state, action: PayloadAction<Transaction>) => {
|
||||
state.redeemTx = action.payload;
|
||||
state.isRedeeming = false;
|
||||
},
|
||||
reset: (state) => ({
|
||||
...initialState,
|
||||
|
|
|
@ -12,8 +12,9 @@ export const uint8ArrayToHex = (a: Uint8Array) =>
|
|||
Buffer.from(a).toString("hex");
|
||||
export const hexToUint8Array = (h: string) =>
|
||||
new Uint8Array(Buffer.from(h, "hex"));
|
||||
export const hexToNativeString = (h: string | undefined, c: ChainId) =>
|
||||
!h
|
||||
export const hexToNativeString = (h: string | undefined, c: ChainId) => {
|
||||
try {
|
||||
return !h
|
||||
? undefined
|
||||
: c === CHAIN_ID_SOLANA
|
||||
? new PublicKey(hexToUint8Array(h)).toString()
|
||||
|
@ -22,3 +23,6 @@ export const hexToNativeString = (h: string | undefined, c: ChainId) =>
|
|||
: c === CHAIN_ID_TERRA
|
||||
? humanAddress(hexToUint8Array(h.substr(24))) // terra expects 20 bytes, not 32
|
||||
: h;
|
||||
} catch (e) {}
|
||||
return undefined;
|
||||
};
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import {
|
||||
ChainId,
|
||||
CHAIN_ID_SOLANA,
|
||||
getForeignAssetEth as getForeignAssetEthTx,
|
||||
getForeignAssetSolana as getForeignAssetSolanaTx,
|
||||
getForeignAssetTerra as getForeignAssetTerraTx,
|
||||
} from "@certusone/wormhole-sdk";
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { ethers } from "ethers";
|
||||
import { arrayify, isHexString, zeroPad } from "ethers/lib/utils";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { LCDClient } from "@terra-money/terra.js";
|
||||
import { ethers } from "ethers";
|
||||
import { hexToUint8Array } from "./array";
|
||||
import {
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
SOLANA_HOST,
|
||||
TERRA_HOST,
|
||||
SOL_TOKEN_BRIDGE_ADDRESS,
|
||||
TERRA_HOST,
|
||||
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||
} from "./consts";
|
||||
|
||||
|
@ -23,21 +22,14 @@ export async function getForeignAssetEth(
|
|||
originAsset: string
|
||||
) {
|
||||
try {
|
||||
// TODO: address conversion may be more complex than this
|
||||
const originAssetBytes = zeroPad(
|
||||
originChain === CHAIN_ID_SOLANA
|
||||
? new PublicKey(originAsset).toBytes()
|
||||
: arrayify(originAsset),
|
||||
32
|
||||
);
|
||||
return await getForeignAssetEthTx(
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
provider,
|
||||
originChain,
|
||||
originAssetBytes
|
||||
hexToUint8Array(originAsset)
|
||||
);
|
||||
} catch (e) {
|
||||
return ethers.constants.AddressZero;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,18 +37,12 @@ export async function getForeignAssetSol(
|
|||
originChain: ChainId,
|
||||
originAsset: string
|
||||
) {
|
||||
if (!isHexString(originAsset)) return null;
|
||||
// TODO: address conversion may be more complex than this
|
||||
const originAssetBytes = zeroPad(
|
||||
arrayify(originAsset, { hexPad: "left" }),
|
||||
32
|
||||
);
|
||||
const connection = new Connection(SOLANA_HOST, "confirmed");
|
||||
return await getForeignAssetSolanaTx(
|
||||
connection,
|
||||
SOL_TOKEN_BRIDGE_ADDRESS,
|
||||
originChain,
|
||||
originAssetBytes
|
||||
hexToUint8Array(originAsset)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,21 +57,14 @@ export async function getForeignAssetTerra(
|
|||
originAsset: string
|
||||
) {
|
||||
try {
|
||||
const originAssetBytes = zeroPad(
|
||||
originChain === CHAIN_ID_SOLANA
|
||||
? new PublicKey(originAsset).toBytes()
|
||||
: arrayify(originAsset),
|
||||
32
|
||||
);
|
||||
const lcd = new LCDClient(TERRA_HOST);
|
||||
return await getForeignAssetTerraTx(
|
||||
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||
lcd,
|
||||
originChain,
|
||||
originAssetBytes
|
||||
hexToUint8Array(originAsset)
|
||||
);
|
||||
} catch (e) {
|
||||
// TODO: better return for this
|
||||
return ethers.constants.AddressZero;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ export async function getForeignAssetEth(
|
|||
try {
|
||||
return await tokenBridge.wrappedAsset(originChain, originAsset);
|
||||
} catch (e) {
|
||||
return ethers.constants.AddressZero;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,13 +33,20 @@ export async function getForeignAssetTerra(
|
|||
originChain: ChainId,
|
||||
originAsset: Uint8Array
|
||||
) {
|
||||
const result: { address: string } = await client.wasm.contractQuery(tokenBridgeAddress, {
|
||||
try {
|
||||
const result: { address: string } = await client.wasm.contractQuery(
|
||||
tokenBridgeAddress,
|
||||
{
|
||||
wrapped_registry: {
|
||||
chain: originChain,
|
||||
address: fromUint8Array(originAsset),
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
return result.address;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,7 +51,7 @@ export async function getOriginalAssetEth(
|
|||
return {
|
||||
isWrapped: false,
|
||||
chainId: CHAIN_ID_ETH,
|
||||
assetAddress: arrayify(wrappedAddress),
|
||||
assetAddress: zeroPad(arrayify(wrappedAddress), 32),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ export async function getOriginalAssetTerra(
|
|||
client: LCDClient,
|
||||
wrappedAddress: string
|
||||
): Promise<WormholeWrappedInfo> {
|
||||
try {
|
||||
const result: {
|
||||
asset_address: string;
|
||||
asset_chain: ChainId;
|
||||
|
@ -70,9 +71,12 @@ export async function getOriginalAssetTerra(
|
|||
return {
|
||||
isWrapped: true,
|
||||
chainId: result.asset_chain,
|
||||
assetAddress: new Uint8Array(Buffer.from(result.asset_address, "base64")),
|
||||
assetAddress: new Uint8Array(
|
||||
Buffer.from(result.asset_address, "base64")
|
||||
),
|
||||
};
|
||||
}
|
||||
} catch (e) {}
|
||||
return {
|
||||
isWrapped: false,
|
||||
chainId: CHAIN_ID_TERRA,
|
||||
|
@ -114,6 +118,13 @@ export async function getOriginalAssetSol(
|
|||
};
|
||||
}
|
||||
}
|
||||
try {
|
||||
return {
|
||||
isWrapped: false,
|
||||
chainId: CHAIN_ID_SOLANA,
|
||||
assetAddress: new PublicKey(mintAddress).toBytes(),
|
||||
};
|
||||
} catch (e) {}
|
||||
return {
|
||||
isWrapped: false,
|
||||
chainId: CHAIN_ID_SOLANA,
|
||||
|
|
Loading…
Reference in New Issue