Skip to content

Commit ac22260

Browse files
ryanioclaude
andauthored
feat: add postListing/postOffer API methods, deprecate legacy order endpoints (#1936)
* feat: migrate from deprecated order response to v2 listing/offer types The os2-core POST listing/offer endpoints now return both a deprecated `order` field and new `listing`/`offer` fields with the v2 response format. This PR migrates the SDK to read from the new fields. BREAKING CHANGES: - `createListing` now returns `Listing` instead of `OrderV2` - `createOffer` now returns `Offer` instead of `OrderV2` - `createBulkListings` returns `BulkListingResult` instead of `BulkOrderResult` - `createBulkOffers` returns `BulkOfferResult` instead of `BulkOrderResult` - New `postListing`/`postOffer` API methods replace deprecated `postOrder` - GET orders endpoints (`getOrder`/`getOrders`) marked as deprecated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: add new postListing/postOffer API methods (non-breaking) Add new API methods that return native Listing/Offer types from the upcoming os2-core response format changes. Existing methods and return types are preserved — consumers can migrate at their own pace. - Add postListing() and postOffer() on OpenSeaAPI and OrdersAPI - Add ListingPostQueryResponse and OfferPostQueryResponse types - Mark deprecated methods with @deprecated JSDoc annotations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4f1e504 commit ac22260

3 files changed

Lines changed: 92 additions & 0 deletions

File tree

src/api/api.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import {
5151
GetSwapQuoteArgs,
5252
GetSwapQuoteResponse,
5353
GetTokenResponse,
54+
Listing,
55+
Offer,
5456
SearchArgs,
5557
SearchResponse,
5658
} from "./types";
@@ -126,6 +128,7 @@ export class OpenSeaAPI {
126128

127129
/**
128130
* Gets an order from API based on query options.
131+
* @deprecated Use collection-based endpoints instead: getAllOffers, getAllListings, getBestOffer, getBestListing.
129132
* @param options Query options for fetching an order
130133
* @returns The first {@link OrderV2} returned by the API
131134
*
@@ -155,6 +158,7 @@ export class OpenSeaAPI {
155158

156159
/**
157160
* Gets a list of orders from API based on query options.
161+
* @deprecated Use collection-based endpoints instead: getAllOffers, getAllListings, getBestOffer, getBestListing.
158162
* @param options Query options for fetching orders
159163
* @returns The {@link GetOrdersResponse} returned by the API.
160164
*/
@@ -325,6 +329,7 @@ export class OpenSeaAPI {
325329

326330
/**
327331
* Post an order to OpenSea.
332+
* @deprecated Use postListing or postOffer instead.
328333
* @param order The order to post
329334
* @param apiOptions API options for the order
330335
* @returns The {@link OrderV2} posted to the API.
@@ -336,6 +341,32 @@ export class OpenSeaAPI {
336341
return this.ordersAPI.postOrder(order, apiOptions);
337342
}
338343

344+
/**
345+
* Post a listing to OpenSea. Returns the new v2 Listing response format.
346+
* @param order The order to post
347+
* @param protocolAddress The contract address of the seaport protocol
348+
* @returns The {@link Listing} posted to the API.
349+
*/
350+
public async postListing(
351+
order: ProtocolData,
352+
protocolAddress: string,
353+
): Promise<Listing> {
354+
return this.ordersAPI.postListing(order, protocolAddress);
355+
}
356+
357+
/**
358+
* Post an offer to OpenSea. Returns the new v2 Offer response format.
359+
* @param order The order to post
360+
* @param protocolAddress The contract address of the seaport protocol
361+
* @returns The {@link Offer} posted to the API.
362+
*/
363+
public async postOffer(
364+
order: ProtocolData,
365+
protocolAddress: string,
366+
): Promise<Offer> {
367+
return this.ordersAPI.postOffer(order, protocolAddress);
368+
}
369+
339370
/**
340371
* Build a OpenSea collection offer.
341372
* @param offererAddress The wallet address which is creating the offer.

src/api/orders.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ import {
77
GetOrdersResponse,
88
CancelOrderResponse,
99
GetOrderByHashResponse,
10+
Listing,
11+
Offer,
1012
} from "./types";
1113
import {
1214
FulfillmentDataResponse,
15+
ListingPostQueryResponse,
16+
OfferPostQueryResponse,
1317
OrderAPIOptions,
1418
OrdersPostQueryResponse,
1519
OrdersQueryOptions,
@@ -38,6 +42,7 @@ export class OrdersAPI {
3842

3943
/**
4044
* Gets an order from API based on query options.
45+
* @deprecated Use collection-based endpoints instead: getAllOffers, getAllListings, getBestOffer, getBestListing.
4146
*/
4247
async getOrder({
4348
side,
@@ -90,6 +95,7 @@ export class OrdersAPI {
9095

9196
/**
9297
* Gets a list of orders from API based on query options.
98+
* @deprecated Use collection-based endpoints instead: getAllOffers, getAllListings, getBestOffer, getBestListing.
9399
*/
94100
async getOrders({
95101
side,
@@ -176,6 +182,7 @@ export class OrdersAPI {
176182

177183
/**
178184
* Post an order to OpenSea.
185+
* @deprecated Use postListing or postOffer instead.
179186
*/
180187
async postOrder(
181188
order: ProtocolData,
@@ -216,6 +223,48 @@ export class OrdersAPI {
216223
return deserializeOrder(response.order);
217224
}
218225

226+
/**
227+
* Post a listing to OpenSea. Returns the new Listing response format.
228+
*/
229+
async postListing(
230+
order: ProtocolData,
231+
protocolAddress: string,
232+
): Promise<Listing> {
233+
if (!order) {
234+
throw new Error("order data is required");
235+
}
236+
if (!protocolAddress || !/^0x[a-fA-F0-9]{40}$/.test(protocolAddress)) {
237+
throw new Error("Invalid protocol address format");
238+
}
239+
240+
const response = await this.fetcher.post<ListingPostQueryResponse>(
241+
getOrdersAPIPath(this.chain, "seaport", OrderSide.LISTING),
242+
{ ...order, protocol_address: protocolAddress },
243+
);
244+
return response.listing;
245+
}
246+
247+
/**
248+
* Post an offer to OpenSea. Returns the new Offer response format.
249+
*/
250+
async postOffer(
251+
order: ProtocolData,
252+
protocolAddress: string,
253+
): Promise<Offer> {
254+
if (!order) {
255+
throw new Error("order data is required");
256+
}
257+
if (!protocolAddress || !/^0x[a-fA-F0-9]{40}$/.test(protocolAddress)) {
258+
throw new Error("Invalid protocol address format");
259+
}
260+
261+
const response = await this.fetcher.post<OfferPostQueryResponse>(
262+
getOrdersAPIPath(this.chain, "seaport", OrderSide.OFFER),
263+
{ ...order, protocol_address: protocolAddress },
264+
);
265+
return response.offer;
266+
}
267+
219268
/**
220269
* Offchain cancel an order, offer or listing, by its order hash when protected by the SignedZone.
221270
*/

src/orders/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { BasicOrderParametersStruct } from "@opensea/seaport-js/lib/typechain-types/seaport/contracts/Seaport";
22
import { AdvancedOrder, OrderWithCounter } from "@opensea/seaport-js/lib/types";
3+
import { Listing, Offer } from "../api/types";
34
import { OpenSeaAccount, OrderSide } from "../types";
45

56
// Protocol data
@@ -173,4 +174,15 @@ export type OrdersQueryResponse = QueryCursors & {
173174
orders: SerializedOrderV2[];
174175
};
175176

177+
/** @deprecated Use ListingPostQueryResponse or OfferPostQueryResponse instead. */
176178
export type OrdersPostQueryResponse = { order: SerializedOrderV2 };
179+
180+
export type ListingPostQueryResponse = {
181+
order: SerializedOrderV2;
182+
listing: Listing;
183+
};
184+
185+
export type OfferPostQueryResponse = {
186+
order: SerializedOrderV2;
187+
offer: Offer;
188+
};

0 commit comments

Comments
 (0)