UNPKG

@lucoadam/zebec-wormhole-sdk

Version:

This sdk can be use to transfer assets across chains and to interact with the Zebec's xchain bridge smart contracts for passing message from EVM chain to solana specially to utilize the features of Zebec Streaming and Zebec Multisig Streaming protocol.

105 lines (103 loc) 4.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transferEvm = transferEvm; var _ethers = require("ethers"); var _wormholeSdk = require("@certusone/wormhole-sdk"); var _anchor = require("@project-serum/anchor"); var _splToken = require("@solana/spl-token"); var _web = require("@solana/web3.js"); var _constants = require("../utils/constants"); var _assets = require("./assets"); /** * Transfer token across from evm chain * @param signer evm signer that extends ethers.Signer * @param sourceTokenAddress token address string of source chain * @param sourceChainId source chain id * @param amount amount to transfer * @param recipientChain recipient chain id * @param recipientAddress destination address in recipient chain * @param relayerFee relayer fee * @returns transaction reciept of transfer */ async function transferEvm(signer, sourceTokenAddress, sourceChainId, amount, recipientChain, recipientAddress, relayerFee, onApproved) { if (!_ethers.ethers.utils.isAddress(sourceTokenAddress)) { throw new Error("Invalid source token address"); } let decimals; try { const token = _wormholeSdk.TokenImplementation__factory.connect(sourceTokenAddress, signer); decimals = await token.decimals(); } catch (e) { console.error(e); throw e; } if (!decimals || decimals === 0) { throw new Error("Could not retrieve decimal value"); } console.debug("decimals:", decimals); const tokenBridgeAddress = (0, _constants.getTokenBridgeAddressForChain)(sourceChainId); const connection = new _anchor.web3.Connection(_constants.SOLANA_HOST, "confirmed"); let recipientAddr; try { const targetTokenAddress = await (0, _assets.getTargetAsset)(signer, sourceTokenAddress, sourceChainId, recipientChain); console.debug("targetTokenAddress:", targetTokenAddress); if (recipientChain === _wormholeSdk.CHAIN_ID_SOLANA) { const recipientTokenAddress = await (0, _splToken.getAssociatedTokenAddress)(new _web.PublicKey(targetTokenAddress), new _web.PublicKey(recipientAddress), true); recipientAddr = (0, _wormholeSdk.tryNativeToUint8Array)(recipientTokenAddress.toString(), "solana"); //console.log("Recever Address ATA: ", recipientAddr); // todo: check if account exists or not and figure out if extra fee should be added in relayer fee or not const receipientTokenAccountInfo = await connection.getAccountInfo(recipientTokenAddress, "confirmed"); if (!receipientTokenAccountInfo) { //throw new Error("Recipient doesn't have associated token account for given token address in solana"); console.log("Creating ATA!"); const txn = new _web.Transaction(); txn.add((0, _splToken.createAssociatedTokenAccountInstruction)(_constants.fee_keypair.publicKey, recipientTokenAddress, new _web.PublicKey(recipientAddress), new _web.PublicKey(targetTokenAddress))); const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(); txn.recentBlockhash = blockhash; txn.lastValidBlockHeight = lastValidBlockHeight; txn.feePayer = _constants.fee_keypair.publicKey; txn.partialSign(_constants.fee_keypair); const signature = await connection.sendRawTransaction(txn.serialize()); await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }); } } else { // todo: for terra and algorand recipientAddr = (0, _wormholeSdk.tryNativeToUint8Array)(recipientAddress, recipientChain); } } catch (e) { console.error(e); throw e; } const baseAmountParsed = _ethers.ethers.utils.parseUnits(amount, decimals); const feeParsed = _ethers.ethers.utils.parseUnits(relayerFee || "0", decimals); const transferAmountParsed = baseAmountParsed.add(feeParsed); const approveReceipt = await (0, _wormholeSdk.approveEth)(tokenBridgeAddress, sourceTokenAddress, signer, transferAmountParsed); // for ux purpose if (onApproved) { onApproved(approveReceipt); } console.log("approve eth:", approveReceipt.transactionHash); const isNative = (0, _constants.getDefaultNativeCurrencyAddressEvm)(sourceChainId) === sourceTokenAddress; const overrides = { gasLimit: "1000000" }; try { const result = isNative ? (0, _wormholeSdk.transferFromEthNative)(tokenBridgeAddress, signer, transferAmountParsed, recipientChain, recipientAddr, feeParsed, overrides) : (0, _wormholeSdk.transferFromEth)(tokenBridgeAddress, signer, sourceTokenAddress, transferAmountParsed, recipientChain, recipientAddr, feeParsed, overrides); const transferReceipt = await result; console.log("transferRecieptHash:", transferReceipt.transactionHash); return transferReceipt; } catch (e) { console.error(e); throw e; } } //# sourceMappingURL=evm.js.map