aptos
Version:
867 lines (730 loc) • 34 kB
text/typescript
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
import { AptosClient } from "../../providers/aptos_client";
import * as Gen from "../../generated/index";
import { AptosAccount } from "../../account/aptos_account";
import {
TxnBuilderTypes,
TransactionBuilderMultiEd25519,
TransactionBuilderRemoteABI,
} from "../../transaction_builder";
import { AptosToken, TokenClient } from "../../plugins";
import { HexString } from "../../utils";
import { getFaucetClient, longTestTimeout, NODE_URL, PROVIDER_LOCAL_NETWORK_CONFIG } from "../unit/test_helper.test";
import { bcsSerializeUint64, bcsToBytes } from "../../bcs";
import { AccountAddress, Ed25519PublicKey, stringStructTag, TypeTagStruct } from "../../aptos_types";
import { Provider } from "../../providers";
import { BCS } from "../..";
import { WriteSetChange_WriteResource } from "../../generated/index";
const account = "0x1::account::Account";
const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>";
test("node url empty", () => {
expect(() => {
const client = new AptosClient("");
client.getAccount("0x1");
}).toThrow("Node URL cannot be empty.");
});
test("gets genesis account", async () => {
const client = new AptosClient(NODE_URL);
const genesisAccount = await client.getAccount("0x1");
expect(genesisAccount.authentication_key.length).toBe(66);
expect(genesisAccount.sequence_number).not.toBeNull();
});
test("gets transactions", async () => {
const client = new AptosClient(NODE_URL);
const transactions = await client.getTransactions();
expect(transactions.length).toBeGreaterThan(0);
});
test("gets genesis resources", async () => {
const client = new AptosClient(NODE_URL);
const resources = await client.getAccountResources("0x1");
const accountResource = resources.find((r) => r.type === account);
expect(accountResource).toBeDefined();
});
test(
"gets object",
async () => {
const alice = new AptosAccount();
const faucetClient = getFaucetClient();
await faucetClient.fundAccount(alice.address(), 100000000);
const provider = new Provider({
fullnodeUrl: NODE_URL,
indexerUrl: NODE_URL,
});
const aptosToken = new AptosToken(provider);
const txn = await provider.waitForTransactionWithResult(
await aptosToken.createCollection(alice, "Alice's simple collection", "AliceCollection", "https://aptos.dev"),
{ checkSuccess: true },
);
const objectCore = (txn as Gen.UserTransaction).changes.find(
(change) => (change as Gen.WriteResource).data.type === "0x1::object::ObjectCore",
);
const objectAddress = (objectCore as WriteSetChange_WriteResource).address;
const object = await provider.getAccountResource(objectAddress, "0x4::aptos_token::AptosCollection");
expect(object.type).toBeDefined();
expect(object.data).toBeDefined();
},
longTestTimeout,
);
test("gets the Account resource", async () => {
const client = new AptosClient(NODE_URL);
const accountResource = await client.getAccountResource("0x1", account);
expect(accountResource).toBeDefined();
});
test("gets ledger info", async () => {
const client = new AptosClient(NODE_URL);
const ledgerInfo = await client.getLedgerInfo();
expect(ledgerInfo.chain_id).toBeGreaterThan(1);
expect(parseInt(ledgerInfo.ledger_version, 10)).toBeGreaterThan(0);
});
test("gets account modules", async () => {
const client = new AptosClient(NODE_URL);
const modules = await client.getAccountModules("0x1");
const module = modules.find((r) => r.abi!.name === "aptos_coin");
expect(module!.abi!.address).toBe("0x1");
});
test("gets the AptosCoin module", async () => {
const client = new AptosClient(NODE_URL);
const module = await client.getAccountModule("0x1", "aptos_coin");
expect(module!.abi!.address).toBe("0x1");
});
test(
"submits bcs transaction",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const account1 = new AptosAccount();
await faucetClient.fundAccount(account1.address(), 100_000_000);
let resources = await client.getAccountResources(account1.address());
let accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("100000000");
const account2 = new AptosAccount();
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x1::aptos_account",
"transfer",
[],
[bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account2.address())), bcsSerializeUint64(717)],
),
);
const rawTxn = await client.generateRawTransaction(account1.address(), entryFunctionPayload);
const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn);
const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
await client.waitForTransaction(transactionRes.hash);
resources = await client.getAccountResources(account2.address());
accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("717");
},
longTestTimeout,
);
test(
"submits generic type bcs transaction",
async () => {
const provider = new Provider(PROVIDER_LOCAL_NETWORK_CONFIG);
const aptosToken = new AptosToken(provider);
const account1 = new AptosAccount();
const faucetClient = getFaucetClient();
await faucetClient.fundAccount(account1.address(), 100_000_000);
let resources = await provider.getAccountResources(account1.address());
let accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("100000000");
let tokenAddress = "";
await provider.waitForTransaction(
await aptosToken.createCollection(account1, "Collection description", "Collection Name", "https://aptos.dev", 5, {
royaltyNumerator: 10,
royaltyDenominator: 10,
}),
);
const txn = await provider.waitForTransactionWithResult(
await aptosToken.mint(
account1,
"Collection Name",
"Token Description",
"Token Name",
"https://aptos.dev/img/nyan.jpeg",
["key"],
["bool"],
["true"],
),
{ checkSuccess: true },
);
tokenAddress = (txn as Gen.UserTransaction).events[0].data.token;
const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x4::token::Token"));
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x4::aptos_token",
"add_typed_property",
[token, new TypeTagStruct(stringStructTag)],
[
BCS.bcsToBytes(AccountAddress.fromHex(tokenAddress)),
BCS.bcsSerializeStr("bcsKey"),
BCS.bcsSerializeStr("bcs value"),
],
),
);
const rawTxn = await provider.generateRawTransaction(account1.address(), entryFunctionPayload);
const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn);
const transactionRes = await provider.submitSignedBCSTransaction(bcsTxn);
await provider.waitForTransaction(transactionRes.hash, { checkSuccess: true });
},
longTestTimeout,
);
test(
"submits transaction with remote ABI",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const sender = new AptosAccount();
await faucetClient.fundAccount(sender.address(), 100_000_000);
let resources = await client.getAccountResources(sender.address());
let accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("100000000");
const receiver = new AptosAccount();
const builder = new TransactionBuilderRemoteABI(client, { sender: sender.address() });
const rawTxn = await builder.build("0x1::aptos_account::transfer", [], [receiver.address(), 400]);
const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTxn);
const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
await client.waitForTransaction(transactionRes.hash);
resources = await client.getAccountResources(receiver.address());
accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("400");
},
longTestTimeout,
);
test(
"submits multisig transaction simulation",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const account1 = new AptosAccount();
const account2 = new AptosAccount();
const account3 = new AptosAccount();
const multiSigPublicKey = new TxnBuilderTypes.MultiEd25519PublicKey(
[
new TxnBuilderTypes.Ed25519PublicKey(account1.signingKey.publicKey),
new TxnBuilderTypes.Ed25519PublicKey(account2.signingKey.publicKey),
new TxnBuilderTypes.Ed25519PublicKey(account3.signingKey.publicKey),
],
2,
);
const authKey = TxnBuilderTypes.AuthenticationKey.fromMultiEd25519PublicKey(multiSigPublicKey);
const mutisigAccountAddress = authKey.derivedAddress();
await faucetClient.fundAccount(mutisigAccountAddress, 50000000);
let resources = await client.getAccountResources(mutisigAccountAddress);
let accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("50000000");
const account4 = new AptosAccount();
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x1::aptos_account",
"transfer",
[],
[bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account4.address())), bcsSerializeUint64(123)],
),
);
const rawTxn = await client.generateRawTransaction(mutisigAccountAddress, entryFunctionPayload);
const txnBuilder = new TransactionBuilderMultiEd25519((signingMessage: TxnBuilderTypes.SigningMessage) => {
const sigHexStr1 = account1.signBuffer(signingMessage);
const sigHexStr3 = account3.signBuffer(signingMessage);
const bitmap = TxnBuilderTypes.MultiEd25519Signature.createBitmap([0, 2]);
const muliEd25519Sig = new TxnBuilderTypes.MultiEd25519Signature(
[
new TxnBuilderTypes.Ed25519Signature(sigHexStr1.toUint8Array()),
new TxnBuilderTypes.Ed25519Signature(sigHexStr3.toUint8Array()),
],
bitmap,
);
return muliEd25519Sig;
}, multiSigPublicKey);
// simulate transaction
const [simulateTransactionRes] = await client.simulateTransaction(multiSigPublicKey, rawTxn, {
estimateGasUnitPrice: true,
estimateMaxGasAmount: true,
estimatePrioritizedGasUnitPrice: true,
});
expect(parseInt(simulateTransactionRes.gas_used, 10) > 0);
expect(simulateTransactionRes.success);
const bcsTxn = txnBuilder.sign(rawTxn);
const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
await client.waitForTransaction(transactionRes.hash);
resources = await client.getAccountResources(account4.address());
accountResource = resources.find((r) => r.type === aptosCoin);
expect((accountResource!.data as any).coin.value).toBe("123");
},
longTestTimeout,
);
test(
"submits json transaction simulation",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const account1 = new AptosAccount();
const account2 = new AptosAccount();
const txns1 = await faucetClient.fundAccount(account1.address(), 1000000);
const tx1 = await client.getTransactionByHash(txns1[0]);
expect(tx1.type).toBe("user_transaction");
const checkAptosCoin = async () => {
const resources1 = await client.getAccountResources(account1.address());
const account1Resource = resources1.find((r) => r.type === aptosCoin);
expect((account1Resource!.data as { coin: { value: string } }).coin.value).toBe("1000000");
};
await checkAptosCoin();
const payload: Gen.TransactionPayload = {
type: "entry_function_payload",
function: "0x1::aptos_account::transfer",
type_arguments: [],
arguments: [account2.address().hex(), 100000],
};
const txnRequest = await client.generateTransaction(account1.address(), payload);
[account1, new Ed25519PublicKey(account1.pubKey().toUint8Array())].forEach(async (accountOrAddress) => {
const transactionRes = (
await client.simulateTransaction(accountOrAddress, txnRequest, {
estimateGasUnitPrice: true,
estimateMaxGasAmount: true,
estimatePrioritizedGasUnitPrice: true,
})
)[0];
expect(parseInt(transactionRes.gas_used, 10) > 0);
expect(transactionRes.success);
const account2AptosCoin = transactionRes.changes.filter((change) => {
if (change.type !== "write_resource") {
return false;
}
const write = change as Gen.WriteResource;
return (
write.address === account2.address().hex() &&
write.data.type === aptosCoin &&
(write.data.data as { coin: { value: string } }).coin.value === "100000"
);
});
expect(account2AptosCoin).toHaveLength(1);
});
await checkAptosCoin();
},
longTestTimeout,
);
test(
"it returns succeed transaction data",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const sender = new AptosAccount();
const receiver = new AptosAccount();
await faucetClient.fundAccount(sender.address(), 100_000_000);
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x1::aptos_account",
"transfer",
[],
[bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(receiver.address())), bcsSerializeUint64(1000)],
),
);
const txn = await client.generateSignSubmitWaitForTransaction(sender, entryFunctionPayload, { checkSuccess: true });
expect((txn as any).success).toBeTruthy();
expect(txn as any).toHaveProperty("changes");
expect((txn as any).vm_status).toEqual("Executed successfully");
},
longTestTimeout,
);
test(
"it returns failed transaction reason",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const sender = new AptosAccount();
const receiver = new AptosAccount();
await faucetClient.fundAccount(sender.address(), 100_000_000);
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x1::aptos_account",
"transfer",
[],
[bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(receiver.address()))],
),
);
const rawTxn = await client.generateRawTransaction(sender.address(), entryFunctionPayload);
const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTxn);
const txn = await client.submitSignedBCSTransaction(bcsTxn);
expect(async () => {
await client.waitForTransactionWithResult(txn.hash, { checkSuccess: true });
}).rejects.toThrow(
`Transaction ${txn.hash} failed with an error: Transaction Executed and Committed with Error NUMBER_OF_ARGUMENTS_MISMATCH`,
);
},
longTestTimeout,
);
test(
"submits bcs transaction simulation",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const sender = new AptosAccount();
const receiver = new AptosAccount();
const txns1 = await faucetClient.fundAccount(sender.address(), 100_000_000);
const tx1 = await client.getTransactionByHash(txns1[0]);
expect(tx1.type).toBe("user_transaction");
const checkAptosCoin = async () => {
const resources1 = await client.getAccountResources(sender.address());
const senderResource = resources1.find((r) => r.type === aptosCoin);
expect((senderResource!.data as { coin: { value: string } }).coin.value).toBe("100000000");
};
await checkAptosCoin();
const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
"0x1::aptos_account",
"transfer",
[],
[bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(receiver.address())), bcsSerializeUint64(1000)],
),
);
const rawTxn = await client.generateRawTransaction(sender.address(), entryFunctionPayload);
const bcsTxn = AptosClient.generateBCSSimulation(sender, rawTxn);
const transactionRes = (await client.submitBCSSimulation(bcsTxn))[0];
expect(parseInt(transactionRes.gas_used, 10) > 0);
expect(transactionRes.success);
const receiverAptosCoin = transactionRes.changes.filter((change) => {
if (change.type !== "write_resource") {
return false;
}
const write = change as Gen.WriteResource;
return (
write.address === receiver.address().toShortString() &&
write.data.type === aptosCoin &&
(write.data.data as { coin: { value: string } }).coin.value === "1000"
);
});
expect(receiverAptosCoin).toHaveLength(1);
await checkAptosCoin();
},
longTestTimeout,
);
test(
"submits multiagent transaction",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const tokenClient = new TokenClient(client);
const alice = new AptosAccount();
const bob = new AptosAccount();
// Fund both Alice's and Bob's Account
await faucetClient.fundAccount(alice.address(), 100000000);
await faucetClient.fundAccount(bob.address(), 100000000);
const collectionName = "AliceCollection";
const tokenName = "Alice Token";
async function ensureTxnSuccess(txnHashPromise: Promise<string>) {
const txnHash = await txnHashPromise;
const txn = await client.waitForTransactionWithResult(txnHash);
expect((txn as any)?.success).toBe(true);
}
// Create collection and token on Alice's account
await ensureTxnSuccess(
tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"),
);
await ensureTxnSuccess(
tokenClient.createToken(
alice,
collectionName,
tokenName,
"Alice's simple token",
1,
"https://aptos.dev/img/nyan.jpeg",
1000,
alice.address(),
0,
0,
["key"],
["2"],
["u64"],
),
);
const propertyVersion = 0;
const tokenId = {
token_data_id: {
creator: alice.address().hex(),
collection: collectionName,
name: tokenName,
},
property_version: `${propertyVersion}`,
};
// Transfer Token from Alice's Account to Bob's Account
await tokenClient.getCollectionData(alice.address().hex(), collectionName);
let aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId);
expect(aliceBalance.amount).toBe("1");
const txnHash = await tokenClient.directTransferToken(
alice,
bob,
alice.address(),
collectionName,
tokenName,
1,
propertyVersion,
);
await client.waitForTransaction(txnHash, { checkSuccess: true });
aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId);
expect(aliceBalance.amount).toBe("0");
const bobBalance = await tokenClient.getTokenForAccount(bob.address().hex(), tokenId);
expect(bobBalance.amount).toBe("1");
},
longTestTimeout,
);
test(
"submits fee payer transaction with no secondary signers",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const alice = new AptosAccount();
const bob = new AptosAccount();
const feePayer = new AptosAccount();
// Fund Alice's and feePayer's Accounts
await faucetClient.fundAccount(alice.address(), 100000000);
await faucetClient.fundAccount(feePayer.address(), 100000000);
const getBalance = async (account: AptosAccount) => {
const resources = await client.getAccountResources(account.address().hex());
let accountResource = resources.find((r) => r.type === aptosCoin);
return BigInt((accountResource!.data as any).coin.value);
};
const aliceBefore = await getBalance(alice);
const feePayerBefore = await getBalance(feePayer);
// Alice transfers 100000 coins to Bob's Account with feePayer paying the fee
const payload: Gen.EntryFunctionPayload = {
function: "0x1::aptos_account::transfer",
type_arguments: [],
arguments: [bob.address().hex(), 100000],
};
// Create a fee payer transaction with the sender, transaction payload, and fee payer account
const feePayerTxn = await client.generateFeePayerTransaction(alice.address().hex(), payload, feePayer.address());
// sender and fee payer need to sign the transaction
const senderAuthenticator = await client.signMultiTransaction(alice, feePayerTxn);
const feePayerAuthenticator = await client.signMultiTransaction(feePayer, feePayerTxn);
// submit gas fee payer transaction
const txn = await client.submitFeePayerTransaction(feePayerTxn, senderAuthenticator, feePayerAuthenticator);
await client.waitForTransaction(txn.hash, { checkSuccess: true });
// Check that Alice and Bob did not pay the fee
// Alice final balance is -100000 coins transfered to Bob
expect(await getBalance(alice)).toBe(aliceBefore - BigInt(100000));
// Bob final balance is 100000 coins transfered from Alice
expect(await getBalance(bob)).toBe(BigInt(100000));
// Check that feePayer paid the fee
expect(await getBalance(feePayer)).toBeLessThan(feePayerBefore);
},
longTestTimeout,
);
test(
"submits fee payer transaction with secondary signers",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const tokenClient = new TokenClient(client);
const alice = new AptosAccount();
const bob = new AptosAccount();
const feePayer = new AptosAccount();
// Fund both Alice's and Bob's Account
await faucetClient.fundAccount(alice.address(), 100000000);
await faucetClient.fundAccount(bob.address(), 100000000);
await faucetClient.fundAccount(feePayer.address(), 100000000);
const collectionName = "AliceCollection";
const tokenName = "Alice Token";
async function ensureTxnSuccess(txnHashPromise: Promise<string>) {
const txnHash = await txnHashPromise;
const txn = await client.waitForTransactionWithResult(txnHash);
expect((txn as any)?.success).toBe(true);
}
// Create collection and token on Alice's account
await ensureTxnSuccess(
tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"),
);
await ensureTxnSuccess(
tokenClient.createToken(
alice,
collectionName,
tokenName,
"Alice's simple token",
1,
"https://aptos.dev/img/nyan.jpeg",
1000,
alice.address(),
0,
0,
["key"],
["2"],
["u64"],
),
);
const propertyVersion = 0;
const tokenId = {
token_data_id: {
creator: alice.address().hex(),
collection: collectionName,
name: tokenName,
},
property_version: `${propertyVersion}`,
};
// Transfer Token from Alice's Account to Bob's Account with bob paying the fee
await tokenClient.getCollectionData(alice.address().hex(), collectionName);
let aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId);
expect(aliceBalance.amount).toBe("1");
const getBalance = async (account: AptosAccount) => {
const resources = await client.getAccountResources(account.address().hex());
let accountResource = resources.find((r) => r.type === aptosCoin);
return BigInt((accountResource!.data as any).coin.value);
};
const aliceBefore = await getBalance(alice);
const bobBefore = await getBalance(bob);
const feePayerBefore = await getBalance(feePayer);
const payload: Gen.EntryFunctionPayload = {
function: "0x3::token::direct_transfer_script",
type_arguments: [],
arguments: [alice.address(), collectionName, tokenName, propertyVersion, 1],
};
// Create a fee payer transaction with the sender, transaction payload, fee payer account and secondary signers
const feePayerTxn = await client.generateFeePayerTransaction(alice.address().hex(), payload, feePayer.address(), [
bob.address(),
]);
// sender and fee payer need to sign the transaction
const senderAuthenticator = await client.signMultiTransaction(alice, feePayerTxn);
const seconderySignerAuthenticator = await client.signMultiTransaction(bob, feePayerTxn);
const feePayerAuthenticator = await client.signMultiTransaction(feePayer, feePayerTxn);
// submit gas fee payer transaction
const txn = await client.submitFeePayerTransaction(feePayerTxn, senderAuthenticator, feePayerAuthenticator, [
seconderySignerAuthenticator,
]);
await client.waitForTransaction(txn.hash, { checkSuccess: true });
// Check that Alice and Bob did not pay the fee
// Alice final balance is -100000 coins transfered to Bob
expect(await getBalance(alice)).toBe(aliceBefore);
// Bob final balance is 100000 coins transfered from Alice
expect(await getBalance(bob)).toBe(bobBefore);
// Check that feePayer paid the fee
expect(await getBalance(feePayer)).toBeLessThan(feePayerBefore);
},
longTestTimeout,
);
test(
"publishes a package",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const account1 = new AptosAccount(
new HexString("0x883fdd67576e5fdceb370ba665b8af8856d0cae63fd808b8d16077c6b008ea8c").toUint8Array(),
);
await faucetClient.fundAccount(account1.address(), 100_000_000);
const txnHash = await client.publishPackage(
account1,
new HexString(
// eslint-disable-next-line max-len
"084578616d706c657301000000000000000040314137344146383742383132393043323533323938383036373846304137444637393737373637383734334431434345443230413446354345334238464446388f011f8b08000000000002ff3dccc10ac2300c06e07b9ea2f46ee70b78f0a02f31c6886d74a55d5b1a51417c7713c1915c927cf9c7863ee18d2628b89239187b7ae1da32b18507758eb5e872efa42cc088217462269e60a19ceb7cc9d527bf60fcb9594da0462550f151d9b1dd2b9fbba43f6b4f82de465e302b776e90befe8f03aadd6db3351ff802f2294cdfa100000001076d6573736167658f051f8b08000000000002ff95555d6bdb30147dcfafb8ed20d8c52c1d8c3194a6ec83b0be747be8dec6108a7d9d983a5226c94dc3f07f9f2cd98e6cc769e787884857e79e73bfb4154991236c30cf055de5227e8c372ce3846c5129b646f83b01f3150a41e984109452c879774f656b8e834d2d33be3e6eb29d168aa6926d712fe423212c8e45c175dfc27979c2ea64329b910b722b518942c6682d0d6e116bb877f4ee449ea0840d53f088879a6cf5d5f409381e843cd835ea1b5023979bc57a5404ec4ac8b25aee184f72bca95d7db586f6e0d6c19486df8d21d8f23b41d0bb65592652ec226323247a6c5329b6f445ca5a9cb7291d81d96c063f37681c640ab86894c2cef03434ac4d2cb8d2b0fcfe83de2f1f1e3e7f5b12283ebc87055ccf1dc8ae58e5590c69c1618dbaf11bb0249104aa5fb311f669008bff149939eaa5e728942985525f04f89c29ad6e3a66b7163d8cc0d618215c689a9a1249028f6718ce5bb0abe94a18d33d5de762c5f293686f6be67e806a6d2616f260152a5fa12b4b23cd5675345649a1857a51708e1a6a485a11322176c0a6015c14a94883696de289cb52082e46c2e4e185a1e7ccd6b57842aa450b198d52eb75423476d06f91264284e3de6dd2cd68a71ca575f1cbb0fd5b02e60a7bc4aab819c24d5ae8c6b15f4027e5745be8b3d1990f40fd56337057d3a197a666ba97ebc980db4c3bd5c1d47887f1ebddb845a726c230193ebd6146fc09108bdde174eeca9eec718a260003ada5df2a6f7e6954ba89a931ff74fdfc2efc3dd646dc60d398717aa6a3c25736cdff34cbd8e342482c9169a44d51a44252a7a85b1d27f846d0767ca1d38fc1eaf2ae7a2423f8d2be9297d5341acc362ff6fdd119c262f10a543f9ddeec6b776be2e5a49cfc0325c63f11c007000000000300000000000000000000000000000000000000000000000000000000000000010e4170746f734672616d65776f726b00000000000000000000000000000000000000000000000000000000000000010b4170746f735374646c696200000000000000000000000000000000000000000000000000000000000000010a4d6f76655374646c696200",
).toUint8Array(),
[
new TxnBuilderTypes.Module(
new HexString(
// eslint-disable-next-line max-len
"a11ceb0b050000000c01000c020c12031e20043e04054228076ad50108bf024006ff020a108903450ace03150ce3035f0dc20404000001010102010301040105000606000007080005080700030e040106010009000100000a020300020f0404000410060000011106080106031209030106040705070105010802020c08020001030305080207080101060c010800010b0301090002070b030109000900076d657373616765076163636f756e74056572726f72056576656e74067369676e657206737472696e67124d6573736167654368616e67654576656e740d4d657373616765486f6c64657206537472696e670b6765745f6d6573736167650b7365745f6d6573736167650c66726f6d5f6d6573736167650a746f5f6d657373616765156d6573736167655f6368616e67655f6576656e74730b4576656e7448616e646c65096e6f745f666f756e640a616464726573735f6f66106e65775f6576656e745f68616e646c650a656d69745f6576656e746766284c3984add58e00d20ba272a40d33d5b4ea33c08a904254e28fdff97b9f000000000000000000000000000000000000000000000000000000000000000103080000000000000000126170746f733a3a6d657461646174615f7630310100000000000000000b454e4f5f4d4553534147451b5468657265206973206e6f206d6573736167652070726573656e740002020b08020c08020102020008020d0b030108000001000101030b0a002901030607001102270b002b0110001402010104010105210e0011030c020a022901200308050f0e000b010e00380012012d0105200b022a010c040a041000140c030a040f010b030a01120038010b010b040f0015020100010100",
).toUint8Array(),
),
],
);
await client.waitForTransaction(txnHash);
const txn = await client.getTransactionByHash(txnHash);
expect((txn as any).success).toBeTruthy();
},
longTestTimeout,
);
test(
"rotates auth key ed25519",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const alice = new AptosAccount();
await faucetClient.fundAccount(alice.address(), 100_000_000);
const helperAccount = new AptosAccount();
const pendingTxn = await client.rotateAuthKeyEd25519(alice, helperAccount.signingKey.secretKey);
await client.waitForTransaction(pendingTxn.hash);
const origAddressHex = await client.lookupOriginalAddress(helperAccount.address());
// Sometimes the returned addresses do not have leading 0s. To be safe, converting hex addresses to AccountAddress
const origAddress = TxnBuilderTypes.AccountAddress.fromHex(origAddressHex);
const aliceAddress = TxnBuilderTypes.AccountAddress.fromHex(alice.address());
expect(HexString.fromUint8Array(bcsToBytes(origAddress)).hex()).toBe(
HexString.fromUint8Array(bcsToBytes(aliceAddress)).hex(),
);
},
longTestTimeout,
);
test(
"gets block by height",
async () => {
const blockHeight = 100;
const client = new AptosClient(NODE_URL);
const block = await client.getBlockByHeight(blockHeight);
expect(block.block_height).toBe(blockHeight.toString());
},
longTestTimeout,
);
test(
"gets block by version",
async () => {
const version = 100;
const client = new AptosClient(NODE_URL);
const block = await client.getBlockByVersion(version);
expect(parseInt(block.first_version, 10)).toBeLessThanOrEqual(version);
expect(parseInt(block.last_version, 10)).toBeGreaterThanOrEqual(version);
},
longTestTimeout,
);
test(
"estimates max gas amount",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const alice = new AptosAccount();
await faucetClient.fundAccount(alice.address(), 10000000);
const maxGasAmount = await client.estimateMaxGasAmount(alice.address());
expect(maxGasAmount).toBeGreaterThan(BigInt(0));
},
longTestTimeout,
);
test(
"view function",
async () => {
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const alice = new AptosAccount();
await faucetClient.fundAccount(alice.address(), 100_000_000);
const payload: Gen.ViewRequest = {
function: "0x1::coin::balance",
type_arguments: ["0x1::aptos_coin::AptosCoin"],
arguments: [alice.address().hex()],
};
const balance = await client.view(payload);
expect(balance[0]).toBe("100000000");
},
longTestTimeout,
);
test(
"view function with a struct return type",
async () => {
// This test is just to show that the view function supports a struct return type.
// We test against get_collection_mutability_config although
// b/c at the time of writing this is the only view function on the move side
// that can easily test a struct return type.
const client = new AptosClient(NODE_URL);
const faucetClient = getFaucetClient();
const tokenClient = new TokenClient(client);
const alice = new AptosAccount();
// Fund Alice's Account
await faucetClient.fundAccount(alice.address(), 100000000);
const collectionName = "AliceCollection";
// Create collection on Alice's account
await client.waitForTransaction(
await tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"),
{ checkSuccess: true },
);
const payload: Gen.ViewRequest = {
function: "0x3::token::get_collection_mutability_config",
type_arguments: [],
arguments: [alice.address().hex(), collectionName],
};
const collection = await client.view(payload);
expect(collection[0]).toMatchObject({ description: false, maximum: false, uri: false });
},
longTestTimeout,
);