import type { Chain, OpenSeaCollection, OpenSeaCollectionStats } from "../types" import { getBatchCollectionsPath, getCollectionFloorPricesPath, getCollectionHoldersPath, getCollectionOfferAggregatesPath, getCollectionPath, getCollectionStatsPath, getCollectionsPath, getTopCollectionsPath, getTraitsPath, getTrendingCollectionsPath, } from "./apiPaths" import type { Fetcher } from "./fetcher" import { type BatchCollectionsRequest, type CollectionBatchResponse, type CollectionFloorPricesArgs, type CollectionHoldersArgs, type CollectionHoldersPaginatedResponse, type CollectionOfferAggregatesPaginatedResponse, CollectionOrderByOption, type FloorPriceHistoryResponse, type GetCollectionResponse, type GetCollectionsArgs, type GetCollectionsPaginatedResponse, type GetCollectionsResponse, type GetTopCollectionsArgs, type GetTraitsResponse, type GetTrendingCollectionsArgs, type PaginatedAnalyticsArgs, } from "./types" /** * Collection-related API operations */ export class CollectionsAPI { constructor(private fetcher: Fetcher) {} /** * Fetch an OpenSea collection. */ async getCollection(slug: string): Promise { const path = getCollectionPath(slug) return this.fetcher.get(path) } /** * Fetch a list of OpenSea collections. */ async getCollections( orderBy: CollectionOrderByOption = CollectionOrderByOption.CREATED_DATE, chain?: Chain, creatorUsername?: string, includeHidden: boolean = false, limit?: number, next?: string, ): Promise { const path = getCollectionsPath() const args: GetCollectionsArgs = { orderBy, chain, creatorUsername, includeHidden, limit, next, } return this.fetcher.get(path, args) } /** * Fetch stats for an OpenSea collection. */ async getCollectionStats(slug: string): Promise { const path = getCollectionStatsPath(slug) const response = await this.fetcher.get(path) return response as OpenSeaCollectionStats } /** * Fetch all traits for a collection with their possible values and counts. * * Opts out of response camelization: this payload is keyed by * collection-authored trait names and trait values rather than by field * names, so the default rewrite reports a `dark_brown` trait as `darkBrown` * and silently merges two traits that differ only in casing. The response's * own field names (`categories`, `counts`) are single words with nothing to * convert, so opting out is complete rather than a partial workaround. */ async getTraits(collectionSlug: string): Promise { const path = getTraitsPath(collectionSlug) const response = await this.fetcher.get( path, undefined, { camelizeResponse: false, }, ) return response } /** * Fetch trending collections sorted by sales activity. */ async getTrendingCollections( args?: GetTrendingCollectionsArgs, ): Promise { return this.fetcher.get( getTrendingCollectionsPath(), { ...args, chains: args?.chains?.join(","), }, ) } /** * Fetch top collections ranked by various stats. */ async getTopCollections( args?: GetTopCollectionsArgs, ): Promise { return this.fetcher.get( getTopCollectionsPath(), { ...args, chains: args?.chains?.join(","), }, ) } /** * Fetch multiple collections in a single request by slug. */ async getCollectionsBatch( request: BatchCollectionsRequest, ): Promise { return this.fetcher.post( getBatchCollectionsPath(), request, ) } /** * Fetch aggregated offer information for a collection — top offers grouped * by price level. Useful for displaying offer-book depth. */ async getCollectionOfferAggregates( slug: string, args?: PaginatedAnalyticsArgs, ): Promise { return this.fetcher.get( getCollectionOfferAggregatesPath(slug), args, ) } /** * Fetch holders of a collection, ranked by quantity owned. Optionally * filter to a single owner via `args.owned_by`. */ async getCollectionHolders( slug: string, args?: CollectionHoldersArgs, ): Promise { return this.fetcher.get( getCollectionHoldersPath(slug), args, ) } /** * Fetch the floor-price history of a collection. */ async getCollectionFloorPrices( slug: string, args?: CollectionFloorPricesArgs, ): Promise { return this.fetcher.get( getCollectionFloorPricesPath(slug), args, ) } }