-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #47 from trustenterprises/feature/batch-nfts-transfer
Batch NFT transfer
- Loading branch information
Showing
7 changed files
with
388 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import HashgraphClient from "app/hashgraph/client" | ||
|
||
const client = new HashgraphClient() | ||
|
||
// NFT is reused for different tests | ||
let nft | ||
|
||
// Account of dummy user claiming NFTs from treasury | ||
let dummyAccount | ||
|
||
// Reused please | ||
const TOKENS_SUPPLY = 200 | ||
|
||
// Utility for sending batch. | ||
const sendBatch = async amount => { | ||
if (!dummyAccount || !nft) { | ||
throw Error('NFT or account state not initialised.') | ||
} | ||
|
||
return await client.multipleNftTransfer({ | ||
token_id: nft.token_id, | ||
receiver_id: dummyAccount.accountId, | ||
serials: Array(amount).fill(1).map((e, i) => i + e) | ||
}) | ||
} | ||
|
||
const sendBatchUsingMirrornode = async (amount = 30) => { | ||
if (!dummyAccount || !nft) { | ||
throw Error('NFT or account state not initialised.') | ||
} | ||
|
||
return await client.batchTransferNft({ | ||
token_id: nft.token_id, | ||
// token_id: '0.0.48905114', | ||
receiver_id: dummyAccount.accountId, | ||
amount | ||
}) | ||
|
||
} | ||
|
||
const mintMoarNfts = async (amount = 10) => { | ||
const mintNfts = { | ||
amount, | ||
token_id: nft.token_id, | ||
cid: 'xxx' | ||
} | ||
|
||
return await client.mintNonFungibleToken(mintNfts) | ||
} | ||
|
||
// This will be generated uniquely per NFT (low-priority test) | ||
|
||
test("This test will create an NFT and mint all tokens", async () => { | ||
|
||
const passTokenData = { | ||
supply: TOKENS_SUPPLY, | ||
collection_name: 'example nft', | ||
symbol: 'te-e2e-nft' | ||
} | ||
|
||
nft = await client.createNonFungibleToken(passTokenData) | ||
|
||
const mint = await mintMoarNfts(5) | ||
|
||
expect(mint.token_id).toBe(nft.token_id) | ||
|
||
console.log(mint) | ||
|
||
}, 30000) | ||
|
||
// Normally this would hit an end point for an integration test | ||
test("This will create an account and attempt to send a multiple transfer to account", async () => { | ||
|
||
dummyAccount = await client.createAccount() | ||
|
||
// This should fail as we have only minted 5 | ||
const badSend = await sendBatch(6) | ||
|
||
expect(badSend.total).toBe(0) | ||
expect(badSend.error).toBeTruthy() | ||
|
||
const goodSend = await sendBatch(5) | ||
|
||
expect(goodSend.total).toBe(5) | ||
expect(goodSend.error).toBeFalsy() | ||
|
||
}, 20000) | ||
|
||
|
||
test("Send a big'ol batch of NFTs!", async () => { | ||
|
||
const send = await sendBatchUsingMirrornode() | ||
|
||
expect(send.error[0]).toBe(`The treasury does not hold the amount of NFTs of id ${nft.token_id} to do the required batch transfer`) | ||
|
||
// Due to mirrornode limitations we can't test this in real time | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// await mintMoarNfts() | ||
// | ||
// const sendMoar = await sendBatchUsingMirrornode(38) | ||
// | ||
// console.log(sendMoar) | ||
// expect(sendMoar.results.length).toBeTruthy() | ||
|
||
}, 20000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Response from "app/response" | ||
import transferNftRequest from "app/validators/transferNftRequest" | ||
import batchTransferNftRequest from "../validators/batchTransferNftRequest" | ||
|
||
async function BatchTransferNftHandler(req, res) { | ||
const validationErrors = batchTransferNftRequest(req.body) | ||
|
||
if (validationErrors) { | ||
return Response.unprocessibleEntity(res, validationErrors) | ||
} | ||
|
||
const { receiver_id, token_id, amount } = req.body | ||
|
||
const batchTransferPayload = { | ||
receiver_id, | ||
token_id, | ||
amount | ||
} | ||
|
||
const { hashgraphClient } = req.context | ||
const sendResponse = await hashgraphClient.batchTransferNft( | ||
batchTransferPayload | ||
) | ||
|
||
if (sendResponse.error) { | ||
return Response.unprocessibleEntity(res, sendResponse.error) | ||
} | ||
|
||
if (sendResponse) { | ||
return Response.json(res, sendResponse) | ||
} | ||
|
||
return Response.badRequest(res) | ||
} | ||
|
||
export default BatchTransferNftHandler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const BATCH_LIMITS = { | ||
nftTransfers: 10 | ||
} | ||
|
||
/** | ||
* Create an array of cycles of NFT transfers based on an amount and a max limit. | ||
* | ||
* @param amount | ||
* @returns {any[]} | ||
*/ | ||
function nftTransfer(amount) { | ||
// mod rem diff | ||
const rem = amount % BATCH_LIMITS.nftTransfers | ||
|
||
// Basal cycle for batch, as a whole number | ||
const max = (amount - rem) / BATCH_LIMITS.nftTransfers | ||
|
||
// When rem is falsely, remove -- more simple then if | ||
const cycle = Array(max) | ||
.fill(BATCH_LIMITS.nftTransfers) | ||
.concat(rem) | ||
.filter(e => e) | ||
|
||
// For readability | ||
return cycle | ||
} | ||
|
||
export default { | ||
nftTransfer | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.