Merge pull request #47 from Permissionless-Software-Foundation/ct-unstable

feat(nsfw): Detecting tokens marked NSFW in the mutable data
This commit is contained in:
Chris Troutner
2022-09-13 14:17:12 -07:00
committed by GitHub
2 changed files with 68 additions and 13 deletions
+54 -7
View File
@@ -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'
+14 -6
View File
@@ -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')
})