Skip to content

Commit

Permalink
Merge pull request #1 from qvkare/update
Browse files Browse the repository at this point in the history
update
  • Loading branch information
qvkare authored Dec 17, 2024
2 parents f827e11 + 311155d commit 4dc359f
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 101 deletions.
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module.exports = {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-var-requires": "off",
"import/no-unused-modules": "off",
"import/order": [
"error",
{
Expand All @@ -51,9 +52,7 @@ module.exports = {
},
},
],
"import/no-unused-modules": [1, { unusedExports: true }],
"no-control-regex": "off",

"object-shorthand": ["error", "always"],
},
settings: {
Expand Down
89 changes: 52 additions & 37 deletions src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
import { ethers } from "ethers";
import { API_BASE_MAINNET, API_BASE_TESTNET } from "../constants";
import {
ProtocolData,
OrdersQueryOptions,
OrdersQueryResponse,
OrderV2,
FulfillmentDataResponse,
OrderAPIOptions,
OrdersPostQueryResponse,
} from "../orders/types";
import {
getFulfillListingPayload,
getFulfillOfferPayload,
getFulfillmentDataPath,
getBuildCollectionOfferPayload,
getPostCollectionOfferPayload,
serializeOrdersQueryOptions,
deserializeOrder,
} from "../orders/utils";
import {
Chain,
OpenSeaAPIConfig,
OpenSeaCollection,
OpenSeaCollectionStats,
OpenSeaPaymentToken,
OpenSeaAccount,
OrderSide,
OrderProtocol,
} from "../types";
import {
getCollectionPath,
getCollectionsPath,
Expand Down Expand Up @@ -38,35 +67,6 @@ import {
CancelOrderResponse,
GetCollectionsArgs,
} from "./types";
import { API_BASE_MAINNET, API_BASE_TESTNET } from "../constants";
import {
FulfillmentDataResponse,
OrderAPIOptions,
OrdersPostQueryResponse,
OrdersQueryOptions,
OrdersQueryResponse,
OrderV2,
ProtocolData,
} from "../orders/types";
import {
serializeOrdersQueryOptions,
deserializeOrder,
getFulfillmentDataPath,
getFulfillListingPayload,
getFulfillOfferPayload,
getBuildCollectionOfferPayload,
getPostCollectionOfferPayload,
} from "../orders/utils";
import {
Chain,
OpenSeaAPIConfig,
OpenSeaAccount,
OpenSeaCollection,
OpenSeaCollectionStats,
OpenSeaPaymentToken,
OrderSide,
} from "../types";
import { OrderProtocol } from "../orders/types";
import {
paymentTokenFromJSON,
collectionFromJSON,
Expand Down Expand Up @@ -136,7 +136,7 @@ export class OpenSeaAPI {
*/
public async getOrder({
side,
protocol = "seaport",
protocol = OrderProtocol.SEAPORT,
orderDirection = "desc",
orderBy = "created_date",
...restOptions
Expand Down Expand Up @@ -174,7 +174,7 @@ export class OpenSeaAPI {
*/
public async getOrders({
side,
protocol = "seaport",
protocol = OrderProtocol.SEAPORT,
orderDirection = "desc",
orderBy = "created_date",
...restOptions
Expand Down Expand Up @@ -347,23 +347,38 @@ export class OpenSeaAPI {
if (!order || !apiOptions) {
throw new Error("Order and API options are required");
}

// Protocol validation
if (apiOptions.protocol && apiOptions.protocol !== OrderProtocol.SEAPORT) {
throw new Error(`Invalid protocol specified. Must be ${OrderProtocol.SEAPORT}`);
throw new Error(
`Invalid protocol specified. Must be ${OrderProtocol.SEAPORT}`,
);
}

// Side validation
if (!apiOptions.side || (apiOptions.side !== OrderSide.LISTING && apiOptions.side !== OrderSide.OFFER)) {
throw new Error(`Invalid order side specified. Must be either ${OrderSide.LISTING} or ${OrderSide.OFFER}`);
if (
!apiOptions.side ||
(apiOptions.side !== OrderSide.LISTING &&
apiOptions.side !== OrderSide.OFFER)
) {
throw new Error(
`Invalid order side specified. Must be either ${OrderSide.LISTING} or ${OrderSide.OFFER}`,
);
}

// Protocol address validation
if (!apiOptions.protocolAddress || !ethers.isAddress(apiOptions.protocolAddress)) {
if (
!apiOptions.protocolAddress ||
!ethers.isAddress(apiOptions.protocolAddress)
) {
throw new Error("Invalid protocol address provided");
}

const { protocol = OrderProtocol.SEAPORT, side, protocolAddress } = apiOptions;
const {
protocol = OrderProtocol.SEAPORT,
side,
protocolAddress,
} = apiOptions;
const response = await this.post<OrdersPostQueryResponse>(
getOrdersAPIPath(this.chain, protocol, side),
{ ...order, protocol_address: protocolAddress },
Expand Down
3 changes: 1 addition & 2 deletions src/api/apiPaths.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { OrderProtocol } from "../orders/types";
import { Chain, OrderSide } from "../types";
import { Chain, OrderSide, OrderProtocol } from "../types";

export const getOrdersAPIPath = (
chain: Chain,
Expand Down
4 changes: 2 additions & 2 deletions src/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ConsiderationItem } from "@opensea/seaport-js/lib/types";
import {
import type {
OrderType,
OrderV2,
ProtocolData,
QueryCursors,
} from "../orders/types";
import { OpenSeaCollection } from "../types";
import type { OpenSeaCollection } from "../types";

/**
* Response from OpenSea API for building an offer.
Expand Down
1 change: 0 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const MAX_EXPIRATION_MONTHS = 1;
export const API_BASE_MAINNET = "https://api.opensea.io";
export const API_BASE_TESTNET = "https://testnets-api.opensea.io";

// eslint-disable-next-line import/no-unused-modules
export const SIGNED_ZONE = "0x000056f7000000ece9003ca63978907a00ffd100";

export const ENGLISH_AUCTION_ZONE_MAINNETS =
Expand Down
11 changes: 5 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { OpenSeaSDK } from "./sdk";

/**
* @example
* // Example Setup
* ```ts
* import { ethers } from 'ethers'
* import { OpenSeaSDK, Chain } from 'opensea-js'
Expand All @@ -12,11 +11,11 @@ import { OpenSeaSDK } from "./sdk";
* })
* ```
*/
export {
// Main SDK export
OpenSeaSDK,
};

// Export main SDK
export { OpenSeaSDK };

// Export types
export * from "./types";
export * from "./api/types";
export * from "./orders/types";
export type { OrderType, ProtocolData } from "./orders/types";
57 changes: 36 additions & 21 deletions src/orders/types.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import { BasicOrderParametersStruct } from "@opensea/seaport-js/lib/typechain-types/seaport/contracts/Seaport";
import { AdvancedOrder, OrderWithCounter } from "@opensea/seaport-js/lib/types";
import { OpenSeaAccount, OrderSide } from "../types";
import {
AdvancedOrder,
OrderWithCounter,
OrderParameters,
Order,
} from "@opensea/seaport-js/lib/types";
import { BigNumberish } from "ethers";
import { OpenSeaAccount, OrderSide, OrderProtocol } from "../types";

// Protocol data
export enum OrderProtocol {
SEAPORT = "seaport"
}

type OrderProtocolToProtocolData = {
[OrderProtocol.SEAPORT]: OrderWithCounter;
};
type _OrderProtocolToProtocolData = Record<
OrderProtocol,
OrderWithCounter | AdvancedOrder | BasicOrderParametersStruct
>;

export type ProtocolData =
OrderProtocolToProtocolData[keyof typeof OrderProtocol];

export enum OrderType {
BASIC = "basic",
ENGLISH = "english",
CRITERIA = "criteria",
}

type OrderFee = {
account: OpenSeaAccount;
basisPoints: string;
};
| OrderWithCounter
| (Order & {
numerator: bigint;
denominator: bigint;
extraData: string;
parameters: OrderParameters & { counter: BigNumberish };
});

/**
* The latest OpenSea Order schema.
Expand Down Expand Up @@ -69,6 +67,23 @@ export type OrderV2 = {
remainingQuantity: number;
};

/**
* Represents the type of order in the OpenSea marketplace
*/
export enum OrderType {
/** Basic order type for simple transactions */
BASIC = "basic",
/** English auction order type */
ENGLISH = "english",
/** Criteria-based order type for collection offers */
CRITERIA = "criteria",
}

type OrderFee = {
account: OpenSeaAccount;
basisPoints: string;
};

export type FulfillmentDataResponse = {
protocol: string;
fulfillment_data: FulfillmentData;
Expand Down
5 changes: 3 additions & 2 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
TokenStandard,
AssetWithTokenStandard,
AssetWithTokenId,
OrderProtocol,
} from "./types";
import {
getMaxOrderExpirationTimestamp,
Expand Down Expand Up @@ -428,7 +429,7 @@ export class OpenSeaSDK {
const order = await executeAllActions();

return this.api.postOrder(order, {
protocol: "seaport",
protocol: OrderProtocol.SEAPORT,
protocolAddress: DEFAULT_SEAPORT_CONTRACT_ADDRESS,
side: OrderSide.OFFER,
});
Expand Down Expand Up @@ -552,7 +553,7 @@ export class OpenSeaSDK {
const order = await executeAllActions();

return this.api.postOrder(order, {
protocol: "seaport",
protocol: OrderProtocol.SEAPORT,
protocolAddress: DEFAULT_SEAPORT_CONTRACT_ADDRESS,
side: OrderSide.LISTING,
});
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,10 @@ export interface SocialMediaAccount {
platform: string;
username: string;
}

/**
* Order protocol
*/
export enum OrderProtocol {
SEAPORT = "seaport",
}
11 changes: 7 additions & 4 deletions test/api/api.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from "chai";
import { assert, expect } from "chai";
import { suite, test } from "mocha";
import { Chain } from "../../src";
import { getWETHAddress } from "../../src/utils";
Expand All @@ -21,7 +21,9 @@ suite("API", () => {
const logPromise = new Promise<void>((resolve, reject) => {
mainAPI.logger = (log) => {
try {
assert.include(log, `"x-api-key":"${MAINNET_API_KEY}"`);
if (MAINNET_API_KEY) {
assert.include(log, `"x-api-key":"${MAINNET_API_KEY}"`);
}
resolve();
} catch (e) {
reject(e);
Expand All @@ -37,11 +39,12 @@ suite("API", () => {
});

test("API handles errors", async () => {
// 404 Not found for random token id
try {
await mainAPI.getNFT(BAYC_CONTRACT_ADDRESS, "404040");
expect.fail("Should have thrown an error");
} catch (error) {
assert.include((error as Error).message, "not found");
expect(error).to.be.an.instanceOf(Error);
expect((error as Error).message).to.include("not found");
}
});
});
Loading

0 comments on commit 4dc359f

Please sign in to comment.