bridge_ui: Terra2 ExternalTokenId conversions

This commit is contained in:
Kevin Peters 2022-06-24 16:23:28 +00:00 committed by Evan Gray
parent 4131381fa4
commit 52e66964b0
4 changed files with 118 additions and 26 deletions

View File

@ -4,6 +4,7 @@ import {
CHAIN_ID_ALGORAND,
CHAIN_ID_KARURA,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA2,
getEmitterAddressAlgorand,
getEmitterAddressEth,
getEmitterAddressSolana,
@ -73,6 +74,7 @@ import {
} from "../utils/consts";
import { getSignedVAAWithRetry } from "../utils/getSignedVAAWithRetry";
import parseError from "../utils/parseError";
import { queryExternalId } from "../utils/terra";
import ButtonWithLoader from "./ButtonWithLoader";
import ChainSelect from "./ChainSelect";
import KeyAndBalance from "./KeyAndBalance";
@ -378,6 +380,7 @@ export default function Recovery() {
const [recoverySourceTxError, setRecoverySourceTxError] = useState("");
const [recoverySignedVAA, setRecoverySignedVAA] = useState("");
const [recoveryParsedVAA, setRecoveryParsedVAA] = useState<any>(null);
const [terra2TokenId, setTerra2TokenId] = useState("");
const { isReady, statusMessage } = useIsWalletReady(recoverySourceChain);
const walletConnectError =
isEVMChain(recoverySourceChain) && !isReady ? statusMessage : "";
@ -398,6 +401,21 @@ export default function Recovery() {
}
}, [recoveryParsedVAA, isNFT]);
useEffect(() => {
let cancelled = false;
if (parsedPayload && parsedPayload.targetChain === CHAIN_ID_TERRA2) {
(async () => {
const tokenId = await queryExternalId(parsedPayload.originAddress);
if (!cancelled) {
setTerra2TokenId(tokenId || "");
}
})();
}
return () => {
cancelled = true;
};
}, [parsedPayload]);
const { search } = useLocation();
const query = useMemo(() => new URLSearchParams(search), [search]);
const pathSourceChain = query.get("sourceChain");
@ -470,6 +488,7 @@ export default function Recovery() {
} else if (isTerraChain(recoverySourceChain)) {
setRecoverySourceTxError("");
setRecoverySourceTxIsLoading(true);
setTerra2TokenId("");
(async () => {
const { vaa, error } = await terra(
recoverySourceTx,
@ -789,12 +808,14 @@ export default function Recovery() {
label="Origin Token Address"
disabled
value={
(parsedPayload &&
hexToNativeAssetString(
parsedPayload.originAddress,
parsedPayload.originChain
)) ||
""
parsedPayload
? parsedPayload.targetChain === CHAIN_ID_TERRA2
? terra2TokenId
: hexToNativeAssetString(
parsedPayload.originAddress,
parsedPayload.originChain
) || ""
: ""
}
fullWidth
margin="normal"

View File

@ -2,6 +2,7 @@ import {
ChainId,
CHAIN_ID_ALGORAND,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA2,
getForeignAssetAlgorand,
getForeignAssetEth,
getForeignAssetSolana,
@ -53,6 +54,7 @@ import {
SOL_TOKEN_BRIDGE_ADDRESS,
getTerraConfig,
} from "../utils/consts";
import { queryExternalId } from "../utils/terra";
function useFetchTargetAsset(nft?: boolean) {
const dispatch = useDispatch();
@ -117,20 +119,39 @@ function useFetchTargetAsset(nft?: boolean) {
return;
}
setLastSuccessfulArgs(null);
if (isSourceAssetWormholeWrapped && originChain === targetChain) {
dispatch(
setTargetAsset(
receiveDataWrapper({
doesExist: true,
address: hexToNativeAssetString(originAsset, originChain) || null,
})
)
);
setArgs();
return;
}
let cancelled = false;
(async () => {
if (isSourceAssetWormholeWrapped && originChain === targetChain) {
if (originChain === CHAIN_ID_TERRA2) {
const tokenId = await queryExternalId(originAsset || "");
if (!cancelled) {
dispatch(
setTargetAsset(
receiveDataWrapper({
doesExist: true,
address: tokenId || null,
})
)
);
}
} else {
if (!cancelled) {
dispatch(
setTargetAsset(
receiveDataWrapper({
doesExist: true,
address:
hexToNativeAssetString(originAsset, originChain) || null,
})
)
);
}
}
if (!cancelled) {
setArgs();
}
return;
}
if (
isEVMChain(targetChain) &&
provider &&

View File

@ -2,6 +2,7 @@ import {
ChainId,
CHAIN_ID_ALGORAND,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA2,
getOriginalAssetAlgorand,
getOriginalAssetCosmWasm,
getOriginalAssetEth,
@ -39,6 +40,7 @@ import {
SOL_NFT_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
} from "../utils/consts";
import { queryExternalId } from "../utils/terra";
import useIsWalletReady from "./useIsWalletReady";
export type OriginalAssetInfo = {
@ -228,12 +230,18 @@ function useOriginalAsset(
if (!cancelled) {
setIsLoading(false);
setArgs();
setOriginAddress(
hexToNativeAssetString(
uint8ArrayToHex(result.assetAddress),
result.chainId
) || null
);
if (result.chainId === CHAIN_ID_TERRA2) {
queryExternalId(uint8ArrayToHex(result.assetAddress)).then(
(tokenId) => setOriginAddress(tokenId || null)
);
} else {
setOriginAddress(
hexToNativeAssetString(
uint8ArrayToHex(result.assetAddress),
result.chainId
) || null
);
}
setOriginTokenId(result.tokenId || null);
setOriginChain(result.chainId);
}

View File

@ -9,8 +9,11 @@ import { formatUnits } from "@ethersproject/units";
import { LCDClient, isTxError } from "@terra-money/terra.js";
import { ConnectedWallet, TxResult } from "@terra-money/wallet-provider";
import axios from "axios";
// import { TerraTokenMetadata } from "../hooks/useTerraTokenMap";
import { getTerraGasPricesUrl, getTerraConfig } from "./consts";
import {
getTerraGasPricesUrl,
getTerraConfig,
getTokenBridgeAddressForChain,
} from "./consts";
export const NATIVE_TERRA_DECIMALS = 6;
export const LUNA_SYMBOL = "LUNA";
@ -124,3 +127,42 @@ export async function postWithFees(
return result;
}
export interface ExternalIdResponse {
token_id: {
Bank?: { denom: string };
Contract?: {
NativeCW20?: {
contract_address: string;
};
ForeignToken?: {
chain_id: string;
foreign_address: string;
};
};
};
}
// returns the TokenId corresponding to the ExternalTokenId
// see cosmwasm token_addresses.rs
export const queryExternalId = async (externalTokenId: string) => {
const lcd = new LCDClient(getTerraConfig(CHAIN_ID_TERRA2));
try {
const response = await lcd.wasm.contractQuery<ExternalIdResponse>(
getTokenBridgeAddressForChain(CHAIN_ID_TERRA2),
{
external_id: {
external_id: Buffer.from(externalTokenId, "hex").toString("base64"),
},
}
);
return (
// response depends on the token type
response.token_id.Bank?.denom ||
response.token_id.Contract?.NativeCW20?.contract_address ||
response.token_id.Contract?.ForeignToken?.foreign_address
);
} catch {
return null;
}
};