diff --git a/src/use-cases/offer/index.js b/src/use-cases/offer/index.js index 2593b5e..28bc96f 100644 --- a/src/use-cases/offer/index.js +++ b/src/use-cases/offer/index.js @@ -13,6 +13,9 @@ a partially signed transaction. */ +// Global npm libraries +const axios = require('axios') + // Local libraries const OfferEntity = require('../../entities/offer') const config = require('../../../config') @@ -39,6 +42,7 @@ class OfferUseCases { // Encapsulate dependencies this.config = config + this.axios = axios this.offerEntity = new OfferEntity() this.OfferModel = this.adapters.localdb.Offer @@ -84,12 +88,22 @@ class OfferUseCases { const offerEntity = this.offerEntity.validate(offerObj) console.log('offerEntity: ', offerEntity) + // Get data about the token. + const tokenId = offerEntity.tokenId + const tokenData = await this.adapters.wallet.bchWallet.getTokenData(tokenId) + console.log(`tokenData: ${JSON.stringify(tokenData, null, 2)}`) + // Generate a 'display category' for the token. This will allow the // front end UI to figure out how to display the token. - const displayCategory = await this.categorizeToken(offerEntity) + const displayCategory = await this.categorizeToken(offerEntity, tokenData) console.log('displayCategory: ', displayCategory) offerEntity.displayCategory = displayCategory + // Detect if user set the NSFW flag. + let nsfw = false + nsfw = await this.detectNsfw(tokenData) + offerEntity.nsfw = nsfw + // Add offer to the local database. const offerModel = new this.OfferModel(offerEntity) await offerModel.save() @@ -101,6 +115,39 @@ class OfferUseCases { } } + // By default this function returns false, to indicate the NFT is safe for work. + // If the user who created the token sets the nsfw property in the mutable data, + // this function will return true. + async detectNsfw (tokenData) { + try { + let nsfw = false + + const cid = tokenData.mutableData.substring(7) + + // Retrieve the mutable data from Filecoin/IPFS. + const url = `https://${cid}.ipfs.w3s.link/data.json` + const result = await axios.get(url) + const mutableData = result.data + console.log(`mutableData: ${JSON.stringify(mutableData, null, 2)}`) + + // Logical tests + const hasNsfw = !!mutableData.nsfw + const nsfwSetTrue = mutableData.nsfw === true + const nsfwStringTrue = mutableData.nsfw === 'true' + const nsfwDetected = hasNsfw && (nsfwSetTrue || nsfwStringTrue) + + if (nsfwDetected) { + console.log('NSFW flag set as true') + nsfw = true + } + + return nsfw + } catch (err) { + console.error('Error in detectNsfw(): ', err) + throw err + } + } + // Categorize the token for display purposes. This will categorize a token // into one of these categories: // - nft @@ -111,14 +158,14 @@ class OfferUseCases { // The first three are easy to categorize. The simple-nft is a fungible token // with a quantity of 1, decimals of 0, and no minting baton. Categorizing this // type of token is the main reason why this function exists. - async categorizeToken (offerData) { + async categorizeToken (offerData, tokenData) { try { - console.log(`categorizeToken(): ${JSON.stringify(offerData, null, 2)}`) + // console.log(`categorizeToken(): ${JSON.stringify(offerData, null, 2)}`) - const tokenId = offerData.tokenId - - const tokenData = await this.adapters.wallet.bchWallet.getTokenData(tokenId) - console.log(`tokenData: ${JSON.stringify(tokenData, null, 2)}`) + // const tokenId = offerData.tokenId + // + // const tokenData = await this.adapters.wallet.bchWallet.getTokenData(tokenId) + // console.log(`tokenData: ${JSON.stringify(tokenData, null, 2)}`) if (tokenData.genesisData.type === 65) { return 'nft' diff --git a/test/unit/use-cases/offer.use-case.unit.js b/test/unit/use-cases/offer.use-case.unit.js index 1bd405e..4911946 100644 --- a/test/unit/use-cases/offer.use-case.unit.js +++ b/test/unit/use-cases/offer.use-case.unit.js @@ -74,6 +74,9 @@ describe('#offer-use-case', () => { // Mock dependencies sandbox.stub(uut.adapters.bchjs.Blockchain, 'getTxOut').resolves(null) + sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves({}) + sandbox.stub(uut, 'categorizeToken').resolves('nft') + sandbox.stub(uut, 'detectNsfw').resolves(false) const result = await uut.createOffer(offerObj) // console.log('result: ', result) @@ -120,6 +123,8 @@ describe('#offer-use-case', () => { coinbase: false }) sandbox.stub(uut, 'categorizeToken').resolves('fungible') + sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves({}) + sandbox.stub(uut, 'detectNsfw').resolves(false) const result = await uut.createOffer(offerObj) // console.log('result: ', result) @@ -131,33 +136,36 @@ describe('#offer-use-case', () => { describe('#categorizeToken', () => { it('should categorize an NFT', async () => { // Mock dependencies - sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.nftTokenData01) + // sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.nftTokenData01) const offerData = mockData.nftOffer01 + const tokenData = mockData.nftTokenData01 - const result = await uut.categorizeToken(offerData) + const result = await uut.categorizeToken(offerData, tokenData) assert.equal(result, 'nft') }) it('should categorize a simple NFT', async () => { // Mock dependencies - sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.simpleNftTokenData01) + // sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.simpleNftTokenData01) const offerData = mockData.simpleNftOffer01 + const tokenData = mockData.simpleNftTokenData01 - const result = await uut.categorizeToken(offerData) + const result = await uut.categorizeToken(offerData, tokenData) assert.equal(result, 'simple-nft') }) it('should categorize a fungible token', async () => { // Mock dependencies - sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.fungibleTokenData01) + // sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.fungibleTokenData01) const offerData = mockData.fungibleOffer01 + const tokenData = mockData.fungibleTokenData01 - const result = await uut.categorizeToken(offerData) + const result = await uut.categorizeToken(offerData, tokenData) assert.equal(result, 'fungible') })