Skip to content

Commit

Permalink
handle native sei transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-gray committed Jun 21, 2023
1 parent 5e40161 commit 0880d8a
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 77 deletions.
60 changes: 60 additions & 0 deletions src/components/Recovery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
CHAIN_ID_INJECTIVE,
CHAIN_ID_KARURA,
CHAIN_ID_NEAR,
CHAIN_ID_SEI,
CHAIN_ID_SOLANA,
CHAIN_ID_SUI,
CHAIN_ID_TERRA2,
Expand Down Expand Up @@ -105,6 +106,12 @@ import {
} from "../utils/injective";
import { makeNearProvider } from "../utils/near";
import parseError from "../utils/parseError";
import {
getSeiQueryClient,
getSeiWasmClient,
parseSequenceFromLogSei,
queryExternalIdSei,
} from "../utils/sei";
import { getSuiProvider } from "../utils/sui";
import ButtonWithLoader from "./ButtonWithLoader";
import ChainSelect from "./ChainSelect";
Expand Down Expand Up @@ -320,6 +327,26 @@ async function injective(txHash: string, enqueueSnackbar: any) {
}
}

async function sei(txHash: string, enqueueSnackbar: any) {
try {
const client = await getSeiQueryClient();
const tx = await client.cosmos.tx.v1beta1.getTx({ hash: txHash });
if (!tx || !tx.tx_response) {
throw new Error("Unable to fetch transaction");
}
const sequence = parseSequenceFromLogSei(tx.tx_response);
if (!sequence) {
throw new Error("Sequence not found");
}
const emitterAddress = await getEmitterAddressTerra(
getTokenBridgeAddressForChain(CHAIN_ID_SEI)
);
return await fetchSignedVAA(CHAIN_ID_SEI, emitterAddress, sequence);
} catch (e) {
return handleError(e, enqueueSnackbar);
}
}

