Before a user can send a transaction to pre-sign an order, they need to have tokens and appropriate approvals. This is explained in more detail in Preparing for transactions .
Preparing fees
To create an ERC721 order that will be integrated into our system, it's important that the order matches the fees that were defined by the collection's owner. To get the collection fees settings please check Get collection data .
First, we will define two helper functions to help us with arithmetics. Since Bignumbers are integers, we need to make sure we don't lose precision when computing percentages.
Copy const FEE_PERCENTAGE_PRECISION = 6
const _scalePrecision = (value : BigNumberish ) : BigNumber => {
if ( typeof value === "number" ) {
return BigNumber .from (value * 10 ** FEE_PERCENTAGE_PRECISION )
} else {
return BigNumber .from (value) .mul ( 10 ** FEE_PERCENTAGE_PRECISION )
}
}
export const calculateAmountWithoutFees = (
priceWithFees : BigNumberish ,
feePercentage : BigNumberish
) : BigNumber => {
const scaledPercentage = _scalePrecision (feePercentage) .div ( 100 )
return _scalePrecision (priceWithFees) .div (
_scalePrecision ( 1 ) .add (scaledPercentage)
)
}
const calculateFeesAmount = (
price : BigNumberish ,
percentage : number
) : string => {
const intFeePercentage = percentage * 10 ** FEE_PERCENTAGE_PRECISION
const feeAmount = BigNumber .from (intFeePercentage)
.mul (price)
.div ( 100 )
.div ( 10 ** FEE_PERCENTAGE_PRECISION )
.toString ()
return feeAmount .toString ()
}
We can then use those helpers to prepare our order fees:
Copy const sumOfFeesPercentages = collection . collectionFees .reduce (
(sum , fee) => sum + fee .feePercentage ,
0
)
const amountWithoutFees = calculateAmountWithoutFees (
userChosenPrice ,
sumOfFeesPercentages
)
const orderFees = collection . collectionFees .map ((fee) => {
return {
amount : calculateAmountWithoutFees (amountWithoutFees , fee .feePercentage) ,
recipient : fee .recipientAddress
}
})
Assembling the order arguments
We can use the user's ERC721 data and our marketplace ERC20 config to initialize two corresponding objects:
Copy
const erc721Data : UserFacingERC721AssetDataSerializedV4 = {
tokenAddress : userAsset .contractAddress ,
tokenId : userAsset .tokenId ,
type : 'ERC721'
}
const erc20Data : UserFacingERC20AssetDataSerializedV4 = {
tokenAddress : '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' ,
amount : amountWithoutFees .toString () ,
type : 'ERC20'
}
We also need an expiry date for the order:
Copy const tomorrow = new Date ()
tomorrow .setDate ( tomorrow .getDate () + 1 )
Sending the transaction
At this point, we have everything to call the NFT swap SDK function which will send the transaction:
Copy return nftSwapSdk .buildNftAndErc20Order (
erc721Data ,
erc20Data ,
'sell' ,
userAddres ,
{
fees : orderFees ,
expiry : tomorrow ,
taker : ethers . constants .AddressZero
}
)
Last updated 2 months ago