A JavaScript library for element.market: buy, sell, make offer on any NFTs. With Element.js, you can easily build yourown NFT marketplace. Trade ERC721 or ERC1155 items. You don't have to deploy your own smart contracts or off-chain orderbooks.
This is the JavaScript SDK for element.market, a marketplace for NFTs.
It allows developers to access the official orderbook, filter it, create buy orders (offers), create sell orders (listings), and complete trades programmatically.
You get started by requesting an API key and instantiating your own sdk. Then you can create orders off-chain or fulfill orders on-chain.
Install element-js-sdk, in your project, run:
npm install --save element-js-sdk
If your project run in browser environment, you need install crypto-browserify, stream-browserify, buffer, and config webpack.config.js:
#install crypto-browserify, stream-browserify, buffer
npm install --save crypto-browserify
npm install --save stream-browserify
npm install --save buffer
#config webpack.config.js
module.exports = function (webpackEnv) {
...
return {
...
resolve: {
...
fallback: {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
buffer: require.resolve('buffer/'),
},
},
...
plugins: [
...
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
}
};
To get started, first request an API key here.
Then, create a new ElementJS client, using your ethers web3Provider or signer:
import { ElementSDK, Network } from 'element-js-sdk'
import { ethers } from 'ethers'
// In Browser
// https://docs.ethers.io/v5/getting-started/#getting-started--connecting-rpc
// A Web3Provider wraps a standard Web3 provider, which is what MetaMask injects as window.ethereum into each page.
const signerOrProvider = new ethers.providers.Web3Provider(window.ethereum);
// In Node.js
// https://docs.ethers.io/v5/api/signer/
const jsonRpcProvider = new ethers.providers.JsonRpcProvider(rpcUrl);
const signerOrProvider = new ethers.Wallet(privateKey, jsonRpcProvider);
const sdk = new ElementSDK({
// Supported networks: Network.ETH, Network.BSC, Network.Polygon, Network.Avalanche
networkName: Network.ETH,
isTestnet: false,
apiKey: YOUR_API_KEY,
signer: signerOrProvider
});
Note that the operations: sign orders
erc20.approve
erc721.setApprovalForAll
erc1155.setApprovalForAll
is done inside this sdk.
To sell a bulk of ERC-721 assets, call makeERC721SellOrders
.
const r = await sdk.makeERC721SellOrders({
items: [{
erc721TokenAddress: tokenAddress1,
erc721TokenId: tokenId1,
paymentTokenAmount: '1100000000000000000'
}, {
erc721TokenAddress: tokenAddress2,
erc721TokenId: tokenId2,
paymentTokenAmount: 1200000000000000000
}, {
erc721TokenAddress: tokenAddress3,
erc721TokenId: tokenId3,
paymentTokenAmount: 1.3e18
}]
});
console.log("succeedList, ", r.succeedList);
console.log("failedList, ", r.failedList);
To sell an asset, call makeSellOrder
.
const order = await sdk.makeSellOrder({
assetAddress: tokenAddress,
assetId: tokenId,
paymentTokenAmount: '2000000000000000000'
});
Note that the default assets is ERC-721. For ERC-1155 assets, you should set assetSchema
to AssetSchema.ERC1155
and pass a quantity
:
const order = await sdk.makeSellOrder({
// ...
assetSchema: AssetSchema.ERC1155,
quantity: 10000,
});
The default payment token is native token(e.g. ETH on ether chain), if use an ERC20 token, you can set paymentToken
to an ERC20 token address.
const order = await sdk.makeSellOrder({
// ...
paymentToken: paymentToken
});
The default expiration time is 7 days, you can set expirationTime
to specify another expiration time.
// Note that we convert from the JavaScript timestamp (milliseconds to seconds):
const expirationTime = Math.round(Date.now() / 1000 + 60 * 60 * 24);
const order = await sdk.makeSellOrder({
// ...
expirationTime: expirationTime
});
You can make offers on an asset:
const order = await sdk.makeBuyOrder({
assetId: assetId,
assetAddress: assetAddress,
paymentTokenAmount: '3000000000000000000'
});
Note that make offers aren't supported with the native token, so you have to use an ERC20 token, or wrapped native token if none is specified.
You can make offers for any NFT from a specific collection.
const order = await sdk.makeBuyOrder({
// Note that don't specify the `assetId`
assetAddress: assetAddress,
// Value of the order, in units of the payment token (or wrapped native token if none is specified).
paymentTokenAmount: '3000000000000000000'
});
To fetching orders of the element market, call queryOrders
:
import { ElementSDK } from 'element-js-sdk'
const orders = await sdk.queryOrders({
asset_contract_address: assetAddress,
token_ids: [assetId]
});
The api documentation is here, and the example is here.
To buy a bulk of NFTs, call batchBuyWithETH
:
const orders = await sdk.queryOrders({ ... });
const transaction = await sdk.batchBuyWithETH({
orders: orders,
quantities: [1, 100] // Optional. The default quantity is 1.
});
console.log("tx.hash: ", transaction.hash);
// wait for transaction completed.
const receipt = await transaction.wait();
console.log("completed,receipt: ", receipt);
// getBoughtAssets
const assets = sdk.getBoughtAssets(receipt)
console.log('assets: ', assets)
To buy or sell a NFT, call fillOrder
:
const orders = await sdk.queryOrders({ ... });
const order = orders[0]; // select an order
const transaction = await sdk.fillOrder({
order: order
});
console.log("tx.hash: ", transaction.hash);
const receipt = await transaction.wait();
console.log("completed,receipt: ", receipt);
Note that if the order is a Collection-Based Offer, you need specify the assetId
:
const transaction = await sdk.fillOrder({
order: order,
assetId: assetId
});
const receipt = await transaction.wait();
console.log("completed.");
For the ERC-1155 asset order, the default quantity
is 1. You can also set the quantity
if needed. To do that, it's just call like below:
const quantity = '5000';
const transaction = await sdk.fillOrder({
order: order,
quantity: quantity
});
const receipt = await transaction.wait();
console.log("completed");
To cancel an order, call cancelOrder
.
const orders = await sdk.queryOrders({ ... });
const order = orders[0]; // select an order
const transaction = await sdk.cancelOrder({
order: order
});
const receipt = await transaction.wait()
console.log("completed")
To cancel a bulk of orders, call cancelOrders
:
const orders = await sdk.queryOrders({ ... });
const r = await sdk.cancelOrders({
orders: orders
})
for (const info of r.succeedTransactions) {
console.log('tx.hash: ', info.transaction.hash)
const receipt = await info.transaction.wait()
console.log('completed, receipt: ', receipt)
console.log('orders: ', info.orders)
}
To cancel all orders of the signer, call cancelAllOrdersForSigner
:
const transaction = await sdk.cancelAllOrdersForSigner({
// Supported Standard: Standard.ElementEx, Standard.Seaport, Standard.LooksRare
standard: Standard.ElementEx
});
const receipt = await transaction.wait()
console.log("completed")
If you want to get TradeData
, call encodeTradeData
.
const orders = await sdk.queryOrders({ ... });
const tradeData = await sdk.encodeTradeData({
orders: orders,
taker: accountAddress
});
console.log("tradeData: ", tradeData);
// sendTransaction
const signer = await getEthersSigner()
const transaction = await signer.sendTransaction({
to: tradeData.toContract,
data: tradeData.data,
value: tradeData.payableValue
})
// wait for transaction completed.
const receipt = await transaction.wait();
console.log("completed,receipt: ", receipt);
// getBoughtAssets
const assets = sdk.getBoughtAssets(receipt)
console.log('assets: ', assets)
Note that the taker
is optional, and the default taker
is sdk.signer.
Interested in purchasing for scheduling future orders, or private auctions, element.js can help with that.
You can set maxFeePerGas
and maxPriorityFeePerGas
(EIP-1559), or just set gasPrice
.
const transaction = await sdk.fillOrder({
order: order,
maxFeePerGas: 21e9, // string or number.
maxPriorityFeePerGas: 2e9 // string or number.
});
const receipt = await transaction.wait();
console.log("completed");
const transaction = await sdk.fillOrder({
order: order,
gasPrice: '30000000000', // string or number.
});
const receipt = await transaction.wait();
console.log("completed");
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:
const order = await sdk.makeSellOrder({
assetId: assetId,
assetAddress: assetAddress,
startTokenAmount: 3e19,
listingTime: Math.round(Date.now() / 1000 + 60 * 60 * 24) // One day from now
});
Now you can make offers and listings that can only be filled by an address of your choosing. This allows you to negotiate a price in some channel and sell for your chosen price on element.market, without having to trust that the counterparty will abide by your terms!
Here's an example of listing a Decentraland parcel for 3 ETH with a specific buyer address allowed to take it. No more needing to worry about whether they'll give you enough back!
// Address allowed to buy from you
const takerAddress = "0x123..."
const order = await sdk.makeSellOrder({
takerAddress: takerAddress,
assetId: assetId,
assetAddress: assetAddress,
startTokenAmount: 3e19
});
The examples are here.
The documentation for developer is available here.
If you need extra help, support is free! You can email us [email protected]
.