sdk/js: Terra2 integration tests

This commit is contained in:
Kevin Peters 2022-06-24 16:23:42 +00:00 committed by Evan Gray
parent 52e66964b0
commit 3028b81d63
5 changed files with 208 additions and 9 deletions

View File

@ -36,7 +36,7 @@ const interateToStandardTransactionCount = async () => {
return Promise.resolve();
};
module.exports = async function(callback) {
module.exports = async function (callback) {
try {
const accounts = await web3.eth.getAccounts();
@ -61,6 +61,10 @@ module.exports = async function(callback) {
from: accounts[0],
gas: 1000000,
});
await token.methods.mint(accounts[2], "1000000000000000000000").send({
from: accounts[0],
gas: 1000000,
});
const nftAddress = (
await ERC721.new(

View File

@ -7,6 +7,8 @@ const ci = !!process.env.CI;
export const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545";
export const ETH_PRIVATE_KEY =
"0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d";
export const ETH_PRIVATE_KEY2 =
"0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c"; // account 2
export const ETH_CORE_BRIDGE_ADDRESS =
"0xC89Ce4735882C9F0f0FE26686c53074E09B0D550";
export const ETH_TOKEN_BRIDGE_ADDRESS =
@ -31,12 +33,19 @@ export const TERRA_CHAIN_ID = "localterra";
export const TERRA_GAS_PRICES_URL = ci
? "http://terra-fcd:3060/v1/txs/gas_prices"
: "http://localhost:3060/v1/txs/gas_prices";
export const TERRA2_GAS_PRICES_URL = ci
? "http://terra2-fcd:3060/v1/txs/gas_prices"
: "http://localhost:3061/v1/txs/gas_prices";
export const TERRA_CORE_BRIDGE_ADDRESS =
"terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5";
export const TERRA_TOKEN_BRIDGE_ADDRESS =
"terra10pyejy66429refv3g35g2t7am0was7ya7kz2a4";
export const TERRA2_TOKEN_BRIDGE_ADDRESS =
"terra1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrquka9l6";
export const TERRA_PRIVATE_KEY =
"notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius";
export const TERRA2_PRIVATE_KEY =
"symbol force gallery make bulk round subway violin worry mixture penalty kingdom boring survey tool fringe patrol sausage hard admit remember broken alien absorb"; // test3
export const TEST_ERC20 = "0x2D8BE6BF0baA74e0A907016679CaE9190e80dD0A";
export const TEST_SOLANA_TOKEN = "2WDq7wSs9zYrpx2kbHDA4RUTRch2CCTP6ZWaH4GNfnQQ";
export const WORMHOLE_RPC_HOSTS = ci

View File

@ -105,9 +105,9 @@ export async function transferFromEthToSolana(): Promise<string> {
}
export async function waitForTerraExecution(
transaction: string
transaction: string,
lcd: LCDClient
): Promise<TxInfo | undefined> {
const lcd = new LCDClient(TERRA_HOST);
let done: boolean = false;
let info;
while (!done) {

View File

@ -1180,7 +1180,7 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
const result = await lcd.tx.broadcast(executeTx);
const info = await waitForTerraExecution(result.txhash);
const info = await waitForTerraExecution(result.txhash, lcd);
if (!info) {
throw new Error("info not found");
}
@ -1316,7 +1316,7 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
const result = await lcd.tx.broadcast(executeTx);
const info = await waitForTerraExecution(result.txhash);
const info = await waitForTerraExecution(result.txhash, lcd);
if (!info) {
throw new Error("info not found");
}
@ -1559,7 +1559,7 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
let result = await lcd.tx.broadcast(executeTx);
let info = await waitForTerraExecution(result.txhash);
let info = await waitForTerraExecution(result.txhash, lcd);
if (!info) {
throw new Error("info not found");
}
@ -1678,7 +1678,7 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
result = await lcd.tx.broadcast(executeTx);
info = await waitForTerraExecution(result.txhash);
info = await waitForTerraExecution(result.txhash, lcd);
if (!info) {
throw new Error("info not found");
}
@ -2390,7 +2390,10 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
const attestResult = await lcd.tx.broadcast(executeAttest);
const attestInfo = await waitForTerraExecution(attestResult.txhash);
const attestInfo = await waitForTerraExecution(
attestResult.txhash,
lcd
);
if (!attestInfo) {
throw new Error("info not found");
}
@ -2471,7 +2474,7 @@ describe("Integration Tests", () => {
fee: feeEstimate,
});
const txResult = await lcd.tx.broadcast(executeTx);
const txInfo = await waitForTerraExecution(txResult.txhash);
const txInfo = await waitForTerraExecution(txResult.txhash, lcd);
if (!txInfo) {
throw new Error("info not found");
}

View File

@ -0,0 +1,183 @@
import { beforeAll, afterAll, expect, test } from "@jest/globals";
import {
isTxError,
LCDClient,
MnemonicKey,
Msg,
Wallet,
} from "@terra-money/terra.js";
import { ethers } from "ethers";
import { parseUnits } from "ethers/lib/utils";
import {
createWrappedOnEth,
createWrappedOnTerra,
getEmitterAddressEth,
getEmitterAddressTerra,
getIsTransferCompletedTerra,
parseSequenceFromLogEth,
parseSequenceFromLogTerra,
redeemOnEth,
redeemOnTerra,
updateWrappedOnEth,
} from "../..";
import { tryNativeToUint8Array } from "../../utils";
import { CHAIN_ID_ETH, CHAIN_ID_TERRA2 } from "../../utils/consts";
import { attestFromEth, attestFromTerra } from "../attest";
import { approveEth, transferFromEth, transferFromTerra } from "../transfer";
import {
ETH_CORE_BRIDGE_ADDRESS,
ETH_NODE_URL,
ETH_PRIVATE_KEY2,
ETH_TOKEN_BRIDGE_ADDRESS,
TERRA2_GAS_PRICES_URL,
TERRA2_TOKEN_BRIDGE_ADDRESS,
TERRA2_PRIVATE_KEY,
TEST_ERC20,
} from "./consts";
import { getSignedVAABySequence, waitForTerraExecution } from "./helpers";
const lcd = new LCDClient({
URL: !!process.env.CI ? "http://terra2-terrad:1317" : "http://localhost:1318",
chainID: "localterra",
});
const terraWallet = lcd.wallet(
new MnemonicKey({ mnemonic: TERRA2_PRIVATE_KEY })
);
const terraWalletAddress = terraWallet.key.accAddress;
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY2, provider);
const ethEmitterAddress = getEmitterAddressEth(ETH_TOKEN_BRIDGE_ADDRESS);
const ethTransferAmount = parseUnits("1", 18);
let ethWalletAddress: string;
let terraEmitterAddress: string;
beforeAll(async () => {
ethWalletAddress = await signer.getAddress();
terraEmitterAddress = await getEmitterAddressTerra(
TERRA2_TOKEN_BRIDGE_ADDRESS
);
});
afterAll(async () => {
provider.destroy();
});
const terraBroadcastAndWaitForExecution = async (
msgs: Msg[],
wallet: Wallet
) => {
const tx = await wallet.createAndSignTx({
msgs,
});
const txResult = await lcd.tx.broadcast(tx);
if (isTxError(txResult)) {
throw new Error("tx error");
}
const txInfo = await waitForTerraExecution(txResult.txhash, lcd);
if (!txInfo) {
throw new Error("tx info not found");
}
return txInfo;
};
const terraBroadcastTxAndGetSignedVaa = async (msgs: Msg[], wallet: Wallet) => {
const txInfo = await terraBroadcastAndWaitForExecution(msgs, wallet);
const txSequence = parseSequenceFromLogTerra(txInfo);
if (!txSequence) {
throw new Error("tx sequence not found");
}
return await getSignedVAABySequence(
CHAIN_ID_TERRA2,
txSequence,
terraEmitterAddress
);
};
const ethParseLogAndGetSignedVaa = async (receipt: ethers.ContractReceipt) => {
const sequence = parseSequenceFromLogEth(receipt, ETH_CORE_BRIDGE_ADDRESS);
return await getSignedVAABySequence(
CHAIN_ID_ETH,
sequence,
ethEmitterAddress
);
};
test("Attest and transfer token from Terra2 to Ethereum", async () => {
// Attest
const attestMsg = await attestFromTerra(
TERRA2_TOKEN_BRIDGE_ADDRESS,
terraWalletAddress,
"uluna"
);
const attestSignedVaa = await terraBroadcastTxAndGetSignedVaa(
[attestMsg],
terraWallet
);
try {
await createWrappedOnEth(ETH_TOKEN_BRIDGE_ADDRESS, signer, attestSignedVaa);
} catch {
await updateWrappedOnEth(ETH_TOKEN_BRIDGE_ADDRESS, signer, attestSignedVaa);
}
// Transfer
const transferMsgs = await transferFromTerra(
terraWalletAddress,
TERRA2_TOKEN_BRIDGE_ADDRESS,
"uluna",
"1000000",
CHAIN_ID_ETH,
tryNativeToUint8Array(ethWalletAddress, CHAIN_ID_ETH)
);
const transferSignedVaa = await terraBroadcastTxAndGetSignedVaa(
transferMsgs,
terraWallet
);
await redeemOnEth(ETH_TOKEN_BRIDGE_ADDRESS, signer, transferSignedVaa);
});
test("Attest and transfer token from Ethereum to Terra2", async () => {
// Attest
const attestReceipt = await attestFromEth(
ETH_TOKEN_BRIDGE_ADDRESS,
signer,
TEST_ERC20
);
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
const createWrappedMsg = await createWrappedOnTerra(
TERRA2_TOKEN_BRIDGE_ADDRESS,
terraWalletAddress,
attestSignedVaa
);
await terraBroadcastAndWaitForExecution([createWrappedMsg], terraWallet);
// Transfer
await approveEth(
ETH_TOKEN_BRIDGE_ADDRESS,
TEST_ERC20,
signer,
ethTransferAmount
);
const transferReceipt = await transferFromEth(
ETH_TOKEN_BRIDGE_ADDRESS,
signer,
TEST_ERC20,
ethTransferAmount,
CHAIN_ID_TERRA2,
tryNativeToUint8Array(terraWalletAddress, CHAIN_ID_TERRA2)
);
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
const redeemMsg = await redeemOnTerra(
TERRA2_TOKEN_BRIDGE_ADDRESS,
terraWalletAddress,
transferSignedVaa
);
await terraBroadcastAndWaitForExecution([redeemMsg], terraWallet);
expect(
await getIsTransferCompletedTerra(
TERRA2_TOKEN_BRIDGE_ADDRESS,
transferSignedVaa,
lcd,
TERRA2_GAS_PRICES_URL
)
).toBe(true);
});