async function sui(digest: string, enqueueSnackbar: any) {
try {
const provider = getSuiProvider();
Expand Down Expand Up @@ -568,6 +595,19 @@ export default function Recovery() {
}
})();
}
if (parsedPayload && parsedPayload.targetChain === CHAIN_ID_SEI) {
(async () => {
const client = await getSeiWasmClient();
const tokenId = await queryExternalIdSei(
client,
getTokenBridgeAddressForChain(CHAIN_ID_SEI),
parsedPayload.originAddress
);
if (!cancelled) {
setTokenId(tokenId || "");
}
})();
}
if (parsedPayload && parsedPayload.targetChain === CHAIN_ID_SUI) {
(async () => {
const tokenId = await getForeignAssetSui(
Expand Down Expand Up @@ -777,6 +817,26 @@ export default function Recovery() {
setIsVAAPending(isPending);
}
})();
} else if (recoverySourceChain === CHAIN_ID_SEI) {
setRecoverySourceTxError("");
setRecoverySourceTxIsLoading(true);
setTokenId("");
(async () => {
const { vaa, isPending, error } = await sei(
recoverySourceTx,
enqueueSnackbar
);
if (!cancelled) {
setRecoverySourceTxIsLoading(false);
if (vaa) {
setRecoverySignedVAA(vaa);
}
if (error) {
setRecoverySourceTxError(error);
}
setIsVAAPending(isPending);
}
})();
} else if (recoverySourceChain === CHAIN_ID_SUI) {
setRecoverySourceTxError("");
setRecoverySourceTxIsLoading(true);
Expand Down
76 changes: 76 additions & 0 deletions src/hooks/useHandleAttest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CHAIN_ID_INJECTIVE,
CHAIN_ID_KLAYTN,
CHAIN_ID_NEAR,
CHAIN_ID_SEI,
CHAIN_ID_SOLANA,
CHAIN_ID_SUI,
CHAIN_ID_XPLA,
Expand Down Expand Up @@ -40,9 +41,15 @@ import {
} from "@certusone/wormhole-sdk";
import { getOriginalPackageId } from "@certusone/wormhole-sdk/lib/cjs/sui";
import { getEmitterAddressAndSequenceFromResponseSui } from "@certusone/wormhole-sdk/lib/esm/sui";
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { calculateFee } from "@cosmjs/stargate";
import { WalletStrategy } from "@injectivelabs/wallet-ts";
import { Alert } from "@material-ui/lab";
import { Wallet } from "@near-wallet-selector/core";
import {
useSigningCosmWasmClient as useSeiSigningCosmWasmClient,
useWallet as useSeiWallet,
} from "@sei-js/react";
import { WalletContextState } from "@solana/wallet-adapter-react";
import { Connection, PublicKey } from "@solana/web3.js";
import {
Expand Down Expand Up @@ -113,6 +120,7 @@ import { signSendAndConfirm } from "../utils/solana";
import { getSuiProvider } from "../utils/sui";
import { postWithFees, waitForTerraExecution } from "../utils/terra";
import { postWithFeesXpla, waitForXplaExecution } from "../utils/xpla";
import { attestFromSeiMsg, parseSequenceFromLogSei } from "../utils/sei";

async function algo(
dispatch: any,
Expand Down Expand Up @@ -543,6 +551,56 @@ async function injective(
}
}

async function sei(
dispatch: any,
enqueueSnackbar: any,
wallet: SigningCosmWasmClient,
walletAddress: string,
asset: string
) {
dispatch(setIsSending(true));
try {
const msg = attestFromSeiMsg(asset);
const fee = calculateFee(600000, "0.1usei");
const tokenBridgeAddress = getTokenBridgeAddressForChain(CHAIN_ID_SEI);
const tx = await wallet.execute(
walletAddress,
tokenBridgeAddress,
msg,
fee,
"Wormhole - Create Wrapped"
);
dispatch(setAttestTx({ id: tx.transactionHash, block: tx.height }));
enqueueSnackbar(null, {
content: <Alert severity="success">Transaction confirmed</Alert>,
});
const sequence = parseSequenceFromLogSei(tx);
if (!sequence) {
throw new Error("Sequence not found");
}
const emitterAddress = await getEmitterAddressTerra(tokenBridgeAddress);
enqueueSnackbar(null, {
content: <Alert severity="info">Fetching VAA</Alert>,
});
const { vaaBytes } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS,
CHAIN_ID_SEI,
emitterAddress,
sequence
);
dispatch(setSignedVAAHex(uint8ArrayToHex(vaaBytes)));
enqueueSnackbar(null, {
content: <Alert severity="success">Fetched Signed VAA</Alert>,
});
} catch (e) {
console.error(e);
enqueueSnackbar(null, {
content: <Alert severity="error">{parseError(e)}</Alert>,
});
dispatch(setIsSending(false));
}
}

async function sui(
dispatch: any,
enqueueSnackbar: any,
Expand Down Expand Up @@ -624,6 +682,10 @@ export function useHandleAttest() {
const { account: aptosAccount, signAndSubmitTransaction } = useAptosContext();
const aptosAddress = aptosAccount?.address?.toString();
const { wallet: injWallet, address: injAddress } = useInjectiveContext();
const { signingCosmWasmClient: seiSigningCosmWasmClient } =
useSeiSigningCosmWasmClient();
const { accounts: seiAccounts } = useSeiWallet();
const seiAddress = seiAccounts.length ? seiAccounts[0].address : null;
const { accountId: nearAccountId, wallet: nearWallet } = useNearContext();
const suiWallet = useWallet();
const disabled = !isTargetComplete || isSending || isSendComplete;
Expand All @@ -649,6 +711,18 @@ export function useHandleAttest() {
aptos(dispatch, enqueueSnackbar, sourceAsset, signAndSubmitTransaction);
} else if (sourceChain === CHAIN_ID_INJECTIVE && injWallet && injAddress) {
injective(dispatch, enqueueSnackbar, injWallet, injAddress, sourceAsset);
} else if (
sourceChain === CHAIN_ID_SEI &&
seiSigningCosmWasmClient &&
seiAddress
) {
sei(
dispatch,
enqueueSnackbar,
seiSigningCosmWasmClient,
seiAddress,
sourceAsset
);
} else if (sourceChain === CHAIN_ID_NEAR && nearAccountId && nearWallet) {
near(dispatch, enqueueSnackbar, nearAccountId, sourceAsset, nearWallet);
} else if (
Expand Down Expand Up @@ -677,6 +751,8 @@ export function useHandleAttest() {
nearAccountId,
nearWallet,
suiWallet,
seiSigningCosmWasmClient,
seiAddress,
]);
return useMemo(
() => ({
Expand Down
60 changes: 42 additions & 18 deletions src/hooks/useHandleRedeem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
TerraChainId,
isEVMChain,
isTerraChain,
parseTransferPayload,
parseVaa,
postVaaSolanaWithRetry,
redeemAndUnwrapOnSolana,
redeemOnAlgorand,
Expand Down Expand Up @@ -81,6 +83,7 @@ import {
ALGORAND_TOKEN_BRIDGE_ID,
MAX_VAA_UPLOAD_RETRIES_SOLANA,
NEAR_TOKEN_BRIDGE_ACCOUNT,
SEI_TRANSLATER_TARGET,
SEI_TRANSLATOR,
SOLANA_HOST,
SOL_BRIDGE_ADDRESS,
Expand Down Expand Up @@ -412,24 +415,45 @@ async function sei(
) {
dispatch(setIsRedeeming(true));
try {
const msg = {
complete_transfer_and_convert: {
vaa: fromUint8Array(signedVAA),
},
};
// TODO: is this right?
const fee = calculateFee(800000, "0.1usei");
const tx = await wallet.execute(
walletAddress,
SEI_TRANSLATOR,
msg,
fee,
"Wormhole - Complete Transfer"
);
dispatch(setRedeemTx({ id: tx.transactionHash, block: tx.height }));
enqueueSnackbar(null, {
content: <Alert severity="success">Transaction confirmed</Alert>,
});
const parsed = parseVaa(signedVAA);
const payload = parseTransferPayload(parsed.payload);
if (payload.targetAddress === uint8ArrayToHex(SEI_TRANSLATER_TARGET)) {
const msg = {
complete_transfer_and_convert: {
vaa: fromUint8Array(signedVAA),
},
};
const fee = calculateFee(800000, "0.1usei");
const tx = await wallet.execute(
walletAddress,
SEI_TRANSLATOR,
msg,
fee,
"Wormhole - Complete Transfer"
);
dispatch(setRedeemTx({ id: tx.transactionHash, block: tx.height }));
enqueueSnackbar(null, {
content: <Alert severity="success">Transaction confirmed</Alert>,
});
} else {
const msg = {
submit_vaa: {
data: fromUint8Array(signedVAA),
},
};
const fee = calculateFee(800000, "0.1usei");
const tx = await wallet.execute(
walletAddress,
getTokenBridgeAddressForChain(CHAIN_ID_SEI),
msg,
fee,
"Wormhole - Complete Transfer"
);
dispatch(setRedeemTx({ id: tx.transactionHash, block: tx.height }));
enqueueSnackbar(null, {
content: <Alert severity="success">Transaction confirmed</Alert>,
});
}
} catch (e) {
enqueueSnackbar(null, {
content: <Alert severity="error">{parseError(e)}</Alert>,
Expand Down
Loading

0 comments on commit 0880d8a

Please sign in to comment.