diff --git a/CHANGELOG.md b/CHANGELOG.md index c442046cb..2fe97de84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ All notable changes to the Aptos TypeScript SDK will be captured in this file. T - Separates the signing message functionality out of the transactionSubmission.ts file - Adds an Account implementation for MultiKey accounts - Upgrade `@aptos-labs/aptos-cli` package to version `0.1.7` +- Introduce `table` function APIs +- Add `getTableItemsData` and `getTableItemsMetadata` API queries +- Add `decimal` prop back to `current_token_ownerships_v2.current_token_data` response # 1.14.0 (2024-05-09) diff --git a/src/api/aptos.ts b/src/api/aptos.ts index 95714f303..b03d145ba 100644 --- a/src/api/aptos.ts +++ b/src/api/aptos.ts @@ -12,6 +12,7 @@ import { General } from "./general"; import { ANS } from "./ans"; import { Staking } from "./staking"; import { Transaction } from "./transaction"; +import { Table } from "./table"; /** * This class is the main entry point into Aptos's @@ -47,6 +48,8 @@ export class Aptos { readonly transaction: Transaction; + readonly table: Table; + constructor(settings?: AptosConfig) { this.config = new AptosConfig(settings); this.account = new Account(this.config); @@ -59,6 +62,7 @@ export class Aptos { this.general = new General(this.config); this.staking = new Staking(this.config); this.transaction = new Transaction(this.config); + this.table = new Table(this.config); } } @@ -74,6 +78,7 @@ export interface Aptos FungibleAsset, General, Staking, + Table, Omit {} /** @@ -107,3 +112,4 @@ applyMixin(Aptos, FungibleAsset, "fungibleAsset"); applyMixin(Aptos, General, "general"); applyMixin(Aptos, Staking, "staking"); applyMixin(Aptos, Transaction, "transaction"); +applyMixin(Aptos, Table, "table"); diff --git a/src/api/general.ts b/src/api/general.ts index b870beca5..b2ac7a9b0 100644 --- a/src/api/general.ts +++ b/src/api/general.ts @@ -9,7 +9,6 @@ import { getIndexerLastSuccessVersion, getLedgerInfo, getProcessorStatus, - getTableItem, queryIndexer, } from "../internal/general"; import { view } from "../internal/view"; @@ -22,7 +21,6 @@ import { LedgerInfo, LedgerVersionArg, MoveValue, - TableItemRequest, } from "../types"; import { ProcessorType } from "../utils/const"; import { InputViewFunctionData } from "../transactions"; @@ -112,30 +110,6 @@ export class General { return getBlockByHeight({ aptosConfig: this.config, ...args }); } - /** - * Queries for a table item for a table identified by the handle and the key for the item. - * Key and value types need to be passed in to help with key serialization and value deserialization. - * - * @example https://api.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::coin::CoinInfo%3C0x1::aptos_coin::AptosCoin%3E - * const tableItem = await aptos.getTableItem({ - * handle: "0x123", - * data: { - * key_type: "address", // Move type of table key - * value_type: "u128", // Move type of table value - * key: "0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935" // Value of table key - * }, - * }) - * - * @param args.handle A pointer to where that table is stored - * @param args.data Object that describes table item - * @param args.options.ledgerVersion The ledger version to query, if not provided it will get the latest version - * - * @returns Table item value rendered in JSON - */ - async getTableItem(args: { handle: string; data: TableItemRequest; options?: LedgerVersionArg }): Promise { - return getTableItem({ aptosConfig: this.config, ...args }); - } - /** * Queries for a Move view function * @param args.payload Payload for the view function diff --git a/src/api/table.ts b/src/api/table.ts new file mode 100644 index 000000000..176ff0ea3 --- /dev/null +++ b/src/api/table.ts @@ -0,0 +1,108 @@ +import { getTableItem, getTableItemsData, getTableItemsMetadata } from "../internal/table"; +import { + TableItemRequest, + LedgerVersionArg, + AnyNumber, + PaginationArgs, + WhereArg, + OrderByArg, + GetTableItemsDataResponse, + GetTableItemsMetadataResponse, +} from "../types"; +import { TableItemsBoolExp, TableMetadatasBoolExp } from "../types/generated/types"; +import { ProcessorType } from "../utils"; +import { AptosConfig } from "./aptosConfig"; +import { waitForIndexerOnVersion } from "./utils"; + +/** + * A class to query all `Table` Aptos related queries + */ +export class Table { + readonly config: AptosConfig; + + constructor(config: AptosConfig) { + this.config = config; + } + + /** + * Queries for a table item for a table identified by the handle and the key for the item. + * Key and value types need to be passed in to help with key serialization and value deserialization. + * + * Note, this query calls the fullnode server + * + * @example https://api.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::coin::CoinInfo%3C0x1::aptos_coin::AptosCoin%3E + * const tableItem = await aptos.getTableItem({ + * handle: "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + * data: { + * key_type: "address", // Move type of table key + * value_type: "u128", // Move type of table value + * key: "0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935" // Value of table key + * }, + * }) + * + * @param args.handle A pointer to where that table is stored + * @param args.data Object that describes table item + * @param args.options.ledgerVersion The ledger version to query, if not provided it will get the latest version + * + * @returns Table item value rendered in JSON + */ + async getTableItem(args: { handle: string; data: TableItemRequest; options?: LedgerVersionArg }): Promise { + return getTableItem({ aptosConfig: this.config, ...args }); + } + + /** + * Queries for a table items data. + * + * Optional `options.where` param can be passed to filter the response. + * + * Note, this query calls the indexer server + * + * @example + * const data = await aptos.getTableItemsData({ + * options: { where: { + * table_handle: { _eq: "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca" }, + * transaction_version: { _eq: "0" } + * } + * }, + * }); + * + * @returns GetTableItemsDataResponse + */ + async getTableItemsData(args: { + minimumLedgerVersion?: AnyNumber; + options?: PaginationArgs & WhereArg & OrderByArg; + }): Promise { + await waitForIndexerOnVersion({ + config: this.config, + minimumLedgerVersion: args.minimumLedgerVersion, + processorType: ProcessorType.DEFAULT, + }); + return getTableItemsData({ aptosConfig: this.config, ...args }); + } + + /** + * Queries for a table items metadata. + * + * Optional `options.where` param can be passed to filter the response. + * + * Note, this query calls the indexer server + * + * @example + * const data = await aptos.getTableItemsMetadata({ + * options: { where: { handle: { _eq: "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca" } } }, + * }); + * + * @returns GetTableItemsMetadataResponse + */ + async getTableItemsMetadata(args: { + minimumLedgerVersion?: AnyNumber; + options?: PaginationArgs & WhereArg & OrderByArg; + }): Promise { + await waitForIndexerOnVersion({ + config: this.config, + minimumLedgerVersion: args.minimumLedgerVersion, + processorType: ProcessorType.DEFAULT, + }); + return getTableItemsMetadata({ aptosConfig: this.config, ...args }); + } +} diff --git a/src/internal/account.ts b/src/internal/account.ts index 32b6fdd21..32cae5b7c 100644 --- a/src/internal/account.ts +++ b/src/internal/account.ts @@ -13,7 +13,7 @@ import { AptosApiError, getAptosFullNode, paginateWithCursor } from "../client"; import { AccountAddress, AccountAddressInput } from "../core/accountAddress"; import { Account } from "../account"; import { AnyPublicKey, Ed25519PublicKey, PrivateKey } from "../core/crypto"; -import { getTableItem, queryIndexer } from "./general"; +import { queryIndexer } from "./general"; import { AccountData, GetAccountCoinsDataResponse, @@ -54,6 +54,7 @@ import { import { memoizeAsync } from "../utils/memoize"; import { Secp256k1PrivateKey, AuthenticationKey, Ed25519PrivateKey } from "../core"; import { CurrentFungibleAssetBalancesBoolExp } from "../types/generated/types"; +import { getTableItem } from "./table"; export async function getInfo(args: { aptosConfig: AptosConfig; diff --git a/src/internal/general.ts b/src/internal/general.ts index 673c4a377..7b00d6f0e 100644 --- a/src/internal/general.ts +++ b/src/internal/general.ts @@ -9,7 +9,7 @@ */ import { AptosConfig } from "../api/aptosConfig"; -import { getAptosFullNode, postAptosFullNode, postAptosIndexer } from "../client"; +import { getAptosFullNode, postAptosIndexer } from "../client"; import { AnyNumber, Block, @@ -17,8 +17,6 @@ import { GetProcessorStatusResponse, GraphqlQuery, LedgerInfo, - LedgerVersionArg, - TableItemRequest, } from "../types"; import { GetChainTopUserTransactionsQuery, GetProcessorStatusQuery } from "../types/generated/operations"; import { GetChainTopUserTransactions, GetProcessorStatus } from "../types/generated/queries"; @@ -64,23 +62,6 @@ export async function getBlockByHeight(args: { return data; } -export async function getTableItem(args: { - aptosConfig: AptosConfig; - handle: string; - data: TableItemRequest; - options?: LedgerVersionArg; -}): Promise { - const { aptosConfig, handle, data, options } = args; - const response = await postAptosFullNode({ - aptosConfig, - originMethod: "getTableItem", - path: `tables/${handle}/item`, - params: { ledger_version: options?.ledgerVersion }, - body: data, - }); - return response.data as T; -} - export async function getChainTopUserTransactions(args: { aptosConfig: AptosConfig; limit: number; diff --git a/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql b/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql index bdf67d360..fe5c746ce 100644 --- a/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql +++ b/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql @@ -25,6 +25,7 @@ fragment CurrentTokenOwnershipFields on current_token_ownerships_v2 { token_properties token_standard token_uri + decimals current_collection { collection_id collection_name diff --git a/src/internal/queries/getTableItemsData.graphql b/src/internal/queries/getTableItemsData.graphql new file mode 100644 index 000000000..48b678a26 --- /dev/null +++ b/src/internal/queries/getTableItemsData.graphql @@ -0,0 +1,15 @@ +query getTableItemsData( + $where_condition: table_items_bool_exp! + $offset: Int + $limit: Int + $order_by: [table_items_order_by!] +) { + table_items(where: $where_condition, offset: $offset, limit: $limit, order_by: $order_by){ + decoded_key + decoded_value + key + table_handle + transaction_version + write_set_change_index + } +} \ No newline at end of file diff --git a/src/internal/queries/getTableItemsMetadata.graphql b/src/internal/queries/getTableItemsMetadata.graphql new file mode 100644 index 000000000..03adfd5d2 --- /dev/null +++ b/src/internal/queries/getTableItemsMetadata.graphql @@ -0,0 +1,12 @@ +query getTableItemsMetadata( + $where_condition: table_metadatas_bool_exp! + $offset: Int + $limit: Int + $order_by: [table_metadatas_order_by!] +) { + table_metadatas(where: $where_condition, offset: $offset, limit: $limit, order_by: $order_by){ + handle + key_type + value_type + } +} \ No newline at end of file diff --git a/src/internal/table.ts b/src/internal/table.ts new file mode 100644 index 000000000..66bb52c88 --- /dev/null +++ b/src/internal/table.ts @@ -0,0 +1,82 @@ +import { AptosConfig } from "../api/aptosConfig"; +import { postAptosFullNode } from "../client"; +import { + TableItemRequest, + LedgerVersionArg, + PaginationArgs, + WhereArg, + OrderByArg, + GetTableItemsDataResponse, + GetTableItemsMetadataResponse, +} from "../types"; +import { GetTableItemsDataQuery, GetTableItemsMetadataQuery } from "../types/generated/operations"; +import { GetTableItemsData, GetTableItemsMetadata } from "../types/generated/queries"; +import { TableItemsBoolExp, TableMetadatasBoolExp } from "../types/generated/types"; +import { queryIndexer } from "./general"; + +export async function getTableItem(args: { + aptosConfig: AptosConfig; + handle: string; + data: TableItemRequest; + options?: LedgerVersionArg; +}): Promise { + const { aptosConfig, handle, data, options } = args; + const response = await postAptosFullNode({ + aptosConfig, + originMethod: "getTableItem", + path: `tables/${handle}/item`, + params: { ledger_version: options?.ledgerVersion }, + body: data, + }); + return response.data as T; +} + +export async function getTableItemsData(args: { + aptosConfig: AptosConfig; + options?: PaginationArgs & WhereArg & OrderByArg; +}) { + const { aptosConfig, options } = args; + + const graphqlQuery = { + query: GetTableItemsData, + variables: { + where_condition: options?.where, + offset: options?.offset, + limit: options?.limit, + order_by: options?.orderBy, + }, + }; + + const data = await queryIndexer({ + aptosConfig, + query: graphqlQuery, + originMethod: "getTableItemsData", + }); + + return data.table_items; +} + +export async function getTableItemsMetadata(args: { + aptosConfig: AptosConfig; + options?: PaginationArgs & WhereArg & OrderByArg; +}): Promise { + const { aptosConfig, options } = args; + + const graphqlQuery = { + query: GetTableItemsMetadata, + variables: { + where_condition: options?.where, + offset: options?.offset, + limit: options?.limit, + order_by: options?.orderBy, + }, + }; + + const data = await queryIndexer({ + aptosConfig, + query: graphqlQuery, + originMethod: "getTableItemsMetadata", + }); + + return data.table_metadatas; +} diff --git a/src/types/generated/operations.ts b/src/types/generated/operations.ts index d8b8f96ec..06fe19a0c 100644 --- a/src/types/generated/operations.ts +++ b/src/types/generated/operations.ts @@ -535,6 +535,35 @@ export type GetProcessorStatusQuery = { processor_status: Array<{ last_success_version: any; processor: string; last_updated: any }>; }; +export type GetTableItemsDataQueryVariables = Types.Exact<{ + where_condition: Types.TableItemsBoolExp; + offset?: Types.InputMaybe; + limit?: Types.InputMaybe; + order_by?: Types.InputMaybe | Types.TableItemsOrderBy>; +}>; + +export type GetTableItemsDataQuery = { + table_items: Array<{ + decoded_key: any; + decoded_value?: any | null; + key: string; + table_handle: string; + transaction_version: any; + write_set_change_index: any; + }>; +}; + +export type GetTableItemsMetadataQueryVariables = Types.Exact<{ + where_condition: Types.TableMetadatasBoolExp; + offset?: Types.InputMaybe; + limit?: Types.InputMaybe; + order_by?: Types.InputMaybe | Types.TableMetadatasOrderBy>; +}>; + +export type GetTableItemsMetadataQuery = { + table_metadatas: Array<{ handle: string; key_type: string; value_type: string }>; +}; + export type GetTokenActivityQueryVariables = Types.Exact<{ where_condition: Types.TokenActivitiesV2BoolExp; offset?: Types.InputMaybe; diff --git a/src/types/generated/queries.ts b/src/types/generated/queries.ts index eb5e18dd7..faa22b69d 100644 --- a/src/types/generated/queries.ts +++ b/src/types/generated/queries.ts @@ -389,6 +389,37 @@ export const GetProcessorStatus = ` } } `; +export const GetTableItemsData = ` + query getTableItemsData($where_condition: table_items_bool_exp!, $offset: Int, $limit: Int, $order_by: [table_items_order_by!]) { + table_items( + where: $where_condition + offset: $offset + limit: $limit + order_by: $order_by + ) { + decoded_key + decoded_value + key + table_handle + transaction_version + write_set_change_index + } +} + `; +export const GetTableItemsMetadata = ` + query getTableItemsMetadata($where_condition: table_metadatas_bool_exp!, $offset: Int, $limit: Int, $order_by: [table_metadatas_order_by!]) { + table_metadatas( + where: $where_condition + offset: $offset + limit: $limit + order_by: $order_by + ) { + handle + key_type + value_type + } +} + `; 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( @@ -727,6 +758,34 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = "query", ); }, + getTableItemsData( + variables: Types.GetTableItemsDataQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise { + return withWrapper( + (wrappedRequestHeaders) => + client.request(GetTableItemsData, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + "getTableItemsData", + "query", + ); + }, + getTableItemsMetadata( + variables: Types.GetTableItemsMetadataQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise { + return withWrapper( + (wrappedRequestHeaders) => + client.request(GetTableItemsMetadata, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + "getTableItemsMetadata", + "query", + ); + }, getTokenActivity( variables: Types.GetTokenActivityQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, diff --git a/src/types/generated/types.ts b/src/types/generated/types.ts index 872de886c..e993c46a9 100644 --- a/src/types/generated/types.ts +++ b/src/types/generated/types.ts @@ -98,6 +98,8 @@ export type AccountTransactions = { /** An aggregate relationship */ token_activities_v2_aggregate: TokenActivitiesV2Aggregate; transaction_version: Scalars["bigint"]["output"]; + /** An object relationship */ + user_transaction?: Maybe; }; /** columns and relationships of "account_transactions" */ @@ -219,6 +221,7 @@ export type AccountTransactionsBoolExp = { token_activities_v2?: InputMaybe; token_activities_v2_aggregate?: InputMaybe; transaction_version?: InputMaybe; + user_transaction?: InputMaybe; }; /** aggregate max on columns */ @@ -242,6 +245,7 @@ export type AccountTransactionsOrderBy = { token_activities_aggregate?: InputMaybe; token_activities_v2_aggregate?: InputMaybe; transaction_version?: InputMaybe; + user_transaction?: InputMaybe; }; /** select columns of table "account_transactions" */ @@ -1875,6 +1879,7 @@ export type CurrentAnsLookupV2StreamCursorValueInput = { /** columns and relationships of "current_aptos_names" */ export type CurrentAptosNames = { domain?: Maybe; + domain_expiration_timestamp?: Maybe; domain_with_suffix?: Maybe; expiration_timestamp?: Maybe; is_active?: Maybe; @@ -1885,6 +1890,7 @@ export type CurrentAptosNames = { owner_address?: Maybe; registered_address?: Maybe; subdomain?: Maybe; + subdomain_expiration_policy?: Maybe; token_name?: Maybe; token_standard?: Maybe; }; @@ -1961,11 +1967,13 @@ export type CurrentAptosNamesAggregateOrderBy = { /** aggregate avg on columns */ export type CurrentAptosNamesAvgFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by avg() on columns of table "current_aptos_names" */ export type CurrentAptosNamesAvgOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** Boolean expression to filter rows from the table "current_aptos_names". All fields are combined with a logical 'AND'. */ @@ -1974,6 +1982,7 @@ export type CurrentAptosNamesBoolExp = { _not?: InputMaybe; _or?: InputMaybe>; domain?: InputMaybe; + domain_expiration_timestamp?: InputMaybe; domain_with_suffix?: InputMaybe; expiration_timestamp?: InputMaybe; is_active?: InputMaybe; @@ -1983,6 +1992,7 @@ export type CurrentAptosNamesBoolExp = { owner_address?: InputMaybe; registered_address?: InputMaybe; subdomain?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; token_name?: InputMaybe; token_standard?: InputMaybe; }; @@ -1990,12 +2000,14 @@ export type CurrentAptosNamesBoolExp = { /** aggregate max on columns */ export type CurrentAptosNamesMaxFields = { domain?: Maybe; + domain_expiration_timestamp?: Maybe; domain_with_suffix?: Maybe; expiration_timestamp?: Maybe; last_transaction_version?: Maybe; owner_address?: Maybe; registered_address?: Maybe; subdomain?: Maybe; + subdomain_expiration_policy?: Maybe; token_name?: Maybe; token_standard?: Maybe; }; @@ -2003,12 +2015,14 @@ export type CurrentAptosNamesMaxFields = { /** order by max() on columns of table "current_aptos_names" */ export type CurrentAptosNamesMaxOrderBy = { domain?: InputMaybe; + domain_expiration_timestamp?: InputMaybe; domain_with_suffix?: InputMaybe; expiration_timestamp?: InputMaybe; last_transaction_version?: InputMaybe; owner_address?: InputMaybe; registered_address?: InputMaybe; subdomain?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; token_name?: InputMaybe; token_standard?: InputMaybe; }; @@ -2016,12 +2030,14 @@ export type CurrentAptosNamesMaxOrderBy = { /** aggregate min on columns */ export type CurrentAptosNamesMinFields = { domain?: Maybe; + domain_expiration_timestamp?: Maybe; domain_with_suffix?: Maybe; expiration_timestamp?: Maybe; last_transaction_version?: Maybe; owner_address?: Maybe; registered_address?: Maybe; subdomain?: Maybe; + subdomain_expiration_policy?: Maybe; token_name?: Maybe; token_standard?: Maybe; }; @@ -2029,12 +2045,14 @@ export type CurrentAptosNamesMinFields = { /** order by min() on columns of table "current_aptos_names" */ export type CurrentAptosNamesMinOrderBy = { domain?: InputMaybe; + domain_expiration_timestamp?: InputMaybe; domain_with_suffix?: InputMaybe; expiration_timestamp?: InputMaybe; last_transaction_version?: InputMaybe; owner_address?: InputMaybe; registered_address?: InputMaybe; subdomain?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; token_name?: InputMaybe; token_standard?: InputMaybe; }; @@ -2042,6 +2060,7 @@ export type CurrentAptosNamesMinOrderBy = { /** Ordering options when selecting data from "current_aptos_names". */ export type CurrentAptosNamesOrderBy = { domain?: InputMaybe; + domain_expiration_timestamp?: InputMaybe; domain_with_suffix?: InputMaybe; expiration_timestamp?: InputMaybe; is_active?: InputMaybe; @@ -2051,6 +2070,7 @@ export type CurrentAptosNamesOrderBy = { owner_address?: InputMaybe; registered_address?: InputMaybe; subdomain?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; token_name?: InputMaybe; token_standard?: InputMaybe; }; @@ -2060,6 +2080,8 @@ export enum CurrentAptosNamesSelectColumn { /** column name */ Domain = "domain", /** column name */ + DomainExpirationTimestamp = "domain_expiration_timestamp", + /** column name */ DomainWithSuffix = "domain_with_suffix", /** column name */ ExpirationTimestamp = "expiration_timestamp", @@ -2076,6 +2098,8 @@ export enum CurrentAptosNamesSelectColumn { /** column name */ Subdomain = "subdomain", /** column name */ + SubdomainExpirationPolicy = "subdomain_expiration_policy", + /** column name */ TokenName = "token_name", /** column name */ TokenStandard = "token_standard", @@ -2100,31 +2124,37 @@ export enum CurrentAptosNamesSelectColumnCurrentAptosNamesAggregateBoolExpBoolOr /** aggregate stddev on columns */ export type CurrentAptosNamesStddevFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by stddev() on columns of table "current_aptos_names" */ export type CurrentAptosNamesStddevOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** aggregate stddev_pop on columns */ export type CurrentAptosNamesStddevPopFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by stddev_pop() on columns of table "current_aptos_names" */ export type CurrentAptosNamesStddevPopOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** aggregate stddev_samp on columns */ export type CurrentAptosNamesStddevSampFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by stddev_samp() on columns of table "current_aptos_names" */ export type CurrentAptosNamesStddevSampOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** Streaming cursor of the table "current_aptos_names" */ @@ -2138,6 +2168,7 @@ export type CurrentAptosNamesStreamCursorInput = { /** Initial value of the column from where the streaming should start */ export type CurrentAptosNamesStreamCursorValueInput = { domain?: InputMaybe; + domain_expiration_timestamp?: InputMaybe; domain_with_suffix?: InputMaybe; expiration_timestamp?: InputMaybe; is_active?: InputMaybe; @@ -2146,6 +2177,7 @@ export type CurrentAptosNamesStreamCursorValueInput = { owner_address?: InputMaybe; registered_address?: InputMaybe; subdomain?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; token_name?: InputMaybe; token_standard?: InputMaybe; }; @@ -2153,41 +2185,49 @@ export type CurrentAptosNamesStreamCursorValueInput = { /** aggregate sum on columns */ export type CurrentAptosNamesSumFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by sum() on columns of table "current_aptos_names" */ export type CurrentAptosNamesSumOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** aggregate var_pop on columns */ export type CurrentAptosNamesVarPopFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by var_pop() on columns of table "current_aptos_names" */ export type CurrentAptosNamesVarPopOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** aggregate var_samp on columns */ export type CurrentAptosNamesVarSampFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by var_samp() on columns of table "current_aptos_names" */ export type CurrentAptosNamesVarSampOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** aggregate variance on columns */ export type CurrentAptosNamesVarianceFields = { last_transaction_version?: Maybe; + subdomain_expiration_policy?: Maybe; }; /** order by variance() on columns of table "current_aptos_names" */ export type CurrentAptosNamesVarianceOrderBy = { last_transaction_version?: InputMaybe; + subdomain_expiration_policy?: InputMaybe; }; /** columns and relationships of "current_coin_balances" */ @@ -3495,8 +3535,10 @@ export type CurrentTokenDatasV2 = { collection_id: Scalars["String"]["output"]; /** An object relationship */ current_collection?: Maybe; - /** An object relationship */ - current_token_ownership?: Maybe; + /** An array relationship */ + current_token_ownerships: Array; + /** An aggregate relationship */ + current_token_ownerships_aggregate: CurrentTokenOwnershipsV2Aggregate; decimals: Scalars["bigint"]["output"]; description: Scalars["String"]["output"]; is_fungible_v2?: Maybe; @@ -3512,6 +3554,24 @@ export type CurrentTokenDatasV2 = { token_uri: Scalars["String"]["output"]; }; +/** columns and relationships of "current_token_datas_v2" */ +export type CurrentTokenDatasV2CurrentTokenOwnershipsArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + +/** columns and relationships of "current_token_datas_v2" */ +export type CurrentTokenDatasV2CurrentTokenOwnershipsAggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + /** columns and relationships of "current_token_datas_v2" */ export type CurrentTokenDatasV2TokenPropertiesArgs = { path?: InputMaybe; @@ -3526,7 +3586,8 @@ export type CurrentTokenDatasV2BoolExp = { cdn_asset_uris?: InputMaybe; collection_id?: InputMaybe; current_collection?: InputMaybe; - current_token_ownership?: InputMaybe; + current_token_ownerships?: InputMaybe; + current_token_ownerships_aggregate?: InputMaybe; decimals?: InputMaybe; description?: InputMaybe; is_fungible_v2?: InputMaybe; @@ -3548,7 +3609,7 @@ export type CurrentTokenDatasV2OrderBy = { cdn_asset_uris?: InputMaybe; collection_id?: InputMaybe; current_collection?: InputMaybe; - current_token_ownership?: InputMaybe; + current_token_ownerships_aggregate?: InputMaybe; decimals?: InputMaybe; description?: InputMaybe; is_fungible_v2?: InputMaybe; @@ -3938,6 +3999,7 @@ export type CurrentTokenOwnershipsV2 = { is_soulbound_v2?: Maybe; last_transaction_timestamp: Scalars["timestamp"]["output"]; last_transaction_version: Scalars["bigint"]["output"]; + non_transferrable_by_owner?: Maybe; owner_address: Scalars["String"]["output"]; property_version_v1: Scalars["numeric"]["output"]; storage_id: Scalars["String"]["output"]; @@ -4066,6 +4128,7 @@ export type CurrentTokenOwnershipsV2BoolExp = { is_soulbound_v2?: InputMaybe; last_transaction_timestamp?: InputMaybe; last_transaction_version?: InputMaybe; + non_transferrable_by_owner?: InputMaybe; owner_address?: InputMaybe; property_version_v1?: InputMaybe; storage_id?: InputMaybe; @@ -4136,6 +4199,7 @@ export type CurrentTokenOwnershipsV2OrderBy = { is_soulbound_v2?: InputMaybe; last_transaction_timestamp?: InputMaybe; last_transaction_version?: InputMaybe; + non_transferrable_by_owner?: InputMaybe; owner_address?: InputMaybe; property_version_v1?: InputMaybe; storage_id?: InputMaybe; @@ -4158,6 +4222,8 @@ export enum CurrentTokenOwnershipsV2SelectColumn { /** column name */ LastTransactionVersion = "last_transaction_version", /** column name */ + NonTransferrableByOwner = "non_transferrable_by_owner", + /** column name */ OwnerAddress = "owner_address", /** column name */ PropertyVersionV1 = "property_version_v1", @@ -4179,6 +4245,8 @@ export enum CurrentTokenOwnershipsV2SelectColumnCurrentTokenOwnershipsV2Aggregat IsFungibleV2 = "is_fungible_v2", /** column name */ IsSoulboundV2 = "is_soulbound_v2", + /** column name */ + NonTransferrableByOwner = "non_transferrable_by_owner", } /** select "current_token_ownerships_v2_aggregate_bool_exp_bool_or_arguments_columns" columns of table "current_token_ownerships_v2" */ @@ -4187,6 +4255,8 @@ export enum CurrentTokenOwnershipsV2SelectColumnCurrentTokenOwnershipsV2Aggregat IsFungibleV2 = "is_fungible_v2", /** column name */ IsSoulboundV2 = "is_soulbound_v2", + /** column name */ + NonTransferrableByOwner = "non_transferrable_by_owner", } /** aggregate stddev on columns */ @@ -4246,6 +4316,7 @@ export type CurrentTokenOwnershipsV2StreamCursorValueInput = { is_soulbound_v2?: InputMaybe; last_transaction_timestamp?: InputMaybe; last_transaction_version?: InputMaybe; + non_transferrable_by_owner?: InputMaybe; owner_address?: InputMaybe; property_version_v1?: InputMaybe; storage_id?: InputMaybe; @@ -7072,6 +7143,10 @@ export type QueryRoot = { proposal_votes_aggregate: ProposalVotesAggregate; /** fetch data from the table: "proposal_votes" using primary key columns */ proposal_votes_by_pk?: Maybe; + /** fetch data from the table: "signatures" */ + signatures: Array; + /** fetch data from the table: "signatures" using primary key columns */ + signatures_by_pk?: Maybe; /** fetch data from the table: "table_items" */ table_items: Array; /** fetch data from the table: "table_items" using primary key columns */ @@ -7802,6 +7877,21 @@ export type QueryRootProposalVotesByPkArgs = { voter_address: Scalars["String"]["input"]; }; +export type QueryRootSignaturesArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + +export type QueryRootSignaturesByPkArgs = { + is_sender_primary: Scalars["Boolean"]["input"]; + multi_agent_index: Scalars["bigint"]["input"]; + multi_sig_index: Scalars["bigint"]["input"]; + transaction_version: Scalars["bigint"]["input"]; +}; + export type QueryRootTableItemsArgs = { distinct_on?: InputMaybe>; limit?: InputMaybe; @@ -7925,6 +8015,108 @@ export type QueryRootUserTransactionsByPkArgs = { version: Scalars["bigint"]["input"]; }; +/** columns and relationships of "signatures" */ +export type Signatures = { + is_sender_primary: Scalars["Boolean"]["output"]; + multi_agent_index: Scalars["bigint"]["output"]; + multi_sig_index: Scalars["bigint"]["output"]; + public_key: Scalars["String"]["output"]; + public_key_indices: Scalars["jsonb"]["output"]; + signature: Scalars["String"]["output"]; + signer: Scalars["String"]["output"]; + threshold: Scalars["bigint"]["output"]; + transaction_block_height: Scalars["bigint"]["output"]; + transaction_version: Scalars["bigint"]["output"]; + type: Scalars["String"]["output"]; +}; + +/** columns and relationships of "signatures" */ +export type SignaturesPublicKeyIndicesArgs = { + path?: InputMaybe; +}; + +/** Boolean expression to filter rows from the table "signatures". All fields are combined with a logical 'AND'. */ +export type SignaturesBoolExp = { + _and?: InputMaybe>; + _not?: InputMaybe; + _or?: InputMaybe>; + is_sender_primary?: InputMaybe; + multi_agent_index?: InputMaybe; + multi_sig_index?: InputMaybe; + public_key?: InputMaybe; + public_key_indices?: InputMaybe; + signature?: InputMaybe; + signer?: InputMaybe; + threshold?: InputMaybe; + transaction_block_height?: InputMaybe; + transaction_version?: InputMaybe; + type?: InputMaybe; +}; + +/** Ordering options when selecting data from "signatures". */ +export type SignaturesOrderBy = { + is_sender_primary?: InputMaybe; + multi_agent_index?: InputMaybe; + multi_sig_index?: InputMaybe; + public_key?: InputMaybe; + public_key_indices?: InputMaybe; + signature?: InputMaybe; + signer?: InputMaybe; + threshold?: InputMaybe; + transaction_block_height?: InputMaybe; + transaction_version?: InputMaybe; + type?: InputMaybe; +}; + +/** select columns of table "signatures" */ +export enum SignaturesSelectColumn { + /** column name */ + IsSenderPrimary = "is_sender_primary", + /** column name */ + MultiAgentIndex = "multi_agent_index", + /** column name */ + MultiSigIndex = "multi_sig_index", + /** column name */ + PublicKey = "public_key", + /** column name */ + PublicKeyIndices = "public_key_indices", + /** column name */ + Signature = "signature", + /** column name */ + Signer = "signer", + /** column name */ + Threshold = "threshold", + /** column name */ + TransactionBlockHeight = "transaction_block_height", + /** column name */ + TransactionVersion = "transaction_version", + /** column name */ + Type = "type", +} + +/** Streaming cursor of the table "signatures" */ +export type SignaturesStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: SignaturesStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type SignaturesStreamCursorValueInput = { + is_sender_primary?: InputMaybe; + multi_agent_index?: InputMaybe; + multi_sig_index?: InputMaybe; + public_key?: InputMaybe; + public_key_indices?: InputMaybe; + signature?: InputMaybe; + signer?: InputMaybe; + threshold?: InputMaybe; + transaction_block_height?: InputMaybe; + transaction_version?: InputMaybe; + type?: InputMaybe; +}; + export type SubscriptionRoot = { /** fetch data from the table: "account_transactions" */ account_transactions: Array; @@ -8226,6 +8418,12 @@ export type SubscriptionRoot = { proposal_votes_by_pk?: Maybe; /** fetch data from the table in a streaming manner: "proposal_votes" */ proposal_votes_stream: Array; + /** fetch data from the table: "signatures" */ + signatures: Array; + /** fetch data from the table: "signatures" using primary key columns */ + signatures_by_pk?: Maybe; + /** fetch data from the table in a streaming manner: "signatures" */ + signatures_stream: Array; /** fetch data from the table: "table_items" */ table_items: Array; /** fetch data from the table: "table_items" using primary key columns */ @@ -9260,6 +9458,27 @@ export type SubscriptionRootProposalVotesStreamArgs = { where?: InputMaybe; }; +export type SubscriptionRootSignaturesArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + +export type SubscriptionRootSignaturesByPkArgs = { + is_sender_primary: Scalars["Boolean"]["input"]; + multi_agent_index: Scalars["bigint"]["input"]; + multi_sig_index: Scalars["bigint"]["input"]; + transaction_version: Scalars["bigint"]["input"]; +}; + +export type SubscriptionRootSignaturesStreamArgs = { + batch_size: Scalars["Int"]["input"]; + cursor: Array>; + where?: InputMaybe; +}; + export type SubscriptionRootTableItemsArgs = { distinct_on?: InputMaybe>; limit?: InputMaybe; diff --git a/src/types/indexer.ts b/src/types/indexer.ts index df2952bde..cb9567f63 100644 --- a/src/types/indexer.ts +++ b/src/types/indexer.ts @@ -30,6 +30,8 @@ import { GetTokenActivityQuery, GetCurrentTokenOwnershipQuery, GetNamesQuery, + GetTableItemsDataQuery, + GetTableItemsMetadataQuery, } from "./generated/operations"; /** @@ -66,6 +68,8 @@ export type GetCurrentFungibleAssetBalancesResponse = export type GetTokenActivityResponse = GetTokenActivityQuery["token_activities_v2"]; export type GetCurrentTokenOwnershipResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"][0]; export type GetOwnedTokensResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"]; +export type GetTableItemsDataResponse = GetTableItemsDataQuery["table_items"]; +export type GetTableItemsMetadataResponse = GetTableItemsMetadataQuery["table_metadatas"]; export type GetANSNameResponse = GetNamesQuery["current_aptos_names"]; diff --git a/tests/e2e/api/account.test.ts b/tests/e2e/api/account.test.ts index 84f77a10e..1ed01a66e 100644 --- a/tests/e2e/api/account.test.ts +++ b/tests/e2e/api/account.test.ts @@ -226,6 +226,49 @@ describe("account api", () => { expect(lookupAccount).toStrictEqual(account.accountAddress); }); + test("it fetches account owned token fron collection", async () => { + const config = new AptosConfig({ network: Network.LOCAL }); + const aptos = new Aptos(config); + const creator = Account.generate(); + await aptos.fundAccount({ accountAddress: creator.accountAddress, amount: FUND_AMOUNT }); + const collectionCreationTransaction = await aptos.createCollectionTransaction({ + creator, + description: "My new collection!", + name: "Test Collection", + uri: "Test Collection", + }); + const pendingCollectionCreationTransaction = await aptos.signAndSubmitTransaction({ + signer: creator, + transaction: collectionCreationTransaction, + }); + await aptos.waitForTransaction({ transactionHash: pendingCollectionCreationTransaction.hash }); + const transaction = await aptos.mintDigitalAssetTransaction({ + creator, + collection: "Test Collection", + description: "My new collection!", + name: "Test Token", + uri: "http://aptos.dev/nft", + propertyKeys: ["my bool key", "my array key"], + propertyTypes: ["BOOLEAN", "ARRAY"], + propertyValues: [false, "[value]"], + }); + const pendingTxn = await aptos.signAndSubmitTransaction({ signer: creator, transaction }); + const response = await aptos.waitForTransaction({ transactionHash: pendingTxn.hash }); + + const address = await aptos.getCollectionId({ + collectionName: "Test Collection", + creatorAddress: creator.accountAddress, + }); + const tokens = await aptos.getAccountOwnedTokensFromCollectionAddress({ + accountAddress: creator.accountAddress, + collectionAddress: address, + minimumLedgerVersion: BigInt(response.version), + }); + + expect(tokens.length).toBe(1); + expect(tokens[0].current_token_data?.token_name).toBe("Test Token"); + }); + describe("it derives an account from a private key", () => { test("single sender ed25519", async () => { const config = new AptosConfig({ network: Network.LOCAL }); diff --git a/tests/e2e/api/general.test.ts b/tests/e2e/api/general.test.ts index 74abd37bb..b82f64fe7 100644 --- a/tests/e2e/api/general.test.ts +++ b/tests/e2e/api/general.test.ts @@ -1,102 +1,36 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -import { AptosConfig, Aptos, Network, GraphqlQuery, ProcessorType, InputViewFunctionData } from "../../../src"; +import { Network, GraphqlQuery, ProcessorType, InputViewFunctionData } from "../../../src"; import { getAptosClient } from "../helper"; describe("general api", () => { + const { aptos } = getAptosClient(); + test("it fetches ledger info", async () => { - const { aptos } = getAptosClient(); const ledgerInfo = await aptos.getLedgerInfo(); expect(ledgerInfo.chain_id).toBe(4); }); test("it fetches chain id", async () => { - const { aptos } = getAptosClient(); const chainId = await aptos.getChainId(); expect(chainId).toBe(4); }); test("it fetches block data by block height", async () => { - const { aptos } = getAptosClient(); const blockHeight = 1; const blockData = await aptos.getBlockByHeight({ blockHeight }); expect(blockData.block_height).toBe(blockHeight.toString()); }); test("it fetches block data by block version", async () => { - const { aptos } = getAptosClient(); const blockVersion = 1; const blockData = await aptos.getBlockByVersion({ ledgerVersion: blockVersion }); expect(blockData.block_height).toBe(blockVersion.toString()); }); - test("it fetches table item data", async () => { - const { aptos } = getAptosClient(); - type Supply = { - supply: { - vec: [ - { - aggregator: { - vec: [{ handle: string; key: string }]; - }; - }, - ]; - }; - }; - const resource = await aptos.getAccountResource({ - accountAddress: "0x1", - resourceType: "0x1::coin::CoinInfo<0x1::aptos_coin::AptosCoin>", - }); - - const { handle, key } = resource.supply.vec[0].aggregator.vec[0]; - - const supply = await aptos.getTableItem({ - handle, - data: { - key_type: "address", - value_type: "u128", - key, - }, - }); - expect(parseInt(supply, 10)).toBeGreaterThan(0); - }); - - test("it fetches data with a custom graphql query", async () => { - const config = new AptosConfig({ network: Network.TESTNET }); - const aptos = new Aptos(config); - - const query: GraphqlQuery = { - query: `query MyQuery { - ledger_infos { - chain_id - } - }`, - }; - - const chainId = await aptos.queryIndexer<{ - ledger_infos: [ - { - chain_id: number; - }, - ]; - }>({ query }); - - expect(chainId.ledger_infos[0].chain_id).toBe(2); - }); - - test("it should fetch chain top user transactions", async () => { - const config = new AptosConfig({ network: Network.TESTNET }); - const aptos = new Aptos(config); - - const topUserTransactions = await aptos.getChainTopUserTransactions({ limit: 3 }); - expect(topUserTransactions.length).toEqual(3); - }); - describe("View functions", () => { test("it fetches view function data", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::chain_id::get", }; @@ -107,8 +41,6 @@ describe("general api", () => { }); test("it fetches view function with a type", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::chain_id::get", }; @@ -119,8 +51,6 @@ describe("general api", () => { }); test("it fetches view function with bool", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::account::exists_at", functionArguments: ["0x1"], @@ -141,8 +71,6 @@ describe("general api", () => { }); test("it fetches view function with address input and different output types", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::account::get_sequence_number", functionArguments: ["0x1"], @@ -163,8 +91,6 @@ describe("general api", () => { }); test("it fetches view functions with generics", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::coin::symbol", typeArguments: ["0x1::aptos_coin::AptosCoin"], @@ -192,8 +118,6 @@ describe("general api", () => { }); test("view functions that fail in the VM fail here", async () => { - const { aptos } = getAptosClient(); - const payload: InputViewFunctionData = { function: "0x1::account::get_sequence_number", functionArguments: ["0x123456"], @@ -204,9 +128,35 @@ describe("general api", () => { }); test("it should get the processor statuses for one", async () => { - const { aptos } = getAptosClient(); - const processor = await aptos.getProcessorStatus(ProcessorType.ACCOUNT_TRANSACTION_PROCESSOR); expect(processor.processor).toEqual(ProcessorType.ACCOUNT_TRANSACTION_PROCESSOR); }); }); + +describe("general api (requires testnet)", () => { + const { aptos } = getAptosClient({ network: Network.TESTNET }); + test("it fetches data with a custom graphql query", async () => { + const query: GraphqlQuery = { + query: `query MyQuery { + ledger_infos { + chain_id + } + }`, + }; + + const chainId = await aptos.queryIndexer<{ + ledger_infos: [ + { + chain_id: number; + }, + ]; + }>({ query }); + + expect(chainId.ledger_infos[0].chain_id).toBe(2); + }); + + test("it should fetch chain top user transactions", async () => { + const topUserTransactions = await aptos.getChainTopUserTransactions({ limit: 3 }); + expect(topUserTransactions.length).toEqual(3); + }); +}); diff --git a/tests/e2e/api/table.test.ts b/tests/e2e/api/table.test.ts new file mode 100644 index 000000000..136d0d75a --- /dev/null +++ b/tests/e2e/api/table.test.ts @@ -0,0 +1,63 @@ +import { getAptosClient } from "../helper"; + +const { aptos } = getAptosClient(); +let resource: Supply; + +type Supply = { + supply: { + vec: [ + { + aggregator: { + vec: [{ handle: string; key: string }]; + }; + }, + ]; + }; +}; + +describe("table", () => { + beforeAll(async () => { + resource = await aptos.getAccountResource({ + accountAddress: "0x1", + resourceType: "0x1::coin::CoinInfo<0x1::aptos_coin::AptosCoin>", + }); + }); + + test("it fetches table item", async () => { + const { handle, key } = resource.supply.vec[0].aggregator.vec[0]; + + const supply = await aptos.getTableItem({ + handle, + data: { + key_type: "address", + value_type: "u128", + key, + }, + }); + + expect(parseInt(supply, 10)).toBeGreaterThan(0); + }); + + test("it fetches table items data", async () => { + const { handle } = resource.supply.vec[0].aggregator.vec[0]; + + const data = await aptos.getTableItemsData({ + options: { where: { table_handle: { _eq: handle }, transaction_version: { _eq: 0 } } }, + }); + + expect(data[0].decoded_key).toEqual("0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935"); + expect(data[0].decoded_value).toEqual("18446744073709551625"); + expect(data[0].key).toEqual("0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935"); + }); + + test("it fetches table items metadata data", async () => { + const { handle } = resource.supply.vec[0].aggregator.vec[0]; + + const data = await aptos.getTableItemsMetadata({ + options: { where: { handle: { _eq: handle } } }, + }); + + expect(data[0].value_type).toEqual("u128"); + expect(data[0].key_type).toEqual("address"); + }); +});