Skip to content

Commit

Permalink
rename:
Browse files Browse the repository at this point in the history
 - `createSellOrder` to `createListing`
 - `createBuyOrder` to `createOffer`
and create deprecated aliases for backward compat
misc cleanup and fixes:
 - add more typedocs
 - improve type for Asset when token id or standard is required
  • Loading branch information
ryanio committed Oct 13, 2023
1 parent 5676158 commit e91b3d9
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 64 deletions.
31 changes: 18 additions & 13 deletions developerDocs/advanced-use-cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ Interested in purchasing for users server-side or with a bot, scheduling future

### Scheduling Future Listings

You can create sell orders that aren't fulfillable until a future date. Just pass in a `listingTime` (a UTC timestamp in seconds) to your SDK instance:
You can create listings that aren't fulfillable until a future date. Just pass in a `listingTime` (a UTC timestamp in seconds) to your SDK instance:

```typescript
const order = await openseaSDK.createSellOrder({
tokenAddress,
tokenId,
const listingTime = Math.round(Date.now() / 1000 + 60 * 60 * 24); // One day from now
const order = await openseaSDK.createListing({
asset: { tokenAddress, tokenId },
accountAddress,
startAmount: 1,
listingTime: Math.round(Date.now() / 1000 + 60 * 60 * 24), // One day from now
listingTime,
});
```

Expand All @@ -53,13 +53,15 @@ This will automatically approve the assets for trading and confirm the transacti
Here's an example of listing the Genesis CryptoKitty for $100! No more needing to worry about the exchange rate:

```typescript
// CryptoKitties
const tokenAddress = "0x06012c8cf97bead5deae237070f9587f8e7a266d";
// Token address for the DAI stablecoin, which is pegged to $1 USD
const paymentTokenAddress = "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359";
const paymentTokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F";

// The units for `startAmount` and `endAmount` are now in DAI, so $100 USD
const order = await openseaSDK.createSellOrder({
tokenAddress: "0x06012c8cf97bead5deae237070f9587f8e7a266d", // CryptoKitties
tokenId: "1", // Token ID
const order = await openseaSDK.createListing({
tokenAddress,
tokenId: "1",
accountAddress: OWNERS_WALLET_ADDRESS,
startAmount: 100,
paymentTokenAddress,
Expand Down Expand Up @@ -87,11 +89,14 @@ Here's an example of listing a Decentraland parcel for 10 ETH with a specific bu
```typescript
// Address allowed to buy from you
const buyerAddress = "0x123...";
// Decentraland
const tokenAddress = "0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d";
const tokenId =
"115792089237316195423570985008687907832853042650384256231655107562007036952461";

const listing = await openseaSDK.createSellOrder({
tokenAddress: "0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d", // Decentraland
tokenId:
"115792089237316195423570985008687907832853042650384256231655107562007036952461", // Token ID
const listing = await openseaSDK.createListing({
tokenAddress,
tokenId,
accountAddress: OWNERS_WALLET_ADDRESS,
startAmount: 10,
buyerAddress,
Expand Down
26 changes: 14 additions & 12 deletions developerDocs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ Also see methods `getNFTsByCollection`, `getNFTsByContract`, and `getNFTsByAccou
import { TokenStandard } from "opensea-js/lib/types";

const asset = {
tokenAddress: "0x06012c8cf97bead5deae237070f9587f8e7a266d", // CryptoKitties
// CryptoKitties
tokenAddress: "0x06012c8cf97bead5deae237070f9587f8e7a266d",
tokenId: "1",
tokenStandard: TokenStandard.ERC721,
};
Expand All @@ -51,16 +52,16 @@ const ownsKitty = balance.gt(0);
const { tokenId, tokenAddress } = YOUR_ASSET;
// The offerer's wallet address:
const accountAddress = "0x1234...";
// Value of the offer, in units of the payment token (or wrapped ETH if none is specified)
const startAmount = 1.2;

const offer = await openseaSDK.createBuyOrder({
const offer = await openseaSDK.createOffer({
asset: {
tokenId,
tokenAddress,
tokenStandard, // TokenStandard. If omitted, defaults to 'ERC721'. Other options include 'ERC20' and 'ERC1155'
},
accountAddress,
// Value of the offer, in units of the payment token (or wrapped ETH if none is specified):
startAmount: 1.2,
startAmount,
});
```

Expand All @@ -72,14 +73,14 @@ Note: The total value of buy orders must not exceed 1000x wallet balance.

### Making Listings / Selling Items

To sell an asset, call `createSellOrder`:
To sell an asset, call `createListing`:

```typescript
// Expire this auction one day from now.
// Note that we convert from the JavaScript timestamp (milliseconds):
// Note that we convert from the JavaScript timestamp (milliseconds) to seconds:
const expirationTime = Math.round(Date.now() / 1000 + 60 * 60 * 24);

const listing = await openseaSDK.createSellOrder({
const listing = await openseaSDK.createListing({
asset: {
tokenId,
tokenAddress,
Expand All @@ -103,10 +104,11 @@ To create an English Auction set `englishAuction` to `true`:
```typescript
// Create an auction to receive Wrapped Ether (WETH). See note below.
const paymentTokenAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
const englishAuction = true;
// The minimum amount to start the auction at, in normal units (e.g. ETH)
const startAmount = 0;

const startAmount = 0; // The minimum amount to sell for, in normal units (e.g. ETH)

const auction = await openseaSDK.createSellOrder({
const auction = await openseaSDK.createListing({
asset: {
tokenId,
tokenAddress,
Expand All @@ -115,7 +117,7 @@ const auction = await openseaSDK.createSellOrder({
startAmount,
expirationTime,
paymentTokenAddress,
englishAuction: true,
englishAuction,
});
```

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"eslint:fix": "npm run eslint:check -- --fix",
"postinstall": "husky install || exit 0",
"lint": "concurrently \"npm run check-types\" \"npm run prettier:check\" \"npm run eslint:check\"",
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
"prepare": "npm run build",
"prettier:check": "prettier --check .",
"prettier:check:package.json": "prettier-package-json --list-different",
Expand Down
85 changes: 59 additions & 26 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
ERC721__factory,
} from "./typechain/contracts";
import {
Asset,
ComputedFees,
EventData,
EventType,
Expand All @@ -49,6 +48,8 @@ import {
OrderSide,
TokenStandard,
OpenSeaFungibleToken,
AssetWithTokenStandard,
AssetWithTokenId,
} from "./types";
import {
delay,
Expand Down Expand Up @@ -319,9 +320,21 @@ export class OpenSeaSDK {
}

/**
* Create a buy order to make an offer on an asset.
* Alias, deprecated, please update to using {@link createListing}.
* This method will be removed in the next major version of opensea-js.
*/
createSellOrder = this.createListing;

/**
* Alias, deprecated, please update to using {@link createOffer}.
* This method will be removed in the next major version of opensea-js.
*/
createBuyOrder = this.createOffer;

/**
* Create and submit an offer on an asset.
* @param options
* @param options.asset The asset to trade
* @param options.asset The asset to trade. tokenAddress and tokenId must be defined.
* @param options.accountAddress Address of the wallet making the buy order
* @param options.startAmount Value of the offer in units, not base units e.g. not wei, of the payment token (or WETH if no payment token address specified)
* @param options.quantity The number of assets to bid for (if fungible or semi-fungible). Defaults to 1.
Expand All @@ -336,17 +349,17 @@ export class OpenSeaSDK {
* @throws Error if the startAmount is not greater than 0.
* @throws Error if paymentTokenAddress is not WETH on anything other than Ethereum mainnet.
*/
public async createBuyOrder({
public async createOffer({
asset,
accountAddress,
startAmount,
quantity = 1,
domain,
salt,
expirationTime,
paymentTokenAddress,
paymentTokenAddress = getWETHAddress(this.chain),
}: {
asset: Asset;
asset: AssetWithTokenId;
accountAddress: string;
startAmount: BigNumberish;
quantity?: BigNumberish;
Expand All @@ -357,11 +370,6 @@ export class OpenSeaSDK {
}): Promise<OrderV2> {
await this._requireAccountIsAvailable(accountAddress);

if (!asset.tokenId) {
throw new Error("Asset must have a tokenId");
}
paymentTokenAddress = paymentTokenAddress ?? getWETHAddress(this.chain);

const { nft } = await this.api.getNFT(
this.chain,
asset.tokenAddress,
Expand Down Expand Up @@ -422,9 +430,9 @@ export class OpenSeaSDK {
}

/**
* Create a sell order to make a listing for a asset.
* Create and submit a listing for an asset.
* @param options
* @param options.asset The asset to trade
* @param options.asset The asset to trade. tokenAddress and tokenId must be defined.
* @param options.accountAddress Address of the wallet making the sell order
* @param options.startAmount Value of the listing at the start of the auction in units, not base units e.g. not wei, of the payment token (or WETH if no payment token address specified)
* @param options.endAmount Value of the listing at the end of the auction. If specified, price will change linearly between startAmount and endAmount as time progresses.
Expand All @@ -443,7 +451,7 @@ export class OpenSeaSDK {
* @throws Error if the startAmount is not greater than 0.
* @throws Error if paymentTokenAddress is not WETH on anything other than Ethereum mainnet.
*/
public async createSellOrder({
public async createListing({
asset,
accountAddress,
startAmount,
Expand All @@ -457,7 +465,7 @@ export class OpenSeaSDK {
buyerAddress,
englishAuction,
}: {
asset: Asset;
asset: AssetWithTokenId;
accountAddress: string;
startAmount: BigNumberish;
endAmount?: BigNumberish;
Expand All @@ -472,10 +480,6 @@ export class OpenSeaSDK {
}): Promise<OrderV2> {
await this._requireAccountIsAvailable(accountAddress);

if (!asset.tokenId) {
throw new Error("Asset must have a tokenId");
}

const { nft } = await this.api.getNFT(
this.chain,
asset.tokenAddress,
Expand Down Expand Up @@ -551,7 +555,7 @@ export class OpenSeaSDK {
}

/**
* Create a offer (buy order) for a collection.
* Create and submit a collection offer.
* @param options
* @param options.collectionSlug Identifier for the collection.
* @param options.accountAddress Address of the wallet making the offer.
Expand Down Expand Up @@ -645,6 +649,15 @@ export class OpenSeaSDK {
return this.api.postCollectionOffer(order, collectionSlug);
}

/**
* Fulfill a private order for a designated address.
* @param options
* @param options.order The order to fulfill
* @param options.accountAddress Address of the wallet taking the order.
* @param options.domain An optional domain to be hashed and included at the end of fulfillment calldata.
* This can be used for on-chain order attribution to assist with analytics.
* @returns Transaction hash of the order.
*/
private async fulfillPrivateOrder({
order,
accountAddress,
Expand Down Expand Up @@ -686,7 +699,7 @@ export class OpenSeaSDK {
}

/**
* Fulfill or "take" an order for an asset. The order can be either a buy or sell order.
* Fulfill an order for an asset. The order can be either a listing or an offer.
* @param options
* @param options.order The order to fulfill, a.k.a. "take"
* @param options.accountAddress Address of the wallet taking the offer.
Expand Down Expand Up @@ -765,19 +778,31 @@ export class OpenSeaSDK {
return transaction.hash;
}

/**
* Cancel orders onchain, preventing them from being fulfilled.
* @param options
* @param options.orders The orders to cancel
* @param options.accountAddress The account address cancelling the orders.
* @param options.domain An optional domain to be hashed and included at the end of fulfillment calldata.
* This can be used for on-chain order attribution to assist with analytics.
* @returns Transaction hash of the order.
*/
private async cancelSeaportOrders({
orders,
accountAddress,
domain,
protocolAddress,
protocolAddress = DEFAULT_SEAPORT_CONTRACT_ADDRESS,
}: {
orders: OrderComponents[];
accountAddress: string;
domain?: string;
protocolAddress?: string;
}): Promise<string> {
if (!protocolAddress) {
protocolAddress = DEFAULT_SEAPORT_CONTRACT_ADDRESS;
const checksummedProtocolAddress = ethers.utils.getAddress(protocolAddress);
if (checksummedProtocolAddress !== DEFAULT_SEAPORT_CONTRACT_ADDRESS) {
throw new Error(
`Only ${DEFAULT_SEAPORT_CONTRACT_ADDRESS} is currently supported for cancelling orders.`,
);
}

const transaction = await this.seaport_v1_5
Expand Down Expand Up @@ -872,7 +897,10 @@ export class OpenSeaSDK {
* @throws Error if the token standard does not support balanceOf.
*/
public async getBalance(
{ accountAddress, asset }: { accountAddress: string; asset: Asset },
{
accountAddress,
asset,
}: { accountAddress: string; asset: AssetWithTokenStandard },
retries = 1,
): Promise<BigNumber> {
try {
Expand Down Expand Up @@ -1084,7 +1112,6 @@ export class OpenSeaSDK {

/**
* Throws an error if an account is not available through the provider.
*
* @param accountAddress The account address to check is available.
*/
private async _requireAccountIsAvailable(accountAddress: string) {
Expand All @@ -1108,6 +1135,12 @@ export class OpenSeaSDK {
);
}

/**
* Wait for a transaction to confirm and log the success or failure.
* @param transactionHash The transaction hash to wait for.
* @param event The event type to log.
* @param description The description of the transaction.
*/
private async _confirmTransaction(
transactionHash: string,
event: EventType,
Expand Down
18 changes: 18 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,24 @@ export interface Asset {
decimals?: number;
}

/**
* Generic Blockchain Asset, with tokenId required.
* @category API Models
*/
export interface AssetWithTokenId extends Asset {
/** The asset's token ID */
tokenId: string;
}

/**
* Generic Blockchain Asset, with tokenStandard required.
* @category API Models
*/
export interface AssetWithTokenStandard extends Asset {
/** The token standard (e.g. "ERC721") for this asset */
tokenStandard: TokenStandard;
}

/**
* Annotated asset contract with OpenSea metadata
*/
Expand Down
2 changes: 1 addition & 1 deletion src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ export const hasErrorCode = (error: unknown): error is ErrorWithCode => {
return !!untypedError.code;
};

export const getAssetItemType = (tokenStandard?: TokenStandard) => {
export const getAssetItemType = (tokenStandard: TokenStandard) => {
switch (tokenStandard) {
case "ERC20":
return ItemType.ERC20;
Expand Down
Loading

0 comments on commit e91b3d9

Please sign in to comment.