diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/developerDocs/advanced-use-cases.md b/developerDocs/advanced-use-cases.md index 5ecfcaccc..992403d7c 100644 --- a/developerDocs/advanced-use-cases.md +++ b/developerDocs/advanced-use-cases.md @@ -68,11 +68,10 @@ const order = await openseaSDK.createListing({ }); ``` -You can use `getPaymentTokens` to search for tokens by symbol name. And you can even list all orders for a specific ERC-20 token by querying the API: +You can use `getPaymentToken` to search for payment tokens by address. And you can even list all orders for a specific ERC-20 token by querying the API: ```typescript -const token = (await openseaSDK.api.getPaymentTokens({ symbol: "MANA" })) - .tokens[0]; +const token = await openseaSDK.api.getPaymentToken(paymentTokenAddress); const order = await openseaSDK.api.getOrders({ side: OrderSide.ASK, diff --git a/src/api/api.ts b/src/api/api.ts index 0a0a23281..8f2dd2cd0 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -14,7 +14,7 @@ import { getBestListingAPIPath, getAllOffersAPIPath, getAllListingsAPIPath, - getPaymentTokensPath, + getPaymentTokenPath, getAccountPath, getCollectionStatsPath, getBestListingsAPIPath, @@ -26,7 +26,6 @@ import { GetNFTResponse, ListCollectionOffersResponse, GetOrdersResponse, - GetPaymentTokensResponse, GetBestOfferResponse, GetBestListingResponse, GetOffersResponse, @@ -58,7 +57,7 @@ import { OpenSeaAccount, OpenSeaCollection, OpenSeaCollectionStats, - OpenSeaPaymentTokensQuery, + OpenSeaPaymentToken, OrderSide, } from "../types"; import { @@ -488,7 +487,7 @@ export class OpenSeaAPI { public async getCollection(slug: string): Promise { const path = getCollectionPath(slug); const response = await this.get(path); - return collectionFromJSON(response.collection); + return collectionFromJSON(response); } /** @@ -505,26 +504,19 @@ export class OpenSeaAPI { } /** - * Fetch list of fungible tokens. + * Fetch a payment token. * @param query Query to use for getting tokens. See {@link OpenSeaPaymentTokenQuery}. * @param next The cursor for the next page of results. This is returned from a previous request. - * @returns The {@link GetPaymentTokensResponse} returned by the API. + * @returns The {@link OpenSeaPaymentToken} returned by the API. */ - public async getPaymentTokens( - query: OpenSeaPaymentTokensQuery = {}, - next?: string, - ): Promise { - const json = await this.get( - getPaymentTokensPath(), - { - ...query, - limit: this.pageSize, - next, - }, + public async getPaymentToken( + address: string, + chain = this.chain, + ): Promise { + const json = await this.get( + getPaymentTokenPath(chain, address), ); - return { - tokens: json.tokens.map((t) => paymentTokenFromJSON(t)), - }; + return paymentTokenFromJSON(json); } /** @@ -535,7 +527,6 @@ export class OpenSeaAPI { */ public async getAccount(address: string): Promise { const json = await this.get(getAccountPath(address)); - return accountFromJSON(json); } diff --git a/src/api/apiPaths.ts b/src/api/apiPaths.ts index 4b6301bc0..c0f386573 100644 --- a/src/api/apiPaths.ts +++ b/src/api/apiPaths.ts @@ -44,12 +44,12 @@ export const getCollectionStatsPath = (slug: string) => { return `/api/v2/collections/${slug}/stats`; }; -export const getPaymentTokensPath = () => { - return `/v2/payment_tokens`; +export const getPaymentTokenPath = (chain: Chain, address: string) => { + return `/v2/chain/${chain}/payment_token/${address}`; }; export const getAccountPath = (address: string) => { - return `/v2/account/${address}`; + return `/v2/accounts/${address}`; }; export const getBuildOfferPath = () => { diff --git a/src/api/types.ts b/src/api/types.ts index 9c68fae8c..7693d9184 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -5,7 +5,7 @@ import { ProtocolData, QueryCursors, } from "../orders/types"; -import { OpenSeaCollection, OpenSeaPaymentToken } from "../types"; +import { OpenSeaCollection } from "../types"; /** * Response from OpenSea API for building an offer. @@ -172,15 +172,6 @@ export type GetBestOfferResponse = Offer | CollectionOffer; */ export type GetBestListingResponse = Listing; -/** - * Response from OpenSea API for fetching payment tokens. - * @category API Response Types - */ -export type GetPaymentTokensResponse = { - /** List of {@link OpenSeaPaymentToken} */ - tokens: OpenSeaPaymentToken[]; -}; - /** * NFT type returned by OpenSea API. * @category API Models diff --git a/src/sdk.ts b/src/sdk.ts index fcbc0fa60..ea14b1249 100644 --- a/src/sdk.ts +++ b/src/sdk.ts @@ -273,7 +273,7 @@ export class OpenSeaSDK { } for (const fee of collectionFees) { considerationItems.push( - getConsiderationItem(fee.fee * INVERSE_BASIS_POINT, fee.recipient), + getConsiderationItem(fee.fee * 100, fee.recipient), ); } return considerationItems; @@ -956,13 +956,10 @@ export class OpenSeaSDK { const isEther = tokenAddress === ethers.constants.AddressZero; let paymentToken: OpenSeaPaymentToken | undefined; if (!isEther) { - const { tokens } = await this.api.getPaymentTokens({ - address: tokenAddress, - }); - if (!tokens) { + paymentToken = await this.api.getPaymentToken(tokenAddress); + if (!paymentToken) { throw new Error(`No payment token found for ${tokenAddress}`); } - paymentToken = tokens[0]; } const decimals = paymentToken?.decimals ?? 18; diff --git a/src/types.ts b/src/types.ts index b133b6692..410f09250 100644 --- a/src/types.ts +++ b/src/types.ts @@ -320,6 +320,7 @@ export interface OpenSeaPaymentToken { symbol: string; decimals: number; address: string; + chain: Chain; imageUrl?: string; ethPrice?: string; usdPrice?: string; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 8a01e2cbd..0edfbd9af 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -7,7 +7,6 @@ import { MAX_EXPIRATION_MONTHS, SHARED_STOREFRONT_LAZY_MINT_ADAPTER_CROSS_CHAIN_ADDRESS, SHARED_STOREFRONT_ADDRESSES, - INVERSE_BASIS_POINT, } from "../constants"; import { Chain, @@ -41,7 +40,6 @@ export const collectionFromJSON = (collection: any): OpenSeaCollection => { telegramUrl: collection.telegram_url, twitterUsername: collection.twitter_username, instagramUsername: collection.instagram_username, - contracts: (collection.contracts ?? []).map((contract: any) => ({ address: contract.address, chain: contract.chain, @@ -53,7 +51,10 @@ export const collectionFromJSON = (collection: any): OpenSeaCollection => { }; }; -export const rarityFromJSON = (rarity: any): RarityStrategy => { +export const rarityFromJSON = (rarity: any): RarityStrategy | null => { + if (!rarity) { + return null; + } const fromJSON: RarityStrategy = { strategyId: rarity.strategy_id, strategyVersion: rarity.strategy_version, @@ -70,7 +71,8 @@ export const paymentTokenFromJSON = (token: any): OpenSeaPaymentToken => { symbol: token.symbol, decimals: token.decimals, address: token.address, - imageUrl: token.image_url, + chain: token.chain, + imageUrl: token.image, ethPrice: token.eth_price, usdPrice: token.usd_price, }; @@ -200,7 +202,7 @@ export const getWETHAddress = (chain: Chain) => { case Chain.ZoraTestnet: return "0x4200000000000000000000000000000000000006"; default: - throw new Error(`WETH is not supported on ${chain}`); + throw new Error(`Unknown WETH address for ${chain}`); } }; @@ -223,7 +225,7 @@ export const getAddressAfterRemappingSharedStorefrontAddressToLazyMintAdapterAdd * @returns sum of basis points */ export const feesToBasisPoints = (fees: Fee[]): number => { - const feeBasisPoints = fees.map((fee) => fee.fee * INVERSE_BASIS_POINT); + const feeBasisPoints = fees.map((fee) => fee.fee * 100); return feeBasisPoints.reduce((sum, basisPoints) => basisPoints + sum, 0); }; diff --git a/test/api/api.spec.ts b/test/api/api.spec.ts index a7dce6934..1fd2431a9 100644 --- a/test/api/api.spec.ts +++ b/test/api/api.spec.ts @@ -27,7 +27,8 @@ suite("API", () => { mainAPI.logger = oldLogger; } }; - mainAPI.getPaymentTokens({ symbol: "WETH" }); + const wethAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; + mainAPI.getPaymentToken(wethAddress); }); await logPromise; @@ -38,7 +39,7 @@ suite("API", () => { try { await mainAPI.getNFT(BAYC_CONTRACT_ADDRESS, "404040"); } catch (error) { - assert.include((error as Error).message, "status=404"); + assert.include((error as Error).message, "not found"); } }); }); diff --git a/test/api/getOrders.spec.ts b/test/api/getOrders.spec.ts index 07777a11d..26b0f0a9c 100644 --- a/test/api/getOrders.spec.ts +++ b/test/api/getOrders.spec.ts @@ -1,7 +1,7 @@ import "../utils/setup"; import { expect } from "chai"; import { suite, test } from "mocha"; -import { OrderSide } from "src/types"; +import { OrderSide } from "../../src/types"; import { BAYC_CONTRACT_ADDRESS, BAYC_TOKEN_IDS, diff --git a/test/sdk/orders.spec.ts b/test/sdk/orders.spec.ts index c4099ef0a..949d1d18d 100644 --- a/test/sdk/orders.spec.ts +++ b/test/sdk/orders.spec.ts @@ -15,22 +15,17 @@ const client = new OpenSeaSDK( suite("SDK: orders", () => { test("Fungible tokens filter", async () => { - const manaTokens = (await client.api.getPaymentTokens({ symbol: "MANA" })) - .tokens; - assert.equal(manaTokens.length, 1); - const mana = manaTokens[0]; - assert.isNotNull(mana); - assert.equal(mana.name, "Decentraland MANA"); - assert.equal(mana.address, "0x0f5d2fb29fb7d3cfee444a200298f468908cc942"); - assert.equal(mana.decimals, 18); + const manaAddress = "0x0f5d2fb29fb7d3cfee444a200298f468908cc942"; + const manaPaymentToken = await client.api.getPaymentToken(manaAddress); + assert.isNotNull(manaPaymentToken); + assert.equal(manaPaymentToken.name, "Decentraland MANA"); + assert.equal(manaPaymentToken.address, manaAddress); + assert.equal(manaPaymentToken.decimals, 18); - const dai = (await client.api.getPaymentTokens({ symbol: "DAI" })) - .tokens[0]; - assert.isNotNull(dai); - assert.equal(dai.name, "Dai Stablecoin"); - assert.equal(dai.decimals, 18); - - const all = await client.api.getPaymentTokens(); - assert.isNotEmpty(all); + const daiAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"; + const daiPaymentToken = await client.api.getPaymentToken(daiAddress); + assert.isNotNull(daiPaymentToken); + assert.equal(daiPaymentToken.name, "Dai Stablecoin"); + assert.equal(daiPaymentToken.decimals, 18); }); });