diff --git a/examples/typescript/mint_nft.ts b/examples/typescript/mint_nft.ts new file mode 100644 index 000000000..af98b6d87 --- /dev/null +++ b/examples/typescript/mint_nft.ts @@ -0,0 +1,106 @@ +/** + * This example shows how to use the Aptos client to mint a NFT. + */ + +import { Account, Aptos, AptosConfig, Network } from "aptos"; + +const ALICE_INITIAL_BALANCE = 100_000_000; + +/** + * Prints the balance of an account + * @param aptos + * @param name + * @param address + * @returns {Promise<*>} + * + */ +const accountTokens = async (aptos: Aptos, name: string, accountAddress: string) => { + let tokens = await aptos.getOwnedTokens({ ownerAddress: accountAddress }); + + if (tokens.length === 0) { + console.log(`\n${name} has no tokens.\n`); + return; + } + + console.log(`\n${name}'s tokens:`); + for (let index = 0; index < tokens.length; index++) { + const token = tokens[index]; + console.log( + `*${token.current_token_data.token_name}* in the *${token.current_token_data.current_collection.collection_name}* collection`, + ); + } +}; + +const example = async () => { + console.log( + "This example will create and fund an account (Alice), then the account will create a collection and a token in that collection.", + ); + + // Setup the client + const config = new AptosConfig({ network: Network.DEVNET }); + const aptos = new Aptos(config); + + // Create the account + let alice = Account.generate(); + + console.log("=== Addresses ===\n"); + console.log(`Alice's address is: ${alice.accountAddress.toString()}`); + + // Fund the accounts + console.log("\n=== Funding accounts ===\n"); + + const aliceFundTxn = await aptos.faucet.fundAccount({ + accountAddress: alice.accountAddress.toUint8Array(), + amount: ALICE_INITIAL_BALANCE, + }); + console.log("Alice's fund transaction: ", aliceFundTxn); + + const collectionName = "Example Collection"; + const collectionDescription = "Example description."; + const collectionURI = "aptos.dev"; + + // Create the collection + let transaction = await aptos.createCollectionTransaction({ + creator: alice, + description: collectionDescription, + name: collectionName, + uri: collectionURI, + }); + + console.log("\n=== Create the collection ===\n"); + let committedTxn = await aptos.signAndSubmitTransaction({ signer: alice, transaction }); + + await aptos.waitForTransaction({ transactionHash: committedTxn.hash }); + console.log(`Committed transaction: ${committedTxn.hash}`); + + console.log(`Created collection:`); + let exampleCollection = await aptos.getCollectionData({ + collectionName, + creatorAddress: alice.accountAddress.toString(), + }); + console.log(exampleCollection); + + await accountTokens(aptos, "Alice", alice.accountAddress.toString()); + + const tokenName = "Example Token"; + const tokenDescription = "Example token description."; + const tokenURI = "aptos.dev/token"; + + // Mint the token + transaction = await aptos.mintTokenTransaction({ + creator: alice, + collection: collectionName, + description: tokenDescription, + name: tokenName, + uri: tokenURI, + }); + + console.log("\n=== Mint the token ===\n"); + committedTxn = await aptos.signAndSubmitTransaction({ signer: alice, transaction }); + await aptos.waitForTransaction({ transactionHash: committedTxn.hash }); + console.log(`Committed transaction: ${committedTxn.hash}`); + + await accountTokens(aptos, "Alice", alice.accountAddress.toString()); +}; + +example(); diff --git a/examples/typescript/package.json b/examples/typescript/package.json index 7df7ddaea..7d3c61c5e 100644 --- a/examples/typescript/package.json +++ b/examples/typescript/package.json @@ -6,6 +6,7 @@ "scripts": { "multi_agent_transfer": "ts-node multi_agent_transfer.ts", "simple_transfer": "ts-node simple_transfer.ts", + "mint_nft": "ts-node mint_nft.ts", "simple_sponsored_transaction": "ts-node simple_sponsored_transaction.ts", "transfer_coin": "ts-node transfer_coin.ts" }, diff --git a/src/api/token.ts b/src/api/token.ts index 7bd6d67f8..d94bdeda7 100644 --- a/src/api/token.ts +++ b/src/api/token.ts @@ -2,8 +2,24 @@ // SPDX-License-Identifier: Apache-2.0 import { AptosConfig } from "./aptosConfig"; -import { getTokenData } from "../internal/token"; -import { GetTokenDataResponse, HexInput } from "../types"; +import { + getCurrentTokenOwnership, + getOwnedTokens, + getTokenActivity, + getTokenData, + mintTokenTransaction, +} from "../internal/token"; +import { + GetCurrentTokenOwnershipResponse, + GetOwnedTokensResponse, + GetTokenActivityResponse, + GetTokenDataResponse, + HexInput, + OrderBy, + PaginationArgs, +} from "../types"; +import { Account } from "../core"; +import { GenerateTransactionOptions, SingleSignerTransaction } from "../transactions/types"; /** * A class to query all `Token` related queries on Aptos. @@ -16,7 +32,29 @@ export class Token { } /** - * This gets token data given the address of a token. + * Create a transaction to mint a token into the creators account within an existing collection. + * + * @param args.creator the creator of the collection + * @param args.collection the name of the collection the token belongs to + * @param args.description the description of the token + * @param args.name the name of the token + * @param args.uri the URI to additional info about the token + * + * @returns A SingleSignerTransaction that can be simulated or submitted to chain + */ + async mintTokenTransaction(args: { + creator: Account; + collection: string; + description: string; + name: string; + uri: string; + options?: GenerateTransactionOptions; + }): Promise { + return mintTokenTransaction({ aptosConfig: this.config, ...args }); + } + + /** + * Gets token data given the address of a token. * * @param args.tokenAddress The address of the token * @returns GetTokenDataResponse containing relevant data to the token. @@ -24,4 +62,46 @@ export class Token { async getTokenData(args: { tokenAddress: HexInput }): Promise { return getTokenData({ aptosConfig: this.config, ...args }); } + + /** + * Gets token ownership data given the address of a token. + * + * @param args.tokenAddress The address of the token + * @returns GetCurrentTokenOwnershipResponse containing relevant ownership data of the token. + */ + async getCurrentTokenOwnership(args: { tokenAddress: HexInput }): Promise { + return getCurrentTokenOwnership({ aptosConfig: this.config, ...args }); + } + + /** + * Gets the tokens that the given address owns. + * + * @param args.ownerAddress The address of the owner + * @returns GetOwnedTokensResponse containing ownership data of the tokens belonging to the ownerAddresss. + */ + async getOwnedTokens(args: { + ownerAddress: HexInput; + options?: { + pagination?: PaginationArgs; + orderBy?: OrderBy; + }; + }): Promise { + return getOwnedTokens({ aptosConfig: this.config, ...args }); + } + + /** + * Gets the activity data given the address of a token. + * + * @param args.tokenAddress The address of the token + * @returns GetTokenActivityResponse containing relevant activity data to the token. + */ + async getTokenActivity(args: { + tokenAddress: HexInput; + options?: { + pagination?: PaginationArgs; + orderBy?: OrderBy; + }; + }): Promise { + return getTokenActivity({ aptosConfig: this.config, ...args }); + } } diff --git a/src/internal/queries/TokenActivitiesFieldsFragment.graphql b/src/internal/queries/TokenActivitiesFieldsFragment.graphql new file mode 100644 index 000000000..5cda63134 --- /dev/null +++ b/src/internal/queries/TokenActivitiesFieldsFragment.graphql @@ -0,0 +1,17 @@ +fragment TokenActivitiesFields on token_activities_v2 { + after_value + before_value + entry_function_id_str + event_account_address + event_index + from_address + is_fungible_v2 + property_version_v1 + to_address + token_amount + token_data_id + token_standard + transaction_timestamp + transaction_version + type +} diff --git a/src/internal/queries/getTokenActivity.graphql b/src/internal/queries/getTokenActivity.graphql new file mode 100644 index 000000000..0501300c8 --- /dev/null +++ b/src/internal/queries/getTokenActivity.graphql @@ -0,0 +1,11 @@ +#import "./TokenActivitiesFieldsFragment"; +query getTokenActivity( + $where_condition: token_activities_v2_bool_exp! + $offset: Int + $limit: Int + $order_by: [token_activities_v2_order_by!] +) { + token_activities_v2(where: $where_condition, order_by: $order_by, offset: $offset, limit: $limit) { + ...TokenActivitiesFields + } +} diff --git a/src/internal/queries/getTokenCurrentOwner.graphql b/src/internal/queries/getTokenCurrentOwner.graphql new file mode 100644 index 000000000..c3b8d8495 --- /dev/null +++ b/src/internal/queries/getTokenCurrentOwner.graphql @@ -0,0 +1,11 @@ +#import "./CurrentTokenOwnershipFieldsFragment"; +query getCurrentTokenOwnership( + $where_condition: current_token_ownerships_v2_bool_exp! + $offset: Int + $limit: Int + $order_by: [current_token_ownerships_v2_order_by!] +) { + current_token_ownerships_v2(where: $where_condition, offset: $offset, limit: $limit, order_by: $order_by) { + ...CurrentTokenOwnershipFields + } +} diff --git a/src/internal/token.ts b/src/internal/token.ts index c8b8a3ec5..5f7f8b5af 100644 --- a/src/internal/token.ts +++ b/src/internal/token.ts @@ -9,11 +9,60 @@ */ import { AptosConfig } from "../api/aptosConfig"; -import { Hex } from "../core"; -import { GetTokenDataResponse, HexInput } from "../types"; -import { GetTokenDataQuery } from "../types/generated/operations"; -import { GetTokenData } from "../types/generated/queries"; +import { MoveString, MoveVector, U8 } from "../bcs"; +import { Account, Hex } from "../core"; +import { GenerateTransactionOptions, SingleSignerTransaction } from "../transactions/types"; +import { + GetCurrentTokenOwnershipResponse, + GetOwnedTokensResponse, + GetTokenActivityResponse, + GetTokenDataResponse, + HexInput, + OrderBy, + PaginationArgs, +} from "../types"; +import { GetCurrentTokenOwnershipQuery, GetTokenActivityQuery, GetTokenDataQuery } from "../types/generated/operations"; +import { GetCurrentTokenOwnership, GetTokenActivity, GetTokenData } from "../types/generated/queries"; +import { CurrentTokenOwnershipsV2BoolExp, TokenActivitiesV2BoolExp } from "../types/generated/types"; import { queryIndexer } from "./general"; +import { generateTransaction } from "./transactionSubmission"; + +// TODO: Support properties when minting. +export interface MintTokenOptions { + propertyKeys?: Array; + propertyTypes?: Array; + propertyValues?: Array; +} + +export async function mintTokenTransaction(args: { + aptosConfig: AptosConfig; + creator: Account; + collection: string; + description: string; + name: string; + uri: string; + options?: GenerateTransactionOptions; +}): Promise { + const { aptosConfig, options, creator } = args; + const transaction = await generateTransaction({ + aptosConfig, + sender: creator.accountAddress.toString(), + data: { + function: "0x4::aptos_token::mint", + arguments: [ + new MoveString(args.collection), + new MoveString(args.description), + new MoveString(args.name), + new MoveString(args.uri), + MoveVector.MoveString([]), + MoveVector.MoveString([]), + new MoveVector>([]), + ], + }, + options, + }); + return transaction as SingleSignerTransaction; +} export async function getTokenData(args: { aptosConfig: AptosConfig; @@ -40,3 +89,95 @@ export async function getTokenData(args: { return data.current_token_datas_v2[0]; } + +export async function getCurrentTokenOwnership(args: { + aptosConfig: AptosConfig; + tokenAddress: HexInput; +}): Promise { + const { aptosConfig, tokenAddress } = args; + + const whereCondition: CurrentTokenOwnershipsV2BoolExp = { + token_data_id: { _eq: Hex.fromHexInput(tokenAddress).toString() }, + }; + + const graphqlQuery = { + query: GetCurrentTokenOwnership, + variables: { + where_condition: whereCondition, + }, + }; + + const data = await queryIndexer({ + aptosConfig, + query: graphqlQuery, + originMethod: "getCurrentTokenOwnership", + }); + + return data.current_token_ownerships_v2[0]; +} + +export async function getOwnedTokens(args: { + aptosConfig: AptosConfig; + ownerAddress: HexInput; + options?: { + pagination?: PaginationArgs; + orderBy?: OrderBy; + }; +}): Promise { + const { aptosConfig, ownerAddress, options } = args; + + const whereCondition: CurrentTokenOwnershipsV2BoolExp = { + owner_address: { _eq: Hex.fromHexInput(ownerAddress).toString() }, + }; + + const graphqlQuery = { + query: GetCurrentTokenOwnership, + variables: { + where_condition: whereCondition, + offset: options?.pagination?.offset, + limit: options?.pagination?.limit, + order_by: options?.orderBy, + }, + }; + + const data = await queryIndexer({ + aptosConfig, + query: graphqlQuery, + originMethod: "getOwnedTokens", + }); + + return data.current_token_ownerships_v2; +} + +export async function getTokenActivity(args: { + aptosConfig: AptosConfig; + tokenAddress: HexInput; + options?: { + pagination?: PaginationArgs; + orderBy?: OrderBy; + }; +}): Promise { + const { aptosConfig, tokenAddress, options } = args; + + const whereCondition: TokenActivitiesV2BoolExp = { + token_data_id: { _eq: Hex.fromHexInput(tokenAddress).toString() }, + }; + + const graphqlQuery = { + query: GetTokenActivity, + variables: { + where_condition: whereCondition, + offset: options?.pagination?.offset, + limit: options?.pagination?.limit, + order_by: options?.orderBy, + }, + }; + + const data = await queryIndexer({ + aptosConfig, + query: graphqlQuery, + originMethod: "getTokenActivity", + }); + + return data.token_activities_v2; +} diff --git a/src/types/generated/operations.ts b/src/types/generated/operations.ts index 49678cddd..9ee9aee0f 100644 --- a/src/types/generated/operations.ts +++ b/src/types/generated/operations.ts @@ -46,6 +46,24 @@ export type CurrentTokenOwnershipFieldsFragment = { } | null; }; +export type TokenActivitiesFieldsFragment = { + after_value?: string | null; + before_value?: string | null; + entry_function_id_str?: string | null; + event_account_address: string; + event_index: any; + from_address?: string | null; + is_fungible_v2?: boolean | null; + property_version_v1: any; + to_address?: string | null; + token_amount: any; + token_data_id: string; + token_standard: string; + transaction_timestamp: any; + transaction_version: any; + type: string; +}; + export type GetAccountCoinsCountQueryVariables = Types.Exact<{ address?: Types.InputMaybe; }>; @@ -481,6 +499,88 @@ export type GetProcessorStatusQuery = { processor_status: Array<{ last_success_version: any; processor: string; last_updated: any }>; }; +export type GetTokenActivityQueryVariables = Types.Exact<{ + where_condition: Types.TokenActivitiesV2BoolExp; + offset?: Types.InputMaybe; + limit?: Types.InputMaybe; + order_by?: Types.InputMaybe | Types.TokenActivitiesV2OrderBy>; +}>; + +export type GetTokenActivityQuery = { + token_activities_v2: Array<{ + after_value?: string | null; + before_value?: string | null; + entry_function_id_str?: string | null; + event_account_address: string; + event_index: any; + from_address?: string | null; + is_fungible_v2?: boolean | null; + property_version_v1: any; + to_address?: string | null; + token_amount: any; + token_data_id: string; + token_standard: string; + transaction_timestamp: any; + transaction_version: any; + type: string; + }>; +}; + +export type GetCurrentTokenOwnershipQueryVariables = Types.Exact<{ + where_condition: Types.CurrentTokenOwnershipsV2BoolExp; + offset?: Types.InputMaybe; + limit?: Types.InputMaybe; + order_by?: Types.InputMaybe | Types.CurrentTokenOwnershipsV2OrderBy>; +}>; + +export type GetCurrentTokenOwnershipQuery = { + current_token_ownerships_v2: Array<{ + token_standard: string; + token_properties_mutated_v1?: any | null; + token_data_id: string; + table_type_v1?: string | null; + storage_id: string; + property_version_v1: any; + owner_address: string; + last_transaction_version: any; + last_transaction_timestamp: any; + is_soulbound_v2?: boolean | null; + is_fungible_v2?: boolean | null; + amount: any; + current_token_data?: { + collection_id: string; + description: string; + is_fungible_v2?: boolean | null; + largest_property_version_v1?: any | null; + last_transaction_timestamp: any; + last_transaction_version: any; + maximum?: any | null; + supply: any; + token_data_id: string; + token_name: string; + token_properties: any; + token_standard: string; + token_uri: string; + current_collection?: { + collection_id: string; + collection_name: string; + creator_address: string; + current_supply: any; + description: string; + last_transaction_timestamp: any; + last_transaction_version: any; + max_supply?: any | null; + mutable_description?: boolean | null; + mutable_uri?: boolean | null; + table_handle_v1?: string | null; + token_standard: string; + total_minted_v2?: any | null; + uri: string; + } | null; + } | null; + }>; +}; + export type GetTokenDataQueryVariables = Types.Exact<{ where_condition?: Types.InputMaybe; offset?: Types.InputMaybe; diff --git a/src/types/generated/queries.ts b/src/types/generated/queries.ts index 8c01621c2..d8799f0f3 100644 --- a/src/types/generated/queries.ts +++ b/src/types/generated/queries.ts @@ -49,6 +49,25 @@ export const CurrentTokenOwnershipFieldsFragmentDoc = ` } } `; +export const TokenActivitiesFieldsFragmentDoc = ` + fragment TokenActivitiesFields on token_activities_v2 { + after_value + before_value + entry_function_id_str + event_account_address + event_index + from_address + is_fungible_v2 + property_version_v1 + to_address + token_amount + token_data_id + token_standard + transaction_timestamp + transaction_version + type +} + `; export const GetAccountCoinsCount = ` query getAccountCoinsCount($address: String) { current_fungible_asset_balances_aggregate( @@ -345,6 +364,30 @@ export const GetProcessorStatus = ` } } `; +export const GetTokenActivity = ` + query getTokenActivity($where_condition: token_activities_v2_bool_exp!, $offset: Int, $limit: Int, $order_by: [token_activities_v2_order_by!]) { + token_activities_v2( + where: $where_condition + order_by: $order_by + offset: $offset + limit: $limit + ) { + ...TokenActivitiesFields + } +} + ${TokenActivitiesFieldsFragmentDoc}`; +export const GetCurrentTokenOwnership = ` + query getCurrentTokenOwnership($where_condition: current_token_ownerships_v2_bool_exp!, $offset: Int, $limit: Int, $order_by: [current_token_ownerships_v2_order_by!]) { + current_token_ownerships_v2( + where: $where_condition + offset: $offset + limit: $limit + order_by: $order_by + ) { + ...CurrentTokenOwnershipFields + } +} + ${CurrentTokenOwnershipFieldsFragmentDoc}`; export const GetTokenData = ` query getTokenData($where_condition: current_token_datas_v2_bool_exp, $offset: Int, $limit: Int, $order_by: [current_token_datas_v2_order_by!]) { current_token_datas_v2( @@ -647,6 +690,34 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = "query", ); }, + getTokenActivity( + variables: Types.GetTokenActivityQueryVariables, + requestHeaders?: Dom.RequestInit["headers"], + ): Promise { + return withWrapper( + (wrappedRequestHeaders) => + client.request(GetTokenActivity, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + "getTokenActivity", + "query", + ); + }, + getCurrentTokenOwnership( + variables: Types.GetCurrentTokenOwnershipQueryVariables, + requestHeaders?: Dom.RequestInit["headers"], + ): Promise { + return withWrapper( + (wrappedRequestHeaders) => + client.request(GetCurrentTokenOwnership, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + "getCurrentTokenOwnership", + "query", + ); + }, getTokenData( variables?: Types.GetTokenDataQueryVariables, requestHeaders?: Dom.RequestInit["headers"], diff --git a/src/types/indexer.ts b/src/types/indexer.ts index d49a7212f..7ad371245 100644 --- a/src/types/indexer.ts +++ b/src/types/indexer.ts @@ -27,6 +27,8 @@ import { GetFungibleAssetMetadataQuery, GetFungibleAssetActivitiesQuery, GetCurrentFungibleAssetBalancesQuery, + GetTokenActivityQuery, + GetCurrentTokenOwnershipQuery, } from "./generated/operations"; /** @@ -60,6 +62,9 @@ export type GetFungibleAssetMetadataResponse = GetFungibleAssetMetadataQuery["fu export type GetFungibleAssetActivitiesResponse = GetFungibleAssetActivitiesQuery["fungible_asset_activities"]; export type GetCurrentFungibleAssetBalancesResponse = GetCurrentFungibleAssetBalancesQuery["current_fungible_asset_balances"]; +export type GetTokenActivityResponse = GetTokenActivityQuery["token_activities_v2"]; +export type GetCurrentTokenOwnershipResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"][0]; +export type GetOwnedTokensResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"]; /** * A generic type that being passed by each function and holds an diff --git a/tests/e2e/api/token.test.ts b/tests/e2e/api/token.test.ts index 353d2e82e..30abe2ba3 100644 --- a/tests/e2e/api/token.test.ts +++ b/tests/e2e/api/token.test.ts @@ -1,20 +1,99 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -// import { AptosConfig, Aptos } from "../../../src"; -// import { Network } from "../../../src/utils/apiEndpoints"; +import { AptosConfig, Aptos, Account } from "../../../src"; +import { waitForTransaction } from "../../../src/internal/transaction"; +import { Network } from "../../../src/utils/apiEndpoints"; +import { FUND_AMOUNT } from "../../unit/helper"; + +const config = new AptosConfig({ network: Network.LOCAL }); +const aptos = new Aptos(config); + +const collectionName = "Test Collection"; +const collectionDescription = "My new collection!"; +const collectionUri = "http://aptos.dev"; + +const tokenName = "Test Token"; +const tokenDescription = "my first nft"; +const tokenUri = "http://aptos.dev/nft"; + +const creator = Account.generate(); +const creatorAddress = creator.accountAddress.toString(); + +async function setupCollection() { + await aptos.fundAccount({ accountAddress: creator.accountAddress.toString(), amount: FUND_AMOUNT }); + const transaction = await aptos.createCollectionTransaction({ + creator, + description: collectionDescription, + name: collectionName, + uri: collectionUri, + }); + const response = await aptos.signAndSubmitTransaction({ signer: creator, transaction }); + await waitForTransaction({ aptosConfig: config, transactionHash: response.hash }); +} + +async function setupToken(): Promise { + const transaction = await aptos.mintTokenTransaction({ + creator, + collection: collectionName, + description: tokenDescription, + name: tokenName, + uri: tokenUri, + }); + const response = await aptos.signAndSubmitTransaction({ signer: creator, transaction }); + await waitForTransaction({ aptosConfig: config, transactionHash: response.hash }); + return ( + await aptos.getOwnedTokens({ + ownerAddress: creator.accountAddress.toString(), + }) + )[0].current_token_data?.token_data_id!; +} describe("token api", () => { + let tokenAddress: string; + + beforeAll(async () => { + await setupCollection(); + tokenAddress = await setupToken(); + }); + test("it gets token data for a token's address", async () => { - // const config = new AptosConfig({ network: Network.MAINNET }); - // const aptos = new Aptos(config); - // const tokenAddress = "0x0cb098d8f875f38dcb4109e2638e3e24055a585ed2143e9ba76e002fea303795"; - // const tokenData = await aptos.getTokenData({ tokenAddress }); - // expect(tokenData).toHaveProperty("description") - // expect(tokenData).toHaveProperty("current_collection") - // expect(tokenData).toHaveProperty("token_data_id") - // expect(tokenData.current_collection).toHaveProperty("collection_id") - // expect(tokenData.current_collection).toHaveProperty("collection_name") - // expect(tokenData.current_collection).toHaveProperty("creator_address") + const tokenData = await aptos.getTokenData({ tokenAddress }); + + expect(tokenData.token_data_id).toEqual(tokenAddress); + expect(tokenData.description).toEqual(tokenDescription); + expect(tokenData.token_name).toEqual(tokenName); + expect(tokenData.token_data_id).toEqual(tokenAddress); + expect(tokenData.current_collection?.collection_name).toEqual(collectionName); + expect(tokenData.current_collection?.creator_address).toEqual(creatorAddress); + }); + + test("it gets an owner's tokens", async () => { + const tokenData = (await aptos.getOwnedTokens({ ownerAddress: creatorAddress }))[0]; + + expect(tokenData.token_data_id).toEqual(tokenAddress); + expect(tokenData.owner_address).toEqual(creatorAddress); + expect(tokenData.current_token_data?.description).toEqual(tokenDescription); + expect(tokenData.current_token_data?.token_name).toEqual(tokenName); + expect(tokenData.current_token_data?.token_uri).toEqual(tokenUri); + }); + + test("it gets ownership data given a token's address", async () => { + const tokenOwnershipData = await aptos.getCurrentTokenOwnership({ tokenAddress }); + + expect(tokenOwnershipData.token_data_id).toEqual(tokenAddress); + expect(tokenOwnershipData.owner_address).toEqual(creatorAddress); + expect(tokenOwnershipData.current_token_data?.description).toEqual(tokenDescription); + expect(tokenOwnershipData.current_token_data?.token_name).toEqual(tokenName); + expect(tokenOwnershipData.current_token_data?.token_uri).toEqual(tokenUri); + }); + + test("it gets activity data given a token's address", async () => { + const tokenActivityData = await aptos.getTokenActivity({ tokenAddress }); + + expect(tokenActivityData[0].entry_function_id_str).toEqual("0x4::aptos_token::mint"); + expect(tokenActivityData[0].token_data_id).toEqual(tokenAddress); + expect(tokenActivityData[0].from_address).toEqual(creatorAddress); + expect(tokenActivityData[0].is_fungible_v2).toEqual(false); }); });