sdk/js: add tests for aptos sdk
This commit is contained in:
parent
7c1721d199
commit
3bb0562f45
|
@ -3,6 +3,7 @@
|
|||
"^.+\\.(t|j)sx?$": "ts-jest"
|
||||
},
|
||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
||||
"testPathIgnorePatterns": ["__tests__/utils"],
|
||||
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
|
||||
"testTimeout": 60000
|
||||
}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
import { beforeAll, describe, expect, jest, test } from "@jest/globals";
|
||||
import { AptosAccount, AptosClient, FaucetClient, Types } from "aptos";
|
||||
import { ethers } from "ethers";
|
||||
import Web3 from "web3";
|
||||
import {
|
||||
CHAIN_ID_APTOS,
|
||||
CHAIN_ID_ETH,
|
||||
CONTRACTS,
|
||||
deriveResourceAccountAddress,
|
||||
generateSignAndSubmitEntryFunction,
|
||||
tryNativeToUint8Array,
|
||||
} from "../../utils";
|
||||
import { parseNftTransferVaa } from "../../vaa";
|
||||
import { getIsTransferCompletedAptos } from "../getIsTransferCompleted";
|
||||
import { getIsWrappedAssetAptos } from "../getIsWrappedAsset";
|
||||
import { getOriginalAssetAptos } from "../getOriginalAsset";
|
||||
import { redeemOnAptos } from "../redeem";
|
||||
import { transferFromAptos, transferFromEth } from "../transfer";
|
||||
import {
|
||||
APTOS_FAUCET_URL,
|
||||
APTOS_NODE_URL,
|
||||
ETH_NODE_URL,
|
||||
ETH_PRIVATE_KEY,
|
||||
} from "./consts";
|
||||
import { deployTestNftOnEthereum } from "./utils/deployTestNft";
|
||||
import { getSignedVaaAptos, getSignedVaaEthereum } from "./utils/getSignedVaa";
|
||||
|
||||
jest.setTimeout(60000);
|
||||
|
||||
const APTOS_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.aptos.nft_bridge;
|
||||
const ETH_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.nft_bridge;
|
||||
|
||||
let aptosClient: AptosClient;
|
||||
let aptosAccount: AptosAccount;
|
||||
let web3: Web3;
|
||||
let ethProvider: ethers.providers.WebSocketProvider;
|
||||
let ethSigner: ethers.Wallet;
|
||||
|
||||
beforeAll(async () => {
|
||||
// aptos setup
|
||||
aptosClient = new AptosClient(APTOS_NODE_URL);
|
||||
aptosAccount = new AptosAccount();
|
||||
const faucet = new FaucetClient(APTOS_NODE_URL, APTOS_FAUCET_URL);
|
||||
await faucet.fundAccount(aptosAccount.address(), 100_000_000);
|
||||
|
||||
// ethereum setup
|
||||
web3 = new Web3(ETH_NODE_URL);
|
||||
ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
||||
ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY, ethProvider); // corresponds to accounts[1]
|
||||
});
|
||||
|
||||
describe("Aptos NFT SDK tests", () => {
|
||||
test("Transfer ERC-721 from Ethereum to Aptos and back", async () => {
|
||||
const ETH_COLLECTION_NAME = "Not an APE 🐒";
|
||||
|
||||
// create NFT on Ethereum
|
||||
const ethNft = await deployTestNftOnEthereum(
|
||||
web3,
|
||||
ethSigner,
|
||||
ETH_COLLECTION_NAME,
|
||||
"APE🐒",
|
||||
"https://cloudflare-ipfs.com/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/",
|
||||
11
|
||||
);
|
||||
|
||||
// transfer NFT from Ethereum to Aptos
|
||||
const ethTransferTx = await transferFromEth(
|
||||
ETH_NFT_BRIDGE_ADDRESS,
|
||||
ethSigner,
|
||||
ethNft.address,
|
||||
10,
|
||||
CHAIN_ID_APTOS,
|
||||
aptosAccount.address().toUint8Array()
|
||||
);
|
||||
|
||||
// observe tx and get vaa
|
||||
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
|
||||
const ethTransferVaaParsed = parseNftTransferVaa(ethTransferVaa);
|
||||
expect(ethTransferVaaParsed.name).toBe(ETH_COLLECTION_NAME);
|
||||
|
||||
// redeem NFT on Aptos
|
||||
const aptosRedeemPayload = await redeemOnAptos(
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
ethTransferVaa
|
||||
);
|
||||
const aptosRedeemTx = await generateSignAndSubmitEntryFunction(
|
||||
aptosClient,
|
||||
aptosAccount,
|
||||
aptosRedeemPayload
|
||||
);
|
||||
const aptosRedeemTxResult = (await aptosClient.waitForTransactionWithResult(
|
||||
aptosRedeemTx.hash
|
||||
)) as Types.UserTransaction;
|
||||
expect(aptosRedeemTxResult.success).toBe(true);
|
||||
expect(
|
||||
await getIsTransferCompletedAptos(
|
||||
aptosClient,
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
ethTransferVaa
|
||||
)
|
||||
).toBe(true);
|
||||
|
||||
// get creator address
|
||||
const creatorAddress = await deriveResourceAccountAddress(
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
CHAIN_ID_ETH,
|
||||
ethNft.address
|
||||
);
|
||||
expect(creatorAddress).toBeTruthy();
|
||||
expect(
|
||||
await getIsWrappedAssetAptos(
|
||||
aptosClient,
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
creatorAddress!
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
await getOriginalAssetAptos(
|
||||
aptosClient,
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
creatorAddress!
|
||||
)
|
||||
).toMatchObject({
|
||||
isWrapped: true,
|
||||
chainId: CHAIN_ID_ETH,
|
||||
assetAddress: Uint8Array.from(ethTransferVaaParsed.tokenAddress),
|
||||
});
|
||||
|
||||
// transfer NFT from Aptos back to Ethereum
|
||||
const aptosTransferPayload = await transferFromAptos(
|
||||
APTOS_NFT_BRIDGE_ADDRESS,
|
||||
creatorAddress!,
|
||||
ethTransferVaaParsed.name, // TODO(aki): derive this properly
|
||||
ethTransferVaaParsed.tokenId.toString(16).padStart(64, "0"), // TODO(aki): derive this properly
|
||||
0,
|
||||
CHAIN_ID_ETH,
|
||||
tryNativeToUint8Array(ethSigner.address, CHAIN_ID_ETH)
|
||||
);
|
||||
const aptosTransferTx = await generateSignAndSubmitEntryFunction(
|
||||
aptosClient,
|
||||
aptosAccount,
|
||||
aptosTransferPayload
|
||||
);
|
||||
const aptosTransferTxResult =
|
||||
(await aptosClient.waitForTransactionWithResult(
|
||||
aptosTransferTx.hash
|
||||
)) as Types.UserTransaction;
|
||||
expect(aptosTransferTxResult.success).toBe(true);
|
||||
|
||||
// observe tx and get vaa
|
||||
const aptosTransferVaa = await getSignedVaaAptos(
|
||||
aptosClient,
|
||||
aptosTransferTxResult
|
||||
);
|
||||
const aptosTransferVaaParsed = parseNftTransferVaa(aptosTransferVaa);
|
||||
expect(aptosTransferVaaParsed.name).toBe(ETH_COLLECTION_NAME);
|
||||
expect(aptosTransferVaaParsed.tokenAddress.toString("hex")).toBe(
|
||||
ethTransferVaaParsed.tokenAddress.toString("hex")
|
||||
);
|
||||
|
||||
// TODO(aki): make this work
|
||||
// // redeem NFT on Ethereum & check NFT is the same
|
||||
// const ethRedeemTxResult = await redeemOnEth(
|
||||
// ETH_NFT_BRIDGE_ADDRESS,
|
||||
// ethSigner,
|
||||
// aptosTransferVaa,
|
||||
// { gasLimit: 3e7 }
|
||||
// );
|
||||
// console.log(
|
||||
// "ethRedeemTxResult",
|
||||
// JSON.stringify(ethRedeemTxResult, null, 2)
|
||||
// );
|
||||
// expect(ethRedeemTxResult.status).toBe(1);
|
||||
});
|
||||
});
|
||||
function afterAll(arg0: () => Promise<void>) {
|
||||
throw new Error("Function not implemented.");
|
||||
}
|
|
@ -33,6 +33,15 @@ export const WORMHOLE_RPC_HOSTS = ci
|
|||
? ["http://guardian:7071"]
|
||||
: ["http://localhost:7071"];
|
||||
|
||||
export const APTOS_PRIVATE_KEY =
|
||||
"537c1f91e56891445b491068f519b705f8c0f1a1e66111816dd5d4aa85b8113d";
|
||||
export const APTOS_NODE_URL = ci
|
||||
? "http://aptos:8080/v1"
|
||||
: "http://0.0.0.0:8080/v1";
|
||||
export const APTOS_FAUCET_URL = ci
|
||||
? "http://aptos:8081"
|
||||
: "http://0.0.0.0:8081";
|
||||
|
||||
describe("consts should exist", () => {
|
||||
it("has Solana test token", () => {
|
||||
expect.assertions(1);
|
||||
|
|
|
@ -32,10 +32,7 @@ import {
|
|||
SOLANA_PRIVATE_KEY,
|
||||
TEST_SOLANA_TOKEN,
|
||||
} from "./consts";
|
||||
import {
|
||||
waitUntilTransactionObservedEthereum,
|
||||
waitUntilTransactionObservedSolana,
|
||||
} from "./utils/waitUntilTransactionObserved";
|
||||
import { getSignedVaaEthereum, getSignedVaaSolana } from "./utils/getSignedVaa";
|
||||
|
||||
jest.setTimeout(60000);
|
||||
|
||||
|
@ -59,72 +56,6 @@ afterEach(() => {
|
|||
});
|
||||
|
||||
describe("Integration Tests", () => {
|
||||
// TODO: figure out why this isn't working
|
||||
// test("Send Ethereum ERC-721 to Solana and back", (done) => {
|
||||
// (async () => {
|
||||
// try {
|
||||
// const erc721 = await deployNFTOnEth(
|
||||
// "Not an APE 🐒",
|
||||
// "APE🐒",
|
||||
// "https://cloudflare-ipfs.com/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/",
|
||||
// 11 // mint ids 0..10 (inclusive)
|
||||
// );
|
||||
// const sol_addr = await nft_bridge.getForeignAssetSol(
|
||||
// CONTRACTS.DEVNET.solana.nft_bridge,
|
||||
// CHAIN_ID_ETH,
|
||||
// tryNativeToUint8Array(erc721.address, CHAIN_ID_ETH),
|
||||
// arrayify(BigNumber.from("10"))
|
||||
// );
|
||||
// const fromAddress = await Token.getAssociatedTokenAddress(
|
||||
// ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
// TOKEN_PROGRAM_ID,
|
||||
// new PublicKey(sol_addr),
|
||||
// keypair.publicKey
|
||||
// );
|
||||
// const transaction = await _transferFromEth(
|
||||
// erc721.address,
|
||||
// 10,
|
||||
// fromAddress.toString(),
|
||||
// CHAIN_ID_SOLANA
|
||||
// );
|
||||
// let signedVAA = await waitUntilEthTxObserved(transaction);
|
||||
// await _redeemOnSolana(signedVAA);
|
||||
|
||||
// let ownerEth = await erc721.ownerOf(10);
|
||||
// expect(ownerEth).not.toBe(signer.address);
|
||||
|
||||
// // TODO: check wrapped balance
|
||||
|
||||
// // Send back the NFT to ethereum
|
||||
// const transaction2 = await _transferFromSolana(
|
||||
// fromAddress,
|
||||
// sol_addr,
|
||||
// signer.address,
|
||||
// CHAIN_ID_ETH,
|
||||
// tryNativeToUint8Array(erc721.address, CHAIN_ID_ETH),
|
||||
// CHAIN_ID_ETH,
|
||||
// arrayify(BigNumber.from("10"))
|
||||
// );
|
||||
// signedVAA = await waitUntilSolanaTxObserved(transaction2);
|
||||
// (await expectReceivedOnEth(signedVAA)).toBe(false);
|
||||
// await _redeemOnEth(signedVAA);
|
||||
// (await expectReceivedOnEth(signedVAA)).toBe(true);
|
||||
|
||||
// // ensure that the transaction roundtrips back to the original native asset
|
||||
// ownerEth = await erc721.ownerOf(10);
|
||||
// expect(ownerEth).toBe(signer.address);
|
||||
|
||||
// // TODO: the wrapped token should no longer exist
|
||||
|
||||
// done();
|
||||
// } catch (e) {
|
||||
// console.error(e);
|
||||
// done(
|
||||
// `An error occured while trying to transfer from Ethereum to Solana and back: ${e}`
|
||||
// );
|
||||
// }
|
||||
// })();
|
||||
// });
|
||||
test("Send Solana SPL to Ethereum and back", (done) => {
|
||||
(async () => {
|
||||
try {
|
||||
|
@ -140,7 +71,7 @@ describe("Integration Tests", () => {
|
|||
signer.address,
|
||||
CHAIN_ID_ETH
|
||||
);
|
||||
let signedVAA = await waitUntilTransactionObservedSolana(transaction1);
|
||||
let signedVAA = await getSignedVaaSolana(transaction1);
|
||||
|
||||
// we get the solana token id from the VAA
|
||||
const { tokenId } = parseNftTransferVaa(signedVAA);
|
||||
|
@ -162,7 +93,7 @@ describe("Integration Tests", () => {
|
|||
fromAddress.toString(),
|
||||
CHAIN_ID_SOLANA
|
||||
);
|
||||
signedVAA = await waitUntilTransactionObservedEthereum(transaction3);
|
||||
signedVAA = await getSignedVaaEthereum(transaction3);
|
||||
|
||||
const { name, symbol } = parseNftTransferVaa(signedVAA);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { AptosAccount, AptosClient, TokenClient } from "aptos";
|
||||
import { ethers } from "ethers";
|
||||
import Web3 from "web3";
|
||||
import {
|
||||
|
@ -6,6 +7,31 @@ import {
|
|||
} from "../../../ethers-contracts";
|
||||
const ERC721 = require("@openzeppelin/contracts/build/contracts/ERC721PresetMinterPauserAutoId.json");
|
||||
|
||||
export const deployTestNftOnAptos = async (
|
||||
client: AptosClient,
|
||||
account: AptosAccount
|
||||
) => {
|
||||
const tokenClient = new TokenClient(client);
|
||||
const collectionName = "testCollection";
|
||||
const collectionHash = await tokenClient.createCollection(
|
||||
account,
|
||||
collectionName,
|
||||
"test collection",
|
||||
"https://www.wormhole.com"
|
||||
);
|
||||
await client.waitForTransaction(collectionHash);
|
||||
|
||||
const tokenHash = await tokenClient.createToken(
|
||||
account,
|
||||
collectionName,
|
||||
"testToken",
|
||||
"test token",
|
||||
1,
|
||||
"https://wormhole.com/static/a9281881f58cc7fbe4df796a9ba684ac/90d9d/s2.webp"
|
||||
);
|
||||
await client.waitForTransaction(tokenHash);
|
||||
};
|
||||
|
||||
export async function deployTestNftOnEthereum(
|
||||
web3: Web3,
|
||||
signer: ethers.Wallet,
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
import { GetSignedVAAResponse } from "@certusone/wormhole-sdk-proto-web/lib/cjs/publicrpc/v1/publicrpc";
|
||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||
import { TransactionResponse } from "@solana/web3.js";
|
||||
import { AptosClient, Types } from "aptos";
|
||||
import { ethers } from "ethers";
|
||||
import { NftBridgeState } from "../../../aptos/types";
|
||||
import {
|
||||
getEmitterAddressEth,
|
||||
getEmitterAddressSolana,
|
||||
parseSequenceFromLogAptos,
|
||||
parseSequenceFromLogEth,
|
||||
parseSequenceFromLogSolana,
|
||||
} from "../../../bridge";
|
||||
import { getSignedVAAWithRetry } from "../../../rpc";
|
||||
import {
|
||||
ChainId,
|
||||
CHAIN_ID_APTOS,
|
||||
CHAIN_ID_ETH,
|
||||
CHAIN_ID_SOLANA,
|
||||
CONTRACTS,
|
||||
} from "../../../utils";
|
||||
import { WORMHOLE_RPC_HOSTS } from "../consts";
|
||||
|
||||
// TODO(aki): implement getEmitterAddressAptos and sub here
|
||||
export async function getSignedVaaAptos(
|
||||
client: AptosClient,
|
||||
result: Types.UserTransaction
|
||||
): Promise<Uint8Array> {
|
||||
// get the sequence from the logs (needed to fetch the vaa)
|
||||
const sequence = parseSequenceFromLogAptos(
|
||||
CONTRACTS.DEVNET.aptos.core,
|
||||
result
|
||||
);
|
||||
if (sequence === null) {
|
||||
throw new Error("aptos: Could not parse sequence from logs");
|
||||
}
|
||||
|
||||
const nftBridgeAddress = CONTRACTS.DEVNET.aptos.nft_bridge;
|
||||
const state = (await client.getAccountResources(nftBridgeAddress)).find(
|
||||
(r) => r.type === `${nftBridgeAddress}::state::State`
|
||||
);
|
||||
if (!state) {
|
||||
throw new Error("aptos: Could not find State resource");
|
||||
}
|
||||
|
||||
// TODO: ensure 0x is stripped if exists
|
||||
const emitterAddress = (
|
||||
state.data as NftBridgeState
|
||||
).emitter_cap.emitter.padStart(64, "0");
|
||||
|
||||
// poll until the guardian(s) witness and sign the vaa
|
||||
return getSignedVaa(CHAIN_ID_APTOS, emitterAddress, sequence);
|
||||
}
|
||||
|
||||
export async function getSignedVaaEthereum(
|
||||
receipt: ethers.ContractReceipt
|
||||
): Promise<Uint8Array> {
|
||||
// get the sequence from the logs (needed to fetch the vaa)
|
||||
const sequence = parseSequenceFromLogEth(
|
||||
receipt,
|
||||
CONTRACTS.DEVNET.ethereum.core
|
||||
);
|
||||
const emitterAddress = getEmitterAddressEth(
|
||||
CONTRACTS.DEVNET.ethereum.nft_bridge
|
||||
);
|
||||
|
||||
// poll until the guardian(s) witness and sign the vaa
|
||||
return getSignedVaa(CHAIN_ID_ETH, emitterAddress, sequence);
|
||||
}
|
||||
|
||||
export async function getSignedVaaSolana(
|
||||
response: TransactionResponse
|
||||
): Promise<Uint8Array> {
|
||||
// get the sequence from the logs (needed to fetch the vaa)
|
||||
const sequence = parseSequenceFromLogSolana(response);
|
||||
const emitterAddress = getEmitterAddressSolana(
|
||||
CONTRACTS.DEVNET.solana.nft_bridge
|
||||
);
|
||||
|
||||
// poll until the guardian(s) witness and sign the vaa
|
||||
return getSignedVaa(CHAIN_ID_SOLANA, emitterAddress, sequence);
|
||||
}
|
||||
|
||||
const getSignedVaa = async (
|
||||
chain: ChainId,
|
||||
emitterAddress: string,
|
||||
sequence: string
|
||||
): Promise<Uint8Array> => {
|
||||
const { vaaBytes: signedVAA }: GetSignedVAAResponse =
|
||||
await getSignedVAAWithRetry(
|
||||
WORMHOLE_RPC_HOSTS,
|
||||
chain,
|
||||
emitterAddress,
|
||||
sequence,
|
||||
{
|
||||
transport: NodeHttpTransport(),
|
||||
}
|
||||
);
|
||||
return signedVAA;
|
||||
};
|
|
@ -1,57 +0,0 @@
|
|||
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;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||
import { describe, expect, jest, test } from "@jest/globals";
|
||||
import {
|
||||
AptosAccount,
|
||||
|
@ -6,6 +7,8 @@ import {
|
|||
HexString,
|
||||
Types,
|
||||
} from "aptos";
|
||||
import { ethers } from "ethers";
|
||||
import { parseUnits } from "ethers/lib/utils";
|
||||
import {
|
||||
approveEth,
|
||||
APTOS_TOKEN_BRIDGE_EMITTER_ADDRESS,
|
||||
|
@ -17,7 +20,8 @@ import {
|
|||
createWrappedOnAptos,
|
||||
createWrappedOnEth,
|
||||
createWrappedTypeOnAptos,
|
||||
getAssetFullyQualifiedType,
|
||||
generateSignAndSubmitEntryFunction,
|
||||
generateSignAndSubmitScript,
|
||||
getEmitterAddressEth,
|
||||
getExternalAddressFromType,
|
||||
getForeignAssetAptos,
|
||||
|
@ -30,55 +34,45 @@ import {
|
|||
hexToUint8Array,
|
||||
redeemOnAptos,
|
||||
redeemOnEth,
|
||||
generateSignAndSubmitEntryFunction,
|
||||
generateSignAndSubmitScript,
|
||||
transferFromAptos,
|
||||
transferFromEth,
|
||||
tryNativeToHexString,
|
||||
tryNativeToUint8Array,
|
||||
uint8ArrayToHex,
|
||||
} from "../..";
|
||||
import { registerCoin } from "../../aptos";
|
||||
import {
|
||||
parseSequenceFromLogAptos,
|
||||
parseSequenceFromLogEth,
|
||||
} from "../../bridge/parseSequenceFromLog";
|
||||
import { TokenImplementation__factory } from "../../ethers-contracts";
|
||||
import {
|
||||
APTOS_FAUCET_URL,
|
||||
APTOS_NODE_URL,
|
||||
APTOS_PRIVATE_KEY,
|
||||
ETH_NODE_URL,
|
||||
ETH_PRIVATE_KEY6,
|
||||
TEST_ERC20,
|
||||
WORMHOLE_RPC_HOSTS,
|
||||
} from "./consts";
|
||||
import {
|
||||
parseSequenceFromLogAptos,
|
||||
parseSequenceFromLogEth,
|
||||
} from "../../bridge/parseSequenceFromLog";
|
||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||
import { ethers } from "ethers";
|
||||
import { parseUnits } from "ethers/lib/utils";
|
||||
import { registerCoin } from "../../aptos";
|
||||
import { TokenImplementation__factory } from "../../ethers-contracts";
|
||||
|
||||
const JEST_TEST_TIMEOUT = 60000;
|
||||
jest.setTimeout(JEST_TEST_TIMEOUT);
|
||||
|
||||
describe("Aptos SDK tests", () => {
|
||||
test("Transfer native token from Aptos to Ethereum", async () => {
|
||||
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
|
||||
const APTOS_CORE_BRIDGE = CONTRACTS.DEVNET.aptos.core;
|
||||
const COIN_TYPE = "0x1::aptos_coin::AptosCoin";
|
||||
|
||||
// setup aptos
|
||||
const client = new AptosClient(APTOS_NODE_URL);
|
||||
const sender = new AptosAccount();
|
||||
const faucet = new FaucetClient(APTOS_NODE_URL, APTOS_FAUCET_URL);
|
||||
const sender = new AptosAccount(hexToUint8Array(APTOS_PRIVATE_KEY));
|
||||
const aptosTokenBridge = CONTRACTS.DEVNET.aptos.token_bridge;
|
||||
const aptosCoreBridge = CONTRACTS.DEVNET.aptos.core;
|
||||
|
||||
// sanity check funds in the account
|
||||
const COIN_TYPE = "0x1::aptos_coin::AptosCoin";
|
||||
const before = await getBalanceAptos(client, COIN_TYPE, sender.address());
|
||||
await faucet.fundAccount(sender.address(), 100_000_000);
|
||||
const after = await getBalanceAptos(client, COIN_TYPE, sender.address());
|
||||
expect(Number(after) - Number(before)).toEqual(100_000_000);
|
||||
|
||||
// attest native aptos token
|
||||
const attestPayload = attestFromAptos(
|
||||
aptosTokenBridge,
|
||||
APTOS_TOKEN_BRIDGE,
|
||||
CHAIN_ID_APTOS,
|
||||
COIN_TYPE
|
||||
);
|
||||
|
@ -90,7 +84,7 @@ describe("Aptos SDK tests", () => {
|
|||
await client.waitForTransaction(tx.hash);
|
||||
|
||||
// get signed attest vaa
|
||||
let sequence = parseSequenceFromLogAptos(aptosCoreBridge, tx);
|
||||
let sequence = parseSequenceFromLogAptos(APTOS_CORE_BRIDGE, tx);
|
||||
expect(sequence).toBeTruthy();
|
||||
|
||||
const { vaaBytes: attestVAA } = await getSignedVAAWithRetry(
|
||||
|
@ -135,7 +129,7 @@ describe("Aptos SDK tests", () => {
|
|||
await getBalanceAptos(client, COIN_TYPE, sender.address())
|
||||
);
|
||||
const transferPayload = transferFromAptos(
|
||||
aptosTokenBridge,
|
||||
APTOS_TOKEN_BRIDGE,
|
||||
COIN_TYPE,
|
||||
(10_000_000).toString(),
|
||||
CHAIN_ID_ETH,
|
||||
|
@ -157,7 +151,7 @@ describe("Aptos SDK tests", () => {
|
|||
).toBe(true);
|
||||
|
||||
// get signed transfer vaa
|
||||
sequence = parseSequenceFromLogAptos(aptosCoreBridge, tx);
|
||||
sequence = parseSequenceFromLogAptos(APTOS_CORE_BRIDGE, tx);
|
||||
expect(sequence).toBeTruthy();
|
||||
|
||||
const { vaaBytes: transferVAA } = await getSignedVAAWithRetry(
|
||||
|
@ -243,7 +237,9 @@ describe("Aptos SDK tests", () => {
|
|||
|
||||
// setup aptos
|
||||
const client = new AptosClient(APTOS_NODE_URL);
|
||||
const recipient = new AptosAccount(hexToUint8Array(APTOS_PRIVATE_KEY));
|
||||
const recipient = new AptosAccount();
|
||||
const faucet = new FaucetClient(APTOS_NODE_URL, APTOS_FAUCET_URL);
|
||||
await faucet.fundAccount(recipient.address(), 100_000_000);
|
||||
const aptosTokenBridge = CONTRACTS.DEVNET.aptos.token_bridge;
|
||||
const createWrappedCoinTypePayload = createWrappedTypeOnAptos(
|
||||
aptosTokenBridge,
|
||||
|
|
|
@ -172,7 +172,8 @@ const MAINNET = {
|
|||
core: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
||||
token_bridge:
|
||||
"0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f",
|
||||
nft_bridge: "0x1bdffae984043833ed7fe223f7af7a3f8902d04129b14f801823e64827da7130",
|
||||
nft_bridge:
|
||||
"0x1bdffae984043833ed7fe223f7af7a3f8902d04129b14f801823e64827da7130",
|
||||
},
|
||||
sui: {
|
||||
core: undefined,
|
||||
|
@ -328,7 +329,8 @@ const TESTNET = {
|
|||
core: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
||||
token_bridge:
|
||||
"0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f",
|
||||
nft_bridge: undefined,
|
||||
nft_bridge:
|
||||
"0x1bdffae984043833ed7fe223f7af7a3f8902d04129b14f801823e64827da7130",
|
||||
},
|
||||
sui: {
|
||||
core: undefined,
|
||||
|
@ -484,7 +486,8 @@ const DEVNET = {
|
|||
core: "0xde0036a9600559e295d5f6802ef6f3f802f510366e0c23912b0655d972166017",
|
||||
token_bridge:
|
||||
"0x84a5f374d29fc77e370014dce4fd6a55b58ad608de8074b0be5571701724da31",
|
||||
nft_bridge: undefined,
|
||||
nft_bridge:
|
||||
"0x46da3d4c569388af61f951bdd1153f4c875f90c2991f6b2d0a38e2161a40852c",
|
||||
},
|
||||
sui: {
|
||||
core: undefined,
|
||||
|
|
Loading…
Reference in New Issue