Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions packages/orderbook/src/api-client/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
ListCollectionBidsResult,
ListingResult,
ListListingsResult,
ListMetadataBidsResult,
ListTradeResult,
ListTraitBidsResult,
MetadataBidResult,
OrdersService,
TradeResult,
TraitBidResult,
Expand All @@ -27,10 +29,12 @@ import {
CreateBidParams,
CreateCollectionBidParams,
CreateListingParams,
CreateMetadataBidParams,
CreateTraitBidParams,
ListBidsParams,
ListCollectionBidsParams,
ListListingsParams,
ListMetadataBidsParams,
ListTraitBidsParams,
ListTradesParams,
} from '../types';
Expand Down Expand Up @@ -127,6 +131,22 @@ export class ImmutableApiClient {
});
}

async getMetadataBid(metadataBidId: string): Promise<MetadataBidResult> {
return this.orderbookService.getMetadataBid({
chainName: this.chainName,
metadataBidId,
});
}

async listMetadataBids(
listOrderParams: ListMetadataBidsParams,
): Promise<ListMetadataBidsResult> {
return this.orderbookService.listMetadataBids({
chainName: this.chainName,
...listOrderParams,
});
}

async listTrades(
listTradesParams: ListTradesParams,
): Promise<ListTradeResult> {
Expand Down Expand Up @@ -315,6 +335,68 @@ export class ImmutableApiClient {
});
}

async createMetadataBid({
orderHash,
orderComponents,
orderSignature,
makerFees,
metadataId,
}: CreateMetadataBidParams): Promise<MetadataBidResult> {
if (orderComponents.offer.length !== 1) {
throw new Error('Only one item can be listed for a metadata bid');
}

if (orderComponents.consideration.length !== 1) {
throw new Error('Only one item can be used as currency for a metadata bid');
}

if (ItemType.ERC20 !== orderComponents.offer[0].itemType) {
throw new Error('Only ERC20 tokens can be used as the currency item in a metadata bid');
}

if (![ItemType.ERC721_WITH_CRITERIA, ItemType.ERC1155_WITH_CRITERIA]
.includes(orderComponents.consideration[0].itemType)
) {
throw new Error('Only ERC721 / ERC1155 collection based tokens can be bid against');
}

if (!metadataId) {
throw new Error('A metadata_id is required for a metadata bid');
}

return this.orderbookService.createMetadataBid({
chainName: this.chainName,
requestBody: {
account_address: orderComponents.offerer,
buy: orderComponents.consideration.map(mapSeaportItemToImmutableAssetCollectionItem),
fees: makerFees.map((f) => ({
type: Fee.type.MAKER_ECOSYSTEM,
amount: f.amount,
recipient_address: f.recipientAddress,
})),
end_at: new Date(
parseInt(`${orderComponents.endTime.toString()}000`, 10),
).toISOString(),
order_hash: orderHash,
protocol_data: {
order_type:
mapSeaportOrderTypeToImmutableProtocolDataOrderType(orderComponents.orderType),
zone_address: orderComponents.zone,
seaport_address: this.seaportAddress,
seaport_version: SEAPORT_CONTRACT_VERSION_V1_5,
counter: orderComponents.counter.toString(),
},
salt: orderComponents.salt,
sell: orderComponents.offer.map(mapSeaportItemToImmutableERC20Item),
signature: orderSignature,
start_at: new Date(
parseInt(`${orderComponents.startTime.toString()}000`, 10),
).toISOString(),
metadata_id: metadataId,
},
});
}

async createTraitBid({
orderHash,
orderComponents,
Expand Down
72 changes: 72 additions & 0 deletions packages/orderbook/src/openapi/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ERC721Item,
FeeType,
Listing,
MetadataBid,
NativeItem,
Order,
Page,
Expand Down Expand Up @@ -315,6 +316,75 @@ export function mapTraitBidFromOpenApiOrder(order: OpenApiOrder): TraitBid {
};
}

export function mapMetadataBidFromOpenApiOrder(order: OpenApiOrder): MetadataBid {
if (order.type !== OpenApiOrder.type.METADATA_BID) {
throw new Error('Order type must be METADATA_BID');
}

const sellItems: ERC20Item[] = order.sell.map((item) => {
if (item.type === 'ERC20') {
return {
type: 'ERC20',
contractAddress: item.contract_address,
amount: item.amount,
};
}

throw new Error('Metadata bid sell items must be ERC20');
});

const buyItems: (ERC721CollectionItem | ERC1155CollectionItem)[] = order.buy.map((item) => {
if (item.type === 'ERC721_COLLECTION') {
return {
type: 'ERC721_COLLECTION',
contractAddress: item.contract_address,
amount: item.amount,
};
}

if (item.type === 'ERC1155_COLLECTION') {
return {
type: 'ERC1155_COLLECTION',
contractAddress: item.contract_address,
amount: item.amount,
};
}

throw new Error('Metadata bid buy items must either ERC721_COLLECTION or ERC1155_COLLECTION');
});

return {
id: order.id,
type: order.type,
chain: order.chain,
accountAddress: order.account_address,
sell: sellItems,
buy: buyItems,
fees: order.fees.map((fee) => ({
amount: fee.amount,
recipientAddress: fee.recipient_address,
type: fee.type as unknown as FeeType,
})),
status: order.status,
fillStatus: order.fill_status,
startAt: order.start_at,
endAt: order.end_at,
salt: order.salt,
signature: order.signature,
orderHash: order.order_hash,
protocolData: {
orderType: order.protocol_data.order_type,
counter: order.protocol_data.counter,
seaportAddress: order.protocol_data.seaport_address,
seaportVersion: order.protocol_data.seaport_version,
zoneAddress: order.protocol_data.zone_address,
},
createdAt: order.created_at,
updatedAt: order.updated_at,
metadataId: order.metadata_id ?? '',
};
}

export function mapOrderFromOpenApiOrder(order: OpenApiOrder): Order {
switch (order.type) {
case OpenApiOrder.type.LISTING:
Expand All @@ -325,6 +395,8 @@ export function mapOrderFromOpenApiOrder(order: OpenApiOrder): Order {
return mapCollectionBidFromOpenApiOrder(order);
case OpenApiOrder.type.TRAIT_BID:
return mapTraitBidFromOpenApiOrder(order);
case OpenApiOrder.type.METADATA_BID:
return mapMetadataBidFromOpenApiOrder(order);
default:
return exhaustiveSwitch(order.type);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/orderbook/src/openapi/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type { CollectionBidResult } from './models/CollectionBidResult';
export type { CreateBidRequestBody } from './models/CreateBidRequestBody';
export type { CreateCollectionBidRequestBody } from './models/CreateCollectionBidRequestBody';
export type { CreateTraitBidRequestBody } from './models/CreateTraitBidRequestBody';
export type { CreateMetadataBidRequestBody } from './models/CreateMetadataBidRequestBody';
export type { CreateListingRequestBody } from './models/CreateListingRequestBody';
export type { ERC1155CollectionItem } from './models/ERC1155CollectionItem';
export type { ERC1155Item } from './models/ERC1155Item';
Expand All @@ -41,6 +42,7 @@ export type { Item } from './models/Item';
export type { ListBidsResult } from './models/ListBidsResult';
export type { ListCollectionBidsResult } from './models/ListCollectionBidsResult';
export type { ListTraitBidsResult } from './models/ListTraitBidsResult';
export type { ListMetadataBidsResult } from './models/ListMetadataBidsResult';
export type { ListingResult } from './models/ListingResult';
export type { ListListingsResult } from './models/ListListingsResult';
export type { ListTradeResult } from './models/ListTradeResult';
Expand All @@ -57,6 +59,7 @@ export type { Trade } from './models/Trade';
export type { TradeBlockchainMetadata } from './models/TradeBlockchainMetadata';
export type { TradeResult } from './models/TradeResult';
export type { TraitBidResult } from './models/TraitBidResult';
export type { MetadataBidResult } from './models/MetadataBidResult';
export type { TraitFilter } from './models/TraitFilter';
export type { UnfulfillableOrder } from './models/UnfulfillableOrder';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

import type { AssetCollectionItem } from './AssetCollectionItem';
import type { ERC20Item } from './ERC20Item';
import type { Fee } from './Fee';
import type { ProtocolData } from './ProtocolData';

export type CreateMetadataBidRequestBody = {
account_address: string;
order_hash: string;
/**
* Buy item for metadata bid should either be ERC721 or ERC1155 collection item
*/
buy: Array<AssetCollectionItem>;
/**
* Buy fees should only include maker marketplace fees and should be no more than two entries as more entires will incur more gas. It is best practice to have this as few as possible.
*/
fees: Array<Fee>;
/**
* Time after which the Order is considered expired
*/
end_at: string;
protocol_data: ProtocolData;
/**
* A random value added to the create Order request
*/
salt: string;
/**
* Sell item for metadata bid should be an ERC20 item
*/
sell: Array<ERC20Item>;
/**
* Digital signature generated by the user for the specific Order
*/
signature: string;
/**
* Time after which Order is considered active
*/
start_at: string;
/**
* The metadata_id (stack_id) that NFTs must have to fulfil this bid
*/
metadata_id: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

import type { Order } from './Order';
import type { Page } from './Page';

export type ListMetadataBidsResult = {
page: Page;
result: Array<Order>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

import type { Order } from './Order';

export type MetadataBidResult = {
result: Order;
};
5 changes: 5 additions & 0 deletions packages/orderbook/src/openapi/sdk/models/Order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ export type Order = {
* Trait criteria for trait bids when returned by the API
*/
trait_criteria?: Array<TraitFilter>;
/**
* Metadata ID (stack ID) for metadata bids when returned by the API
*/
metadata_id?: string;
};

export namespace Order {
Expand All @@ -68,6 +72,7 @@ export namespace Order {
BID = 'BID',
COLLECTION_BID = 'COLLECTION_BID',
TRAIT_BID = 'TRAIT_BID',
METADATA_BID = 'METADATA_BID',
}


Expand Down
Loading
Loading