sdk/js: refactor nft test utils

This commit is contained in:
heyitaki 2023-01-17 17:48:17 +00:00 committed by Evan Gray
parent 8dcd3f615f
commit f584f5c739
3 changed files with 121 additions and 128 deletions

View File

@ -1,6 +1,3 @@
import axios from "axios";
import Web3 from "web3";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import {
afterEach,
beforeEach,
@ -9,71 +6,46 @@ import {
jest,
test,
} from "@jest/globals";
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
getAssociatedTokenAddress,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import { BigNumber, BigNumberish, ethers } from "ethers";
import {
ChainId,
CHAIN_ID_ETH,
CHAIN_ID_TERRA,
CONTRACTS,
getEmitterAddressEth,
getEmitterAddressTerra,
parseSequenceFromLogEth,
parseSequenceFromLogTerra,
nft_bridge,
parseSequenceFromLogSolana,
getEmitterAddressSolana,
CHAIN_ID_SOLANA,
} from "../..";
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
import {
ETH_NODE_URL,
ETH_PRIVATE_KEY,
TERRA_GAS_PRICES_URL,
WORMHOLE_RPC_HOSTS,
TERRA_CW721_CODE_ID,
TERRA_NODE_URL,
TERRA_CHAIN_ID,
TERRA_PRIVATE_KEY,
SOLANA_PRIVATE_KEY,
TEST_SOLANA_TOKEN,
SOLANA_HOST,
} from "./consts";
import {
NFTImplementation,
NFTImplementation__factory,
} from "../../ethers-contracts";
import sha3 from "js-sha3";
import { getAssociatedTokenAddress } from "@solana/spl-token";
import {
Connection,
Keypair,
PublicKey,
TransactionResponse,
} from "@solana/web3.js";
import { BigNumberish, ethers } from "ethers";
import Web3 from "web3";
import {
ChainId,
CHAIN_ID_ETH,
CHAIN_ID_SOLANA,
CONTRACTS,
nft_bridge,
} from "../..";
import { postVaaSolanaWithRetry } from "../../solana";
import { tryNativeToUint8Array } from "../../utils";
import { arrayify } from "ethers/lib/utils";
import { parseVaa } from "../../vaa/wormhole";
import { parseNftTransferVaa } from "../../vaa";
const ERC721 = require("@openzeppelin/contracts/build/contracts/ERC721PresetMinterPauserAutoId.json");
import {
ETH_NODE_URL,
ETH_PRIVATE_KEY,
SOLANA_HOST,
SOLANA_PRIVATE_KEY,
TEST_SOLANA_TOKEN,
} from "./consts";
import {
waitUntilTransactionObservedEthereum,
waitUntilTransactionObservedSolana,
} from "./utils/waitUntilTransactionObserved";
jest.setTimeout(60000);
type Address = string;
// ethereum setup
const web3 = new Web3(ETH_NODE_URL);
let provider: ethers.providers.WebSocketProvider;
let signer: ethers.Wallet;
// solana setup
const connection = new Connection(SOLANA_HOST, "confirmed");
const keypair = Keypair.fromSecretKey(SOLANA_PRIVATE_KEY);
const payerAddress = keypair.publicKey.toString();
@ -168,7 +140,7 @@ describe("Integration Tests", () => {
signer.address,
CHAIN_ID_ETH
);
let signedVAA = await waitUntilSolanaTxObserved(transaction1);
let signedVAA = await waitUntilTransactionObservedSolana(transaction1);
// we get the solana token id from the VAA
const { tokenId } = parseNftTransferVaa(signedVAA);
@ -190,7 +162,7 @@ describe("Integration Tests", () => {
fromAddress.toString(),
CHAIN_ID_SOLANA
);
signedVAA = await waitUntilEthTxObserved(transaction3);
signedVAA = await waitUntilTransactionObservedEthereum(transaction3);
const { name, symbol } = parseNftTransferVaa(signedVAA);
@ -214,83 +186,6 @@ describe("Integration Tests", () => {
////////////////////////////////////////////////////////////////////////////////
// Utils
async function deployNFTOnEth(
name: string,
symbol: string,
uri: string,
how_many: number
): Promise<NFTImplementation> {
const accounts = await web3.eth.getAccounts();
const nftContract = new web3.eth.Contract(ERC721.abi);
let nft = await nftContract
.deploy({
data: ERC721.bytecode,
arguments: [name, symbol, uri],
})
.send({
from: accounts[1],
gas: 5000000,
});
// The eth contracts mints tokens with sequential ids, so in order to get to a
// specific id, we need to mint multiple nfts. We need this to test that
// foreign ids on terra get converted to the decimal stringified form of the
// original id.
for (var i = 0; i < how_many; i++) {
await nft.methods.mint(accounts[1]).send({
from: accounts[1],
gas: 1000000,
});
}
return NFTImplementation__factory.connect(nft.options.address, signer);
}
async function waitUntilEthTxObserved(
receipt: ethers.ContractReceipt
): Promise<Uint8Array> {
// get the sequence from the logs (needed to fetch the vaa)
let sequence = parseSequenceFromLogEth(
receipt,
CONTRACTS.DEVNET.ethereum.core
);
let emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.nft_bridge
);
// poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS,
CHAIN_ID_ETH,
emitterAddress,
sequence,
{
transport: NodeHttpTransport(),
}
);
return signedVAA;
}
async function waitUntilSolanaTxObserved(
response: TransactionResponse
): Promise<Uint8Array> {
// get the sequence from the logs (needed to fetch the vaa)
const sequence = parseSequenceFromLogSolana(response);
const emitterAddress = await getEmitterAddressSolana(
CONTRACTS.DEVNET.solana.nft_bridge
);
// poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS,
CHAIN_ID_SOLANA,
emitterAddress,
sequence,
{
transport: NodeHttpTransport(),
}
);
return signedVAA;
}
async function expectReceivedOnEth(signedVAA: Uint8Array) {
return expect(
await nft_bridge.getIsTransferCompletedEth(

View File

@ -0,0 +1,41 @@
import { ethers } from "ethers";
import Web3 from "web3";
import {
NFTImplementation,
NFTImplementation__factory,
} from "../../../ethers-contracts";
const ERC721 = require("@openzeppelin/contracts/build/contracts/ERC721PresetMinterPauserAutoId.json");
export async function deployTestNftOnEthereum(
web3: Web3,
signer: ethers.Wallet,
name: string,
symbol: string,
uri: string,
howMany: number
): Promise<NFTImplementation> {
const accounts = await web3.eth.getAccounts();
const nftContract = new web3.eth.Contract(ERC721.abi);
let nft = await nftContract
.deploy({
data: ERC721.bytecode,
arguments: [name, symbol, uri],
})
.send({
from: accounts[1],
gas: 5000000,
});
// The eth contracts mints tokens with sequential ids, so in order to get to a
// specific id, we need to mint multiple nfts. We need this to test that
// foreign ids on terra get converted to the decimal stringified form of the
// original id.
for (var i = 0; i < howMany; i++) {
await nft.methods.mint(accounts[1]).send({
from: accounts[1],
gas: 1000000,
});
}
return NFTImplementation__factory.connect(nft.options.address, signer);
}

View File

@ -0,0 +1,57 @@
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { TransactionResponse } from "@solana/web3.js";
import { ethers } from "ethers";
import {
getEmitterAddressEth,
getEmitterAddressSolana,
parseSequenceFromLogEth,
parseSequenceFromLogSolana,
} from "../../../bridge";
import { getSignedVAAWithRetry } from "../../../rpc";
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA, CONTRACTS } from "../../../utils";
import { WORMHOLE_RPC_HOSTS } from "../consts";
export async function waitUntilTransactionObservedEthereum(
receipt: ethers.ContractReceipt
): Promise<Uint8Array> {
// get the sequence from the logs (needed to fetch the vaa)
let sequence = parseSequenceFromLogEth(
receipt,
CONTRACTS.DEVNET.ethereum.core
);
let emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.nft_bridge
);
// poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS,
CHAIN_ID_ETH,
emitterAddress,
sequence,
{
transport: NodeHttpTransport(),
}
);
return signedVAA;
}
export async function waitUntilTransactionObservedSolana(
response: TransactionResponse
): Promise<Uint8Array> {
// get the sequence from the logs (needed to fetch the vaa)
const sequence = parseSequenceFromLogSolana(response);
const emitterAddress = await getEmitterAddressSolana(
CONTRACTS.DEVNET.solana.nft_bridge
);
// poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS,
CHAIN_ID_SOLANA,
emitterAddress,
sequence,
{
transport: NodeHttpTransport(),
}
);
return signedVAA;
}