diff --git a/swap_relayer/src/evm.ts b/swap_relayer/src/evm.ts index fe495fe..a3a0593 100644 --- a/swap_relayer/src/evm.ts +++ b/swap_relayer/src/evm.ts @@ -1,7 +1,4 @@ -import { - getIsTransferCompletedEth, - hexToUint8Array, -} from "@certusone/wormhole-sdk"; +import { getIsTransferCompletedEth, hexToUint8Array } from "@certusone/wormhole-sdk"; import { ethers } from "ethers"; @@ -54,35 +51,24 @@ export function loadEvmConfig(): EvmEnvironment[] { } let key_contract_address: string = evm + "_CONTRACT_ADDRESS"; - let val_contract_address: string = eval( - "process.env." + key_contract_address - ); + let val_contract_address: string = eval("process.env." + key_contract_address); if (!val_contract_address) { logger.error("Missing environment variable " + key_contract_address); return undefined; } let key_token_bridge_address: string = evm + "_TOKEN_BRIDGE_ADDRESS"; - let val_token_bridge_address: string = eval( - "process.env." + key_token_bridge_address - ); + let val_token_bridge_address: string = eval("process.env." + key_token_bridge_address); if (!val_token_bridge_address) { logger.error("Missing environment variable " + key_token_bridge_address); return undefined; } let key_wallet_private_key: string = evm + "_WALLET_PRIVATE_KEY"; - let val_wallet_private_key: string = eval( - "process.env." + key_wallet_private_key - ); - if (!val_wallet_private_key) - val_wallet_private_key = process.env.WALLET_PRIVATE_KEY; + let val_wallet_private_key: string = eval("process.env." + key_wallet_private_key); + if (!val_wallet_private_key) val_wallet_private_key = process.env.WALLET_PRIVATE_KEY; if (!val_wallet_private_key) { - logger.error( - "Missing environment variable " + - key_wallet_private_key + - " or WALLET_PRIVATE_KEY" - ); + logger.error("Missing environment variable " + key_wallet_private_key + " or WALLET_PRIVATE_KEY"); return undefined; } @@ -170,72 +156,15 @@ function makeContractDataForEvm(env: EvmEnvironment): EvmContractData { }; } -export function isEvmContract( - contractAddress: string, - chain_id: number -): boolean { +export function isEvmContract(contractAddress: string, chain_id: number): boolean { let ecd = evmContractData.get(chain_id); return ecd && ecd.contractAddress === contractAddress; } -/* - // GOERLI_PROVIDER = Ethereum - // MUMBAI_PROVIDER = Polygon - - if (t3Payload.contractAddress === CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM) { - // Use one of the V3 swap methods. - } else if (t3Payload.contractAddress === CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON) { - // Use one of the V2 swap methods. - } else { - // Error - } - - if (t3Payload.swapFunctionType === 1 && t3Payload.swapCurrencyType === 1) { - // swapExactInFromVaaNative - } else if (t3Payload.swapFunctionType === 1 && t3Payload.swapCurrencyType === 2) { - // swapExactInFromVaaToken - } else if ( - t3Payload.swapFunctionType === 2 && t3Payload.swapCurrencyType === 1) { - // swapExactOutFromVaaNative - } else if (t3Payload.swapFunctionType === 2 && t3Payload.swapCurrencyType === 2) { - // swapExactOutFromVaaToken - } else { - // error - } -*/ - -/* - // GOERLI_PROVIDER = Ethereum - // MUMBAI_PROVIDER = Polygon - - if (t3Payload.contractAddress === CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM) { - // Use one of the V3 swap methods. - } else if (t3Payload.contractAddress === CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON) { - // Use one of the V2 swap methods. - } else { - // Error - } - - if (t3Payload.swapFunctionType === 1 && t3Payload.swapCurrencyType === 1) { - // swapExactInFromVaaNative - } else if (t3Payload.swapFunctionType === 1 && t3Payload.swapCurrencyType === 2) { - // swapExactInFromVaaToken - } else if ( - t3Payload.swapFunctionType === 2 && t3Payload.swapCurrencyType === 1) { - // swapExactOutFromVaaNative - } else if (t3Payload.swapFunctionType === 2 && t3Payload.swapCurrencyType === 2) { - // swapExactOutFromVaaToken - } else { - // error - } -*/ - export async function relayVaaToEvm(vaaBytes: string, t3Payload: Type3Payload) { let ecd = evmContractData.get(t3Payload.targetChainId); if (!ecd) { - logger.error( - "relayVaaToEvm: chain id " + t3Payload.targetChainId + " does not exist!" - ); + logger.error("relayVaaToEvm: chain id " + t3Payload.targetChainId + " does not exist!"); } let exactIn: boolean = false; @@ -244,51 +173,23 @@ export async function relayVaaToEvm(vaaBytes: string, t3Payload: Type3Payload) { exactIn = true; } else if (t3Payload.swapFunctionType !== 2) { error = true; - logger.error( - "relayVaaTo" + - ecd.name + - ": unsupported swapFunctionType: [" + - t3Payload.swapFunctionType + - "]" - ); + logger.error("relayVaaTo" + ecd.name + ": unsupported swapFunctionType: [" + t3Payload.swapFunctionType + "]"); } - - let native: boolean = false; - if (t3Payload.swapCurrencyType === 1) { - native = true; - } else if (t3Payload.swapCurrencyType !== 2) { - error = true; - logger.error( - "relayVaaTo" + - ecd.name + - ": unsupported swapCurrencyType: [" + - t3Payload.swapCurrencyType + - "]" - ); - } - if (error) return; logger.debug( - "relayVaaTo" + - ecd.name + - ": chain_id: " + - ecd.chain_id + - ", contractAddress: [" + - t3Payload.contractAddress + - "]" + "relayVaaTo" + ecd.name + ": chain_id: " + ecd.chain_id + ", contractAddress: [" + t3Payload.contractAddress + "]" ); const signedVaaArray = hexToUint8Array(vaaBytes); - await relayVaaToEvmChain(t3Payload, ecd, signedVaaArray, exactIn, native); + await relayVaaToEvmChain(t3Payload, ecd, signedVaaArray, exactIn); } async function relayVaaToEvmChain( t3Payload: Type3Payload, tcd: EvmContractData, signedVaaArray: Uint8Array, - exactIn: boolean, - native: boolean + exactIn: boolean ) { logger.debug( "relayVaaTo" + @@ -312,8 +213,6 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": completed: already transferred" ); @@ -331,41 +230,17 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": submitting redeem request" ); try { let receipt: any = null; if (exactIn) { - if (native) { - logger.debug("relayVaaTo: calling evmSwapExactInFromVaaNative()"); - receipt = await swap.evmSwapExactInFromVaaNative( - tcd.contractWithSigner, - signedVaaArray - ); - } else { - logger.debug("relayVaaTo: calling evmSwapExactInFromVaaToken()"); - receipt = await swap.evmSwapExactInFromVaaToken( - tcd.contractWithSigner, - signedVaaArray - ); - } + logger.debug("relayVaaTo: calling evmSwapExactInFromVaaNative()"); + receipt = await swap.evmSwapExactInFromVaaNative(tcd.contractWithSigner, signedVaaArray); } else { - if (native) { - logger.debug("relayVaaTo: calling evmSwapExactOutFromVaaNative()"); - receipt = await swap.evmSwapExactOutFromVaaNative( - tcd.contractWithSigner, - signedVaaArray - ); - } else { - logger.debug("relayVaaTo: calling evmSwapExactOutFromVaaToken()"); - receipt = await swap.evmSwapExactOutFromVaaToken( - tcd.contractWithSigner, - signedVaaArray - ); - } + logger.debug("relayVaaTo: calling evmSwapExactOutFromVaaNative()"); + receipt = await swap.evmSwapExactOutFromVaaNative(tcd.contractWithSigner, signedVaaArray); } logger.info( @@ -379,8 +254,6 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": completed: success, txHash: " + receipt.transactionHash ); @@ -397,8 +270,6 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": completed: relay failed because the vaa has already been redeemed" ); @@ -412,8 +283,6 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": transaction failed: %o", e ); @@ -431,8 +300,6 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": redeem confirmed" ); } else { @@ -447,29 +314,18 @@ async function relayVaaToEvmChain( t3Payload.contractAddress + "], exactIn: " + exactIn + - ", native: " + - native + ": completed: failed to confirm redeem!" ); } } -async function isRedeemedOnEvm( - tcd: EvmContractData, - signedVaaArray: Uint8Array -): Promise { +async function isRedeemedOnEvm(tcd: EvmContractData, signedVaaArray: Uint8Array): Promise { let redeemed: boolean = false; try { - redeemed = await getIsTransferCompletedEth( - tcd.tokenBridgeAddress, - tcd.provider, - signedVaaArray - ); + redeemed = await getIsTransferCompletedEth(tcd.tokenBridgeAddress, tcd.provider, signedVaaArray); } catch (e) { logger.error( - "relayVaaTo" + - tcd.name + - ": failed to check if transfer is already complete, will attempt the transfer, e: %o", + "relayVaaTo" + tcd.name + ": failed to check if transfer is already complete, will attempt the transfer, e: %o", e ); } diff --git a/swap_relayer/src/index.ts b/swap_relayer/src/index.ts index 7d33294..b75ca98 100644 --- a/swap_relayer/src/index.ts +++ b/swap_relayer/src/index.ts @@ -12,33 +12,11 @@ import { getEmitterAddressTerra, } from "@certusone/wormhole-sdk"; -import { - importCoreWasm, - setDefaultWasm, -} from "@certusone/wormhole-sdk/lib/cjs/solana/wasm"; - -import { - createSpyRPCServiceClient, - subscribeSignedVAA, -} from "@certusone/wormhole-spydk"; - +import { importCoreWasm, setDefaultWasm } from "@certusone/wormhole-sdk/lib/cjs/solana/wasm"; +import { createSpyRPCServiceClient, subscribeSignedVAA } from "@certusone/wormhole-spydk"; import { ethers } from "ethers"; - -import { - EvmEnvironment, - isEvmContract, - loadEvmConfig, - makeEvmContractData, - relayVaaToEvm, -} from "./evm"; - -import { - isTerraContract, - loadTerraConfig, - makeTerraContractData, - relayVaaToTerra, - TerraEnvironment, -} from "./terra"; +import { EvmEnvironment, isEvmContract, loadEvmConfig, makeEvmContractData, relayVaaToEvm } from "./evm"; +import { isTerraContract, loadTerraConfig, makeTerraContractData, relayVaaToTerra, TerraEnvironment } from "./terra"; export let logger: any; @@ -66,7 +44,6 @@ export type Type3Payload = { contractAddress: string; relayerFee: ethers.BigNumber; swapFunctionType: number; - swapCurrencyType: number; }; type PendingEvent = { @@ -88,11 +65,7 @@ let condition = new CondVar(); let pendingQueue = new Array(); if (success) { - logger.info( - "swap_relayer starting up, will listen for signed VAAs from [" + - env.spy_host + - "]" - ); + logger.info("swap_relayer starting up, will listen for signed VAAs from [" + env.spy_host + "]"); try { makeEvmContractData(env.evm_configs); @@ -143,10 +116,7 @@ async function spy_listen() { var myFilters = []; for (var i = 0; i < parsedJsonFilters.length; i++) { var myChainId = parseInt(parsedJsonFilters[i].chain_id) as ChainId; - var myEmitterAddress = await encodeEmitterAddress( - myChainId, - parsedJsonFilters[i].emitter_address - ); + var myEmitterAddress = await encodeEmitterAddress(myChainId, parsedJsonFilters[i].emitter_address); var myEmitterFilter = { emitterFilter: { chainId: myChainId, @@ -182,10 +152,7 @@ async function spy_listen() { })(); } -async function encodeEmitterAddress( - myChainId, - emitterAddressStr -): Promise { +async function encodeEmitterAddress(myChainId, emitterAddressStr): Promise { if (myChainId === CHAIN_ID_SOLANA) { return await getEmitterAddressSolana(emitterAddressStr); } @@ -206,17 +173,11 @@ async function processVaa(vaaBytes: string) { let emitter_address: string = uint8ArrayToHex(parsedVAA.emitter_address); - let seqNumKey: string = - parsedVAA.emitter_chain.toString() + ":" + emitter_address; + let seqNumKey: string = parsedVAA.emitter_chain.toString() + ":" + emitter_address; let lastSeqNum = seqMap.get(seqNumKey); if (lastSeqNum) { if (lastSeqNum >= parsedVAA.sequence) { - logger.debug( - "ignoring duplicate: emitter: [" + - seqNumKey + - "], seqNum: " + - parsedVAA.sequence - ); + logger.debug("ignoring duplicate: emitter: [" + seqNumKey + "], seqNum: " + parsedVAA.sequence); return; } } @@ -248,8 +209,6 @@ async function processVaa(vaaBytes: string) { t3Payload.relayerFee + "], swapFunctionType: [" + t3Payload.swapFunctionType + - "], swapCurrencyType: [" + - t3Payload.swapCurrencyType + "]" ); @@ -270,8 +229,6 @@ async function processVaa(vaaBytes: string) { t3Payload.relayerFee + "], swapFunctionType: [" + t3Payload.swapFunctionType + - "], swapCurrencyType: [" + - t3Payload.swapCurrencyType + "]" ); } @@ -289,10 +246,7 @@ async function processVaa(vaaBytes: string) { } } -function decodeSignedVAAPayloadType3( - parsedVAA: any, - sourceChainId: number -): Type3Payload { +function decodeSignedVAAPayloadType3(parsedVAA: any, sourceChainId: number): Type3Payload { const payload = Buffer.from(new Uint8Array(parsedVAA.payload)); if (payload[0] !== 3) return undefined; @@ -310,18 +264,13 @@ function decodeSignedVAAPayloadType3( let contractAddress: string = ""; let swapFunctionType: number = 0; - let swapCurrencyType: number = 0; if (targetChainId === 3) { - logger.info( - "decodeSignedVAAPayloadType3: terraContractAddr: [" + - payload.slice(67, 67 + 32).toString("hex") + - "]" - ); + logger.info("decodeSignedVAAPayloadType3: terraContractAddr: [" + payload.slice(67, 67 + 32).toString("hex") + "]"); contractAddress = payload.slice(67, 67 + 32).toString("hex"); } else { - if (payload.length < 262) { + if (payload.length < 272) { logger.error( "decodeSignedVAAPayloadType3: dropping type 3 vaa because the payload is too short to extract the contract fields, length: " + payload.length + @@ -330,34 +279,24 @@ function decodeSignedVAAPayloadType3( ); return undefined; } - contractAddress = payload.slice(79, 79 + 20).toString("hex"); swapFunctionType = payload.readUInt8(272); - swapCurrencyType = payload.readUInt8(273); } return { sourceChainId: sourceChainId, targetChainId: targetChainId, contractAddress: contractAddress, - relayerFee: ethers.BigNumber.from(payload.slice(101, 101 + 32)), + relayerFee: ethers.BigNumber.from(payload.slice(273, 273 + 32)), swapFunctionType: swapFunctionType, - swapCurrencyType: swapCurrencyType, }; } function isOurContract(contractAddress: string, chainId: number): boolean { - return ( - isEvmContract(contractAddress, chainId) || - isTerraContract(contractAddress, chainId) - ); + return isEvmContract(contractAddress, chainId) || isTerraContract(contractAddress, chainId); } -async function postVaa( - vaaBytes: any, - t3Payload: Type3Payload, - receiveTime: Date -) { +async function postVaa(vaaBytes: any, t3Payload: Type3Payload, receiveTime: Date) { let event: PendingEvent = { vaaBytes: vaaBytes, t3Payload: t3Payload, @@ -366,9 +305,7 @@ async function postVaa( await mutex.runExclusive(() => { pendingQueue.push(event); - logger.debug( - "posting event, there are now " + pendingQueue.length + " enqueued events" - ); + logger.debug("posting event, there are now " + pendingQueue.length + " enqueued events"); if (condition) { logger.debug("hitting condition variable."); condition.complete(true); @@ -419,16 +356,12 @@ async function callBack(err: any, result: any) { await mutex.runExclusive(async () => { if (pendingQueue.length === 0) { - logger.debug( - "in callback, no more pending events, rearming the condition." - ); + logger.debug("in callback, no more pending events, rearming the condition."); done = true; condition = new CondVar(); await condition.wait(COND_VAR_TIMEOUT, callBack); } else { - logger.debug( - "in callback, there are " + pendingQueue.length + " pending events." - ); + logger.debug("in callback, there are " + pendingQueue.length + " pending events."); } }); } @@ -455,8 +388,7 @@ function initLogger() { let logFileName: string = ""; if (process.env.LOG_DIR) { useConsole = false; - logFileName = - process.env.LOG_DIR + "/swap_relay." + new Date().toISOString() + ".log"; + logFileName = process.env.LOG_DIR + "/swap_relay." + new Date().toISOString() + ".log"; } let logLevel = "info"; @@ -472,11 +404,7 @@ function initLogger() { level: logLevel, }); } else { - console.log( - "swap_relay is logging to [%s] at level [%s]", - logFileName, - logLevel - ); + console.log("swap_relay is logging to [%s] at level [%s]", logFileName, logLevel); transport = new winston.transports.File({ filename: logFileName, @@ -492,9 +420,7 @@ function initLogger() { winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS", }), - winston.format.printf( - (info: any) => `${[info.timestamp]}|${info.level}|${info.message}` - ) + winston.format.printf((info: any) => `${[info.timestamp]}|${info.level}|${info.message}`) ), };