Repository: alchemyplatform/alchemy-sdk-js
Pull request #218 (2022-12-19 14:55:16)

add request params to getNFTs and getContracts
- add orderBy to getNFTs and getContractsForOwner request options
- add includeFilters to getNFTs params
- rename params object for getContractsForOwner to `getContractsForOwnerParams`

ayang-rkjs: Current dependencies on/for this PR:
* main
  * **PR #218** <a href="https://app.graphite.dev/github/pr/alchemyplatform/alchemy-sdk-js/218" target="_blank"><img src="https://static.graphite.dev/graphite-32x32.png" alt="Graphite" width="10px" height="10px"/></a>  👈

This comment was auto-generated by [Graphite](https://app.graphite.dev/github/pr/alchemyplatform/alchemy-sdk-js/218?utm_source=stack-comment).

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2fb3a3db..c13c72fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,9 @@
 
 ### Minor Changes
 
-- Fixed a bug in `NftNamesapce.getNftsForOwner()` where the `openSea` metadata was not included in the returned NFT.
-- Marked the `NftFilters` type as deprecated. Please use `NftExcludeFilters` or `NftIncludeFilters` instead.
+- Fixed a bug in `NftNamespace.getNftsForOwner()` where the `openSea` metadata was not included in the returned NFT.
+- Marked the `NftExcludeFilters` type as deprecated. Please use `NftFilters` instead.
+- Added support for the `orderBy` param to `NftNamespace.getNftsForOwner()` and `NftNamespace.getContractsForOwner()`.
 
 ## 2.2.4
 
@@ -27,6 +28,7 @@
 ### Major Changes
 
 ### Minor Changes
+
 - Fixed a typo with the `AlchemySettings.batchRequests` property.
 
 ## 2.2.2 (DEPRECATED)
diff --git a/src/internal/nft-api.ts b/src/internal/nft-api.ts
index 98b522f9..d2049ed8 100644
--- a/src/internal/nft-api.ts
+++ b/src/internal/nft-api.ts
@@ -25,6 +25,7 @@ import {
   NftFilters,
   NftMetadataBatchOptions,
   NftMetadataBatchToken,
+  NftOrdering,
   NftSaleMarketplace,
   NftSaleTakerType,
   NftTokenType,
@@ -173,10 +174,13 @@ export async function getNftsForOwner(
     contractAddresses: options?.contractAddresses,
     pageKey: options?.pageKey,
     filters: options?.excludeFilters,
+    excludeFilters: options?.excludeFilters,
+    includeFilters: options?.includeFilters,
     owner,
     pageSize: options?.pageSize,
     withMetadata,
-    tokenUriTimeoutInMs: options?.tokenUriTimeoutInMs
+    tokenUriTimeoutInMs: options?.tokenUriTimeoutInMs,
+    orderBy: options?.orderBy
   });
   return {
     ownedNfts: response.ownedNfts.map(res => ({
@@ -274,13 +278,14 @@ export async function getContractsForOwner(
   srcMethod = 'getContractsForOwner'
 ): Promise<GetContractsForOwnerResponse> {
   const response = await requestHttpWithBackoff<
-    GetOwnersForContractParams,
+    GetContractsForOwnerParams,
     RawGetContractsForOwnerResponse
   >(config, AlchemyApiType.NFT, 'getContractsForOwner', srcMethod, {
     owner,
     excludeFilters: options?.excludeFilters,
     includeFilters: options?.includeFilters,
-    pageKey: options?.pageKey
+    pageKey: options?.pageKey,
+    orderBy: options?.orderBy
   });
 
   return getContractsForOwnerFromRaw(response);
@@ -656,10 +661,14 @@ interface GetNftsAlchemyParams {
   owner: string;
   pageKey?: string;
   contractAddresses?: string[];
+  /** @deprecated - Please use `excludeFilters` instead. */
   filters?: string[];
+  excludeFilters?: NftFilters[];
+  includeFilters?: NftFilters[];
   pageSize?: number;
   withMetadata: boolean;
   tokenUriTimeoutInMs?: number;
+  orderBy?: string;
 }
 
 /**
@@ -707,11 +716,12 @@ interface GetOwnersForNftContractAlchemyParams {
  *
  * @internal
  */
-interface GetOwnersForContractParams {
+interface GetContractsForOwnerParams {
   owner: string;
   pageKey?: string;
   includeFilters?: NftFilters[];
   excludeFilters?: NftFilters[];
+  orderBy?: NftOrdering;
 }
 
 /**
diff --git a/src/types/types.ts b/src/types/types.ts
index 96858222..3d4dc46a 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -541,7 +541,13 @@ export interface GetNftsForOwnerOptions {
    * Optional list of filters applied to the query. NFTs that match one or more
    * of these filters are excluded from the response.
    */
-  excludeFilters?: (NftExcludeFilters | NftFilters)[];
+  excludeFilters?: NftFilters[];
+
+  /**
+   * Optional list of filters applied to the query. NFTs that match one or more
+   * of these filters are included in the response.
+   */
+  includeFilters?: NftFilters[];
 
   /**
    * Sets the total number of NFTs to return in the response. Defaults to 100.
@@ -559,6 +565,12 @@ export interface GetNftsForOwnerOptions {
    * metadata for cache misses then set this value to 0.
    */
   tokenUriTimeoutInMs?: number;
+
+  /**
+   * Order in which to return results. By default, results are ordered by
+   * contract address and token ID in lexicographic order.
+   */
+  orderBy?: NftOrdering;
 }
 
 /**
@@ -584,7 +596,13 @@ export interface GetBaseNftsForOwnerOptions {
    * Optional list of filters applied to the query. NFTs that match one or more
    * of these filters are excluded from the response.
    */
-  excludeFilters?: (NftExcludeFilters | NftFilters)[];
+  excludeFilters?: NftFilters[];
+
+  /**
+   * Optional list of filters applied to the query. NFTs that match one or more
+   * of these filters are included in the response.
+   */
+  includeFilters?: NftFilters[];
 
   /**
    * Sets the total number of NFTs to return in the response. Defaults to 100.
@@ -602,6 +620,12 @@ export interface GetBaseNftsForOwnerOptions {
    * metadata for cache misses then set this value to 0.
    */
   tokenUriTimeoutInMs?: number;
+
+  /**
+   * Order in which to return results. By default, results are ordered by
+   * contract address and token ID in lexicographic order.
+   */
+  orderBy?: NftOrdering;
 }
 
 /**
@@ -635,6 +659,16 @@ export enum NftFilters {
   AIRDROPS = 'AIRDROPS'
 }
 
+/**
+ * Enum of ordering that can be applied to a {@link getNftsForOwner} or a
+ * {@link getContractsForOwner} response.
+ *
+ * @beta
+ */
+export enum NftOrdering {
+  TRANSFERTIME = 'TRANSFERTIME'
+}
+
 /**
  * The response object for the {@link getNftsForOwner} and
  * {@link getNftsForOwnerIterator} functions. The object contains the NFTs with
@@ -852,6 +886,12 @@ export interface GetContractsForOwnerOptions {
    * conjunction with {@link includeFilters}
    */
   excludeFilters?: NftFilters[];
+
+  /**
+   * Order in which to return results. By default, results are ordered by
+   * contract address and token ID in lexicographic order.
+   */
+  orderBy?: NftOrdering;
 }
 
 /**


Test patch:
diff --git a/test/unit/nft-api.test.ts b/test/unit/nft-api.test.ts
index e0d44346..fd9b7ed8 100644
--- a/test/unit/nft-api.test.ts
+++ b/test/unit/nft-api.test.ts
@@ -4,7 +4,6 @@ import MockAdapter from 'axios-mock-adapter';
 import {
   Alchemy,
   BaseNft,
-  fromHex,
   GetContractsForOwnerOptions,
   GetFloorPriceResponse,
   GetNftSalesOptions,
@@ -16,6 +15,7 @@ import {
   NftContractNftsResponse,
   NftFilters,
   NftMetadataBatchToken,
+  NftOrdering,
   NftSaleMarketplace,
   NftSaleTakerType,
   NftTokenType,
@@ -24,7 +24,8 @@ import {
   OwnedNft,
   OwnedNftsResponse,
   RefreshState,
-  SortingOrder
+  SortingOrder,
+  fromHex
 } from '../../src';
 import {
   RawGetBaseNftsForContractResponse,
@@ -281,7 +282,8 @@ describe('NFT module', () => {
       contractAddresses,
       excludeFilters,
       pageSize: 3,
-      tokenUriTimeoutInMs: 50
+      tokenUriTimeoutInMs: 50,
+      orderBy: NftOrdering.TRANSFERTIME
     };
     const baseNftResponse: RawGetBaseNftsResponse = {
       ownedNfts: [
@@ -337,6 +339,10 @@ describe('NFT module', () => {
           'tokenUriTimeoutInMs',
           50
         );
+        expect(mock.history.get[0].params).toHaveProperty(
+          'orderBy',
+          'TRANSFERTIME'
+        );
       }
     );