# Marketplace SDK instructions ## Intro The marketplace supports a number of different strategies for selling hypercerts, one of which is the fractional sale. This strategy allows you to sell of a portion of your hypercert (for example: anywhere between 10 and a 100 units), for a minimum price per unit. :::warning :warning: functionality available from version `hypercerts-org/marketplace-sdk@0.0.19` ::: ## VoiceDeck According to the [designs by VoiceDeck](https://www.figma.com/file/GyA5raT78DnEbungrDTC8Y/VoiceDeck?type=design&node-id=1491-77197&mode=design&t=zsrsvauxZVx3v8sk-4) we will provide some steps that could accomplish the desired functionality. Keep in mind that all prices have to be in WEI, which we won't do here for the sake of clarity. 1. Mint a hypercert 2. Register the hypercert for sale - Example calculation: the hypercert consists of 2000 units - The project needs $1000 - The price per unit will therefore be `const pricePerUnit = 1000 / 2000` ($0.50) - The entire hypercert will be sold, so `const minUnitsToKeep = 0` - You want people to donate at least $1 per donation. So `const minUnitAmount = 2` - People should be able to fund the entire project at once, so `const maxUnitAmount = 2000` 3. Some example math for funding a project - If a user wants to donate $5, he would have to buy 10 units, against the specified minimum price of $0.50 per unit. 4. Listing all donators for a project: - Using the hypercerts SDK (not the marketplace SDK) you can retreive a list of all fractions. Every fraction represents a donation. The owners of these fractions are the people that have donated. The combined size of all fractions for a single owner tells you the amount of money that that user has donated. ## Putting up a hypercert for sale - example code ```typescript= import { HypercertExchangeClient } from "@hypercerts-org/marketplace-sdk"; import { parseEther } from "viem import { waitForTransactionReceipt } from "viem/actions"; const hypercertExchangeClient = new HypercertExchangeClient( chainId, provider, signer ); const { maker, isCollectionApproved, isTransferManagerApproved } = await hypercertExchangeClient.createFractionalSaleMakerAsk({ startTime: Math.floor(Date.now() / 1000), // Use it to create an order that will be valid in the future (Optional, Default to now) endTime: Math.floor(Date.now() / 1000) + 86400, // If you use a timestamp in ms, the function will revert price: parseEther("1"), // Be careful to use a price in wei, this example is for 1 ETH itemIds: [tokenId.toString()], // Token id of the NFT(s) you want to sell, add several ids to create a bundle minUnitAmount: 10, // Minimum amount of units to sell per sale maxUnitAmount: 100, // Maximum amount of units to sell per sale minUnitsToKeep: 50, // Minimum amount of units to keep after the sale sellLeftoverFraction: true, // If you want to sell the leftover fraction currency: '0xABC' // Optional, address of the currency used for the sale. Defaults to WETH for now (0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9). }); // Grant the TransferManager the right the transfer assets on behalf od the LooksRareProtocol if (!isTransferManagerApproved) { const tx = await hypercertExchangeClient .grantTransferManagerApproval() .call(); await waitForTransactionReceipt(walletClientData, { hash: tx.hash as `0x${string}`, }); } // Approve the collection items to be transferred by the TransferManager if (!isCollectionApproved) { const tx = await hypercertExchangeClient.approveAllCollectionItems( maker.collection ); await waitForTransactionReceipt(walletClientData, { hash: tx.hash as `0x${string}`, }); } // Sign your maker order const signature = await hypercertExchangeClient.signMakerOrder(maker); await hypercertExchangeClient.registerOrder({ order, signature, }); ``` ## Fetching open MakerAsks from the marketplace API - example code ```typescript= const { data: orders } = await hypercertExchangeClient.api.fetchOrdersByHypercertId({ hypercertId, chainId, }); ``` Which will give a response with the following properties ```json [ { "id":"9027a798-cb05-49ab-8ec9-0f45a1a9d6f1", "createdAt":"2024-02-11T19:17:02.305689+00:00", "quoteType":1, "globalNonce":"0", "orderNonce":"45", // Means it's a fractional sale "strategyId":10, "collectionType":2, "collection":"0xa16DFb32Eb140a6f3F2AC68f41dAd8c7e83C4941", "currency":"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9", "signer":"0x59266D85D94666D037C1e32dAa8FaC9E95CdaFEf", "startTime":1707679014, "endTime":1707765414, // Minimum price per unit "price":"10000", "signature":"0x4c96b0f09909e4d5059baea4d18b6a9d53cace96d700be1672e440db1ffac38c072fc1f18e8d59be91df76e0d55cb0e91e6bfc02bb9143cc16cdf62918299a981b", "additionalParameters":"0x0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000", "chainId":11155111, "subsetNonce":0, "itemIds":[ // This is the ID of the fraction being sold. "34708801425935723273264209958040357568513" ], "amounts":[ 1 ] } ] ``` ## Buying a part of a hypercert - example code ```typescript= import { HypercertExchangeClient } from "@hypercerts-org/marketplace-sdk"; import { parseEther } from "viem"; import { waitForTransactionReceipt } from "viem/actions"; const buyFractionalSale = ( // Chain that the sale takes place on chainId: number, // Address of the buyer address: string, // Order retreived from API order: Order, // Price to pay per unit in WEI, should be >= the requested price pricePerUnitToPay: BigNumberish, // Number of units to buy, should be minUnits < unitAmount < maxUnits unitAmount: BigNumberish ) => { const hypercertExchangeClient = new HypercertExchangeClient( chainId, provider, signer ); // Create taker bid const takerOrder = hypercertExchangeClient.createFractionalSaleTakerBid( order, address, unitAmount, pricePerUnit ); try { // Set approval for exchange to spend funds const totalPrice = BigInt(order.price) * BigInt(unitAmount); const approveTx = await hypercertExchangeClient.approveErc20( order.currency, // Be sure to set the allowance for the correct currency totalPrice ); await waitForTransactionReceipt(walletClientData, { hash: approveTx.hash as `0x${string}`, }); } catch (e) { console.error(e); } try { // Perform the trade const { call } = hypercertExchangeClient.executeOrder( order, takerOrder, order.signature ); const tx = await call(); await waitForTransactionReceipt(walletClientData, { hash: tx.hash as `0x${string}`, }); } catch (e) { console.error(e); } }; ```