mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
complete NFTFactory class, add some tests
This commit is contained in:
parent
358ec3fdd1
commit
42eb819765
@ -5,10 +5,48 @@ import { AbiItem } from 'web3-utils'
|
|||||||
import defaultFactory721ABI from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
import defaultFactory721ABI from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||||
import { Logger, getFairGasPrice, generateDtName } from '../utils'
|
import { Logger, getFairGasPrice, generateDtName } from '../utils'
|
||||||
|
|
||||||
|
|
||||||
interface Template {
|
interface Template {
|
||||||
templateAddress: string
|
templateAddress: string
|
||||||
isActive: boolean
|
isActive: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TokenOrder {
|
||||||
|
tokenAddress: string
|
||||||
|
consumer: string
|
||||||
|
amount: number
|
||||||
|
serviceId: number
|
||||||
|
consumeFeeAddress: string
|
||||||
|
consumeFeeToken: string // address of the token marketplace wants to add fee on top
|
||||||
|
consumeFeeAmount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NFTCreateData {
|
||||||
|
name: string
|
||||||
|
symbol: string
|
||||||
|
templateIndex: number
|
||||||
|
baseURI: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ErcCreateData {
|
||||||
|
templateIndex: number
|
||||||
|
strings: string[]
|
||||||
|
addresses: string[]
|
||||||
|
uints:(string | number)[]
|
||||||
|
bytess: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PoolData {
|
||||||
|
addresses: string[]
|
||||||
|
ssParams: number[]
|
||||||
|
swapFees: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FixedData {
|
||||||
|
fixedPriceAddress: string
|
||||||
|
addresses: string[]
|
||||||
|
uints: number[]
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Provides an interface for NFT DataTokens
|
* Provides an interface for NFT DataTokens
|
||||||
*/
|
*/
|
||||||
@ -152,6 +190,24 @@ export class NFTFactory {
|
|||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if ERC20 is deployed from the factory
|
||||||
|
* @param {String} datatoken Datatoken address we want to check
|
||||||
|
* @return {Promise<Boolean>} return true if deployed from this factory
|
||||||
|
*/
|
||||||
|
public async checkDatatoken(datatoken: string): Promise<Boolean> {
|
||||||
|
const isDeployed = await this.factory721.methods.erc20List(datatoken).call()
|
||||||
|
return isDeployed
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if NFT is deployed from the factory
|
||||||
|
* @param {String} nftAddress nftAddress address we want to check
|
||||||
|
* @return {Promise<String>} return address(0) if it's not, or the nftAddress if true
|
||||||
|
*/
|
||||||
|
public async checkNFT(nftAddress: string): Promise<String> {
|
||||||
|
const confirmAddress = await this.factory721.methods.erc721List(nftAddress).call()
|
||||||
|
return confirmAddress
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new erc721 token template - only factory Owner
|
* Add a new erc721 token template - only factory Owner
|
||||||
* @param {String} address
|
* @param {String} address
|
||||||
@ -367,4 +423,157 @@ export class NFTFactory {
|
|||||||
|
|
||||||
return trxReceipt
|
return trxReceipt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev startMultipleTokenOrder
|
||||||
|
* Used as a proxy to order multiple services
|
||||||
|
* Users can have inifinite approvals for fees for factory instead of having one approval/ erc20 contract
|
||||||
|
* Requires previous approval of all :
|
||||||
|
* - consumeFeeTokens
|
||||||
|
* - publishMarketFeeTokens
|
||||||
|
* - erc20 datatokens
|
||||||
|
* @param orders an array of struct tokenOrder
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async startMultipleTokenOrder(
|
||||||
|
address: string,
|
||||||
|
orders: TokenOrder[]
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.startMultipleTokenOrder(orders)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.startMultipleTokenOrder(orders)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftWithErc
|
||||||
|
* Creates a new NFT, then a ERC20,all in one call
|
||||||
|
* @param _NftCreateData input data for nft creation
|
||||||
|
* @param _ErcCreateData input data for erc20 creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftWithErc(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftWithErc(nftCreateData, ercCreateData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftWithErc(nftCreateData, ercCreateData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftErcWithPool
|
||||||
|
* Creates a new NFT, then a ERC20, then a Pool, all in one call
|
||||||
|
* Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas
|
||||||
|
* @param _NftCreateData input data for NFT Creation
|
||||||
|
* @param _ErcCreateData input data for ERC20 Creation
|
||||||
|
* @param _PoolData input data for Pool Creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftErcWithPool(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData,
|
||||||
|
poolData: PoolData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftErcWithPool(nftCreateData, ercCreateData, poolData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftErcWithPool(nftCreateData, ercCreateData, poolData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftErcWithFixedRate
|
||||||
|
* Creates a new NFT, then a ERC20, then a FixedRateExchange, all in one call
|
||||||
|
* Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas
|
||||||
|
* @param _NftCreateData input data for NFT Creation
|
||||||
|
* @param _ErcCreateData input data for ERC20 Creation
|
||||||
|
* @param _FixedData input data for FixedRate Creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftErcWithFixedRate(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData,
|
||||||
|
fixedData: FixedData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftErcWithFixedRate(nftCreateData, ercCreateData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftErcWithFixedRate(nftCreateData, ercCreateData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,7 @@ export class TestContractHandler {
|
|||||||
.addSSContract(this.sideStakingAddress)
|
.addSSContract(this.sideStakingAddress)
|
||||||
.send({ from: owner })
|
.send({ from: owner })
|
||||||
// TODO: add OPF deployment and update argument
|
// TODO: add OPF deployment and update argument
|
||||||
|
// TODO: how are we going to call those functions with an OPF contract? it should be a multisig the owner
|
||||||
await RouterContract.methods
|
await RouterContract.methods
|
||||||
.changeRouterOwner(communityCollector)
|
.changeRouterOwner(communityCollector)
|
||||||
.send({ from: owner })
|
.send({ from: owner })
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { assert } from 'chai'
|
import { assert, expect } from 'chai'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
import { AbiItem } from 'web3-utils/types'
|
||||||
import { TestContractHandler } from '../TestContractHandler'
|
import { TestContractHandler } from '../TestContractHandler'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
@ -13,7 +13,6 @@ import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/bal
|
|||||||
import { LoggerInstance } from '../../src/utils'
|
import { LoggerInstance } from '../../src/utils'
|
||||||
// import { NFTDataToken } from '../../../src/datatokens/NFTDatatoken'
|
// import { NFTDataToken } from '../../../src/datatokens/NFTDatatoken'
|
||||||
import { NFTFactory } from '../../src/factories/NFTFactory'
|
import { NFTFactory } from '../../src/factories/NFTFactory'
|
||||||
// import { DT20Factory } from '../../../src/factories/DT20Factory'
|
|
||||||
|
|
||||||
const web3 = new Web3('http://127.0.0.1:8545')
|
const web3 = new Web3('http://127.0.0.1:8545')
|
||||||
|
|
||||||
@ -22,6 +21,7 @@ describe('NFT Factory test', () => {
|
|||||||
let nftOwner: string
|
let nftOwner: string
|
||||||
let user1: string
|
let user1: string
|
||||||
let user2: string
|
let user2: string
|
||||||
|
let user3: string
|
||||||
let contracts: TestContractHandler
|
let contracts: TestContractHandler
|
||||||
let nftFactory: NFTFactory
|
let nftFactory: NFTFactory
|
||||||
|
|
||||||
@ -59,6 +59,8 @@ describe('NFT Factory test', () => {
|
|||||||
factoryOwner = contracts.accounts[0]
|
factoryOwner = contracts.accounts[0]
|
||||||
nftOwner = contracts.accounts[1]
|
nftOwner = contracts.accounts[1]
|
||||||
user1 = contracts.accounts[2]
|
user1 = contracts.accounts[2]
|
||||||
|
user2 = contracts.accounts[3]
|
||||||
|
user3 = contracts.accounts[4]
|
||||||
console.log(factoryOwner)
|
console.log(factoryOwner)
|
||||||
await contracts.deployContracts(factoryOwner, Router.abi as AbiItem[])
|
await contracts.deployContracts(factoryOwner, Router.abi as AbiItem[])
|
||||||
|
|
||||||
@ -71,12 +73,12 @@ describe('NFT Factory test', () => {
|
|||||||
|
|
||||||
it('#getCurrentNFTCount - should return actual nft count (0)', async () => {
|
it('#getCurrentNFTCount - should return actual nft count (0)', async () => {
|
||||||
const nftCount = await nftFactory.getCurrentNFTCount()
|
const nftCount = await nftFactory.getCurrentNFTCount()
|
||||||
assert(nftCount === 0)
|
expect(nftCount).to.equal('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('#getCurrentTokenCount - should return actual token count (0)', async () => {
|
it('#getCurrentTokenCount - should return actual token count (0)', async () => {
|
||||||
const tokenCount = await nftFactory.getCurrentTokenCount()
|
const tokenCount = await nftFactory.getCurrentTokenCount()
|
||||||
assert(tokenCount === 0)
|
expect(tokenCount).to.equal('0')
|
||||||
})
|
})
|
||||||
it('#getOwner - should return actual owner', async () => {
|
it('#getOwner - should return actual owner', async () => {
|
||||||
const owner = await nftFactory.getOwner()
|
const owner = await nftFactory.getOwner()
|
||||||
@ -84,11 +86,11 @@ describe('NFT Factory test', () => {
|
|||||||
})
|
})
|
||||||
it('#getCurrentNFTTemplateCount - should return actual nft template count (1)', async () => {
|
it('#getCurrentNFTTemplateCount - should return actual nft template count (1)', async () => {
|
||||||
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||||
assert(nftTemplateCount === 1)
|
expect(nftTemplateCount).to.equal('1')
|
||||||
})
|
})
|
||||||
it('#getCurrentTokenTemplateCount - should return actual token template count (1)', async () => {
|
it('#getCurrentTokenTemplateCount - should return actual token template count (1)', async () => {
|
||||||
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||||
assert(tokenTemplateCount === 1)
|
expect(tokenTemplateCount).to.equal('1')
|
||||||
})
|
})
|
||||||
it('#getNFTTemplate - should return NFT template struct', async () => {
|
it('#getNFTTemplate - should return NFT template struct', async () => {
|
||||||
const nftTemplate = await nftFactory.getNFTTemplate(1)
|
const nftTemplate = await nftFactory.getNFTTemplate(1)
|
||||||
@ -103,7 +105,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#addNFTTemplate - should add NFT template if factory owner', async () => {
|
it('#addNFTTemplate - should add NFT template if factory owner', async () => {
|
||||||
await nftFactory.addNFTTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
await nftFactory.addNFTTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
||||||
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||||
assert(nftTemplateCount === 2)
|
expect(nftTemplateCount).to.equal('2')
|
||||||
const nftTemplate = await nftFactory.getNFTTemplate(2)
|
const nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
||||||
@ -127,7 +129,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#addTokenTemplate - should add Datatoken template if factory owner', async () => {
|
it('#addTokenTemplate - should add Datatoken template if factory owner', async () => {
|
||||||
await nftFactory.addTokenTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
await nftFactory.addTokenTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
||||||
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||||
assert(tokenTemplateCount === 2)
|
expect(tokenTemplateCount).to.equal('2')
|
||||||
const nftTemplate = await nftFactory.getTokenTemplate(2)
|
const nftTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
||||||
@ -149,4 +151,30 @@ describe('NFT Factory test', () => {
|
|||||||
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(tokenTemplate.isActive === true)
|
assert(tokenTemplate.isActive === true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('#createNFTwithErc - should create an NFT and a Datatoken', async () => {
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [user2, user3, user2, '0x0000000000000000000000000000000000000000'],
|
||||||
|
uints: [web3.utils.toWei('10000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftWithErc(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData
|
||||||
|
)
|
||||||
|
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||||
|
expect(txReceipt.events.TokenCreated.event === 'TokenCreated')
|
||||||
|
console.log(txReceipt.events.NFTCreated.returnValues.newTokenAddress)
|
||||||
|
console.log(txReceipt.events.TokenCreated.returnValues.newTokenAddress)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user