mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Merge pull request #1843 from oceanprotocol/issue-1841-pub-flow
Issue 1841 pub flow - createAsset Fn
This commit is contained in:
commit
7b340ad607
@ -10,6 +10,10 @@ export interface DatatokenCreateParams {
|
||||
cap: string
|
||||
name?: string
|
||||
symbol?: string
|
||||
filesObject?: any // file object for template 4
|
||||
accessListFactory?: string // access list factory address
|
||||
allowAccessList?: string // Allow List Contract (if any)
|
||||
denyAccessList?: string // Deny List Contract (if any)
|
||||
}
|
||||
|
||||
export interface ConsumeMarketFee {
|
||||
|
@ -179,4 +179,8 @@ export class Config {
|
||||
DFRewards?: string
|
||||
DFStrategyV1?: string
|
||||
veFeeEstimate?: string
|
||||
|
||||
// is confidential evm
|
||||
confidentialEVM?: boolean
|
||||
accessListFactory?: string
|
||||
}
|
||||
|
@ -178,6 +178,11 @@ export const configHelperNetworks: Config[] = [
|
||||
}
|
||||
]
|
||||
|
||||
export const KNOWN_CONFIDENTIAL_EVMS = [
|
||||
23294, // oasis_sapphire
|
||||
23295 // oasis_sapphire_testnet
|
||||
]
|
||||
|
||||
export class ConfigHelper {
|
||||
/* Load contract addresses from env ADDRESS_FILE (generated by ocean-contracts) */
|
||||
public getAddressesFromEnv(network: string, customAddresses?: any): Partial<Config> {
|
||||
@ -200,7 +205,8 @@ export class ConfigHelper {
|
||||
veDelegationProxy,
|
||||
DFRewards,
|
||||
DFStrategyV1,
|
||||
veFeeEstimate
|
||||
veFeeEstimate,
|
||||
AccessListFactory
|
||||
} = customAddresses[network]
|
||||
configAddresses = {
|
||||
nftFactoryAddress: ERC721Factory,
|
||||
@ -218,6 +224,7 @@ export class ConfigHelper {
|
||||
DFRewards,
|
||||
DFStrategyV1,
|
||||
veFeeEstimate,
|
||||
accessListFactory: AccessListFactory,
|
||||
...(process.env.AQUARIUS_URL && { metadataCacheUri: process.env.AQUARIUS_URL }),
|
||||
...(process.env.PROVIDER_URL && { providerUri: process.env.PROVIDER_URL })
|
||||
}
|
||||
@ -239,7 +246,8 @@ export class ConfigHelper {
|
||||
veDelegationProxy,
|
||||
DFRewards,
|
||||
DFStrategyV1,
|
||||
veFeeEstimate
|
||||
veFeeEstimate,
|
||||
AccessListFactory
|
||||
} = DefaultContractsAddresses[network]
|
||||
configAddresses = {
|
||||
nftFactoryAddress: ERC721Factory,
|
||||
@ -257,6 +265,7 @@ export class ConfigHelper {
|
||||
DFRewards,
|
||||
DFStrategyV1,
|
||||
veFeeEstimate,
|
||||
accessListFactory: AccessListFactory,
|
||||
...(process.env.AQUARIUS_URL && { metadataCacheUri: process.env.AQUARIUS_URL }),
|
||||
...(process.env.PROVIDER_URL && { providerUri: process.env.PROVIDER_URL })
|
||||
}
|
||||
@ -273,6 +282,7 @@ export class ConfigHelper {
|
||||
*/
|
||||
public getConfig(network: string | number, infuraProjectId?: string): Config {
|
||||
const filterBy = typeof network === 'string' ? 'network' : 'chainId'
|
||||
|
||||
let config = configHelperNetworks.find((c) => c[filterBy] === network)
|
||||
|
||||
if (!config) {
|
||||
@ -292,7 +302,23 @@ export class ConfigHelper {
|
||||
console.log(e)
|
||||
addresses = null
|
||||
}
|
||||
const contractAddressesConfig = this.getAddressesFromEnv(config.network, addresses)
|
||||
|
||||
let contractAddressesConfig = this.getAddressesFromEnv(config.network, addresses)
|
||||
// check oasis network name typos on addresses.json
|
||||
if (!contractAddressesConfig && KNOWN_CONFIDENTIAL_EVMS.includes(config.chainId)) {
|
||||
contractAddressesConfig = this.getAddressesFromEnv(
|
||||
config.network.replace('sapph', 'saph'),
|
||||
addresses
|
||||
)
|
||||
}
|
||||
config.confidentialEVM =
|
||||
filterBy === 'chainId'
|
||||
? KNOWN_CONFIDENTIAL_EVMS.includes(Number(network))
|
||||
: network.toString().includes('oasis_sap')
|
||||
if (config.confidentialEVM) {
|
||||
config.accessListFactory = contractAddressesConfig.accessListFactory
|
||||
}
|
||||
|
||||
config = { ...config, ...contractAddressesConfig }
|
||||
|
||||
const nodeUri = infuraProjectId
|
||||
|
@ -12,7 +12,7 @@ import { SmartContract } from './SmartContract'
|
||||
import {
|
||||
calculateActiveTemplateIndex,
|
||||
getOceanArtifactsAdressesByChainId
|
||||
} from '../utils/Asset'
|
||||
} from '../utils/Assets'
|
||||
|
||||
export class Nft extends SmartContract {
|
||||
getDefaultAbi() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BigNumber } from 'ethers'
|
||||
import { BigNumber, ethers } from 'ethers'
|
||||
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||
import {
|
||||
generateDtName,
|
||||
@ -580,20 +580,39 @@ export class NftFactory extends SmartContractWithAddress {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
templateIndex: dtParams.templateIndex,
|
||||
strings: [dtParams.name || name, dtParams.symbol || symbol],
|
||||
addresses: [
|
||||
// common stuff for other templates
|
||||
const addresses = [
|
||||
dtParams.minter,
|
||||
dtParams.paymentCollector,
|
||||
dtParams.mpFeeAddress,
|
||||
dtParams.feeToken
|
||||
],
|
||||
]
|
||||
|
||||
if (dtParams.filesObject) {
|
||||
// template 4 only, ignored for others
|
||||
if (dtParams.accessListFactory) {
|
||||
addresses.push(dtParams.accessListFactory)
|
||||
}
|
||||
if (dtParams.allowAccessList) {
|
||||
addresses.push(dtParams.allowAccessList)
|
||||
}
|
||||
|
||||
if (dtParams.denyAccessList) {
|
||||
addresses.push(dtParams.denyAccessList)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
templateIndex: dtParams.templateIndex,
|
||||
strings: [dtParams.name || name, dtParams.symbol || symbol],
|
||||
addresses,
|
||||
uints: [
|
||||
await this.amountToUnits(null, dtParams.cap, 18),
|
||||
await this.amountToUnits(null, dtParams.feeAmount, feeTokenDecimals)
|
||||
],
|
||||
bytess: []
|
||||
bytess: dtParams.filesObject
|
||||
? [ethers.utils.toUtf8Bytes(JSON.stringify(dtParams.filesObject))]
|
||||
: []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +510,7 @@ export class Provider {
|
||||
)) + 1
|
||||
).toString()
|
||||
|
||||
const signature = await this.signProviderRequest(signer, did + nonce)
|
||||
const signature = await this.signProviderRequest(signer, did + nonce) // did + nonce
|
||||
let consumeUrl = downloadUrl
|
||||
consumeUrl += `?fileIndex=${fileIndex}`
|
||||
consumeUrl += `&documentId=${did}`
|
||||
|
@ -1,87 +0,0 @@
|
||||
import { ethers, Signer } from 'ethers'
|
||||
|
||||
import { NftFactory } from '../contracts/NFTFactory'
|
||||
// eslint-disable-next-line import/no-named-default
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/interfaces/IERC20Template.sol/IERC20Template.json'
|
||||
import fs from 'fs'
|
||||
// eslint-disable-next-line import/no-named-default
|
||||
import { default as addrs } from '@oceanprotocol/contracts/addresses/address.json'
|
||||
|
||||
/**
|
||||
* Get the artifacts address from the address.json file
|
||||
* either from the env or from the ocean-contracts dir
|
||||
* @returns data or null
|
||||
*/
|
||||
export function getOceanArtifactsAdresses(): any {
|
||||
try {
|
||||
if (process.env.ADDRESS_FILE) {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
const data = fs.readFileSync(process.env.ADDRESS_FILE, 'utf8')
|
||||
return JSON.parse(data)
|
||||
}
|
||||
return addrs
|
||||
} catch (error) {
|
||||
return addrs
|
||||
}
|
||||
}
|
||||
|
||||
export function getOceanArtifactsAdressesByChainId(chain: number): any {
|
||||
try {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
const data = getOceanArtifactsAdresses()
|
||||
if (data) {
|
||||
const networks = Object.keys(data)
|
||||
for (const network of networks) {
|
||||
if (data[network].chainId === chain) {
|
||||
return data[network]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to accurately calculate the template index, and also checking if the template is active
|
||||
* @param owner the signer account
|
||||
* @param nftContractAddress the nft contract address, usually artifactsAddresses.ERC721Factory
|
||||
* @param template the template ID or template address (from smart contract getId() function)
|
||||
* @returns index of the template on the list
|
||||
*/
|
||||
export async function calculateActiveTemplateIndex(
|
||||
owner: Signer,
|
||||
nftContractAddress: string, // addresses.ERC721Factory,
|
||||
template: string | number
|
||||
): Promise<number> {
|
||||
// is an ID number?
|
||||
const isTemplateID = typeof template === 'number'
|
||||
|
||||
const factoryERC721 = new NftFactory(nftContractAddress, owner)
|
||||
const currentTokenCount = await factoryERC721.getCurrentTokenTemplateCount()
|
||||
for (let i = 1; i <= currentTokenCount; i++) {
|
||||
const tokenTemplate = await factoryERC721.getTokenTemplate(i)
|
||||
|
||||
const erc20Template = new ethers.Contract(
|
||||
tokenTemplate.templateAddress,
|
||||
ERC20Template.abi,
|
||||
owner
|
||||
)
|
||||
|
||||
// check for ID
|
||||
if (isTemplateID) {
|
||||
const id = await erc20Template.connect(owner).getId()
|
||||
if (tokenTemplate.isActive && id.toString() === template.toString()) {
|
||||
return i
|
||||
}
|
||||
} else if (
|
||||
tokenTemplate.isActive &&
|
||||
tokenTemplate.templateAddress === template.toString()
|
||||
) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
// if nothing is found it returns -1
|
||||
return -1
|
||||
}
|
350
src/utils/Assets.ts
Normal file
350
src/utils/Assets.ts
Normal file
@ -0,0 +1,350 @@
|
||||
import { SHA256 } from 'crypto-js'
|
||||
import { ethers, Signer } from 'ethers'
|
||||
import { ConfigHelper } from '../../src/config'
|
||||
import { hexlify } from 'ethers/lib/utils'
|
||||
import { createHash } from 'crypto'
|
||||
import fs from 'fs'
|
||||
|
||||
// eslint-disable-next-line import/no-named-default
|
||||
import { default as Addresses } from '@oceanprotocol/contracts/addresses/address.json'
|
||||
import { Aquarius } from '../services/Aquarius'
|
||||
import { NftFactory } from '../contracts/NFTFactory'
|
||||
import { Nft } from '../contracts/NFT'
|
||||
import { DatatokenCreateParams } from '../@types/Datatoken'
|
||||
import { NftCreateData } from '../@types/NFTFactory'
|
||||
import { ZERO_ADDRESS } from './Constants'
|
||||
import { DispenserCreationParams } from '../@types/Dispenser'
|
||||
import { FreCreationParams } from '../@types/FixedPrice'
|
||||
import { getEventFromTx } from './ContractUtils'
|
||||
import { ProviderInstance } from '../services/Provider'
|
||||
// eslint-disable-next-line import/no-named-default
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/interfaces/IERC20Template.sol/IERC20Template.json'
|
||||
import AccessListFactory from '@oceanprotocol/contracts/artifacts/contracts/accesslists/AccessListFactory.sol/AccessListFactory.json'
|
||||
import ERC20Template4 from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template4.sol/ERC20Template4.json'
|
||||
|
||||
// import * as hre from 'hardhat'
|
||||
|
||||
export const DEVELOPMENT_CHAIN_ID = 8996
|
||||
// template address OR templateId
|
||||
export function isConfidentialEVM(network: string | number): boolean {
|
||||
const config = new ConfigHelper().getConfig(network)
|
||||
return config && config.confidentialEVM
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the artifacts address from the address.json file
|
||||
* either from the env or from the ocean-contracts dir
|
||||
* @returns data or null
|
||||
*/
|
||||
export function getOceanArtifactsAdresses(): any {
|
||||
try {
|
||||
if (process.env.ADDRESS_FILE) {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
const data = fs.readFileSync(process.env.ADDRESS_FILE, 'utf8')
|
||||
return JSON.parse(data)
|
||||
}
|
||||
return Addresses
|
||||
} catch (error) {
|
||||
return Addresses
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the artifacts address from the address.json file, for the given chain
|
||||
* either from the env or from the ocean-contracts dir, safer than above, because sometimes the network name
|
||||
* is mispeled, best example "optimism_sepolia" vs "optimism-sepolia"
|
||||
* @returns data or null
|
||||
*/
|
||||
export function getOceanArtifactsAdressesByChainId(chain: number): any {
|
||||
try {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
const data = getOceanArtifactsAdresses()
|
||||
if (data) {
|
||||
const networks = Object.keys(data)
|
||||
for (const network of networks) {
|
||||
if (data[network].chainId === chain) {
|
||||
return data[network]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to accurately calculate the template index, and also checking if the template is active
|
||||
* @param owner the signer account
|
||||
* @param nftContractAddress the nft contract address, usually artifactsAddresses.ERC721Factory
|
||||
* @param template the template ID or template address (from smart contract getId() function)
|
||||
* @returns index of the template on the list
|
||||
*/
|
||||
export async function calculateActiveTemplateIndex(
|
||||
owner: Signer,
|
||||
nftContractAddress: string, // addresses.ERC721Factory,
|
||||
template: string | number
|
||||
): Promise<number> {
|
||||
// is an ID number?
|
||||
const isTemplateID = typeof template === 'number'
|
||||
|
||||
const factoryERC721 = new NftFactory(nftContractAddress, owner)
|
||||
const currentTokenCount = await factoryERC721.getCurrentTokenTemplateCount()
|
||||
for (let i = 1; i <= currentTokenCount; i++) {
|
||||
const tokenTemplate = await factoryERC721.getTokenTemplate(i)
|
||||
|
||||
const erc20Template = new ethers.Contract(
|
||||
tokenTemplate.templateAddress,
|
||||
ERC20Template.abi,
|
||||
owner
|
||||
)
|
||||
|
||||
// check for ID
|
||||
if (isTemplateID) {
|
||||
const id = await erc20Template.connect(owner).getId()
|
||||
if (tokenTemplate.isActive && id.toString() === template.toString()) {
|
||||
return i
|
||||
}
|
||||
} else if (
|
||||
tokenTemplate.isActive &&
|
||||
tokenTemplate.templateAddress === template.toString()
|
||||
) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
// if nothing is found it returns -1
|
||||
return -1
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param name asset name
|
||||
* @param symbol asse symbol
|
||||
* @param owner owner address
|
||||
* @param assetUrl asset url, if present and confidential evm, add it to token create params
|
||||
* @param templateIDorAddress either template address or id
|
||||
* @param ddo ddo
|
||||
* @param encryptDDO encrypt or not?
|
||||
* @param providerUrl the provider URL
|
||||
* @param providerFeeToken the provider fee token
|
||||
* @param aquariusInstance aquarius, could be node instance url
|
||||
* @param allowAccessList?: string,
|
||||
* @param denyAccessList?: string
|
||||
* @returns ddo id as string
|
||||
*/
|
||||
export async function createAsset(
|
||||
name: string,
|
||||
symbol: string,
|
||||
owner: Signer,
|
||||
assetUrl: any, // files object
|
||||
templateIDorAddress: string | number, // If string, it's template address , otherwise, it's templateId
|
||||
ddo: any,
|
||||
encryptDDO: boolean = true, // default is true
|
||||
providerUrl: string,
|
||||
providerFeeToken: string,
|
||||
aquariusInstance: Aquarius,
|
||||
accessListFactory?: string, // access list factory address
|
||||
allowAccessList?: string, // allow list address
|
||||
denyAccessList?: string // deny list address
|
||||
): Promise<string> {
|
||||
const isAddress = typeof templateIDorAddress === 'string'
|
||||
const isTemplateIndex = typeof templateIDorAddress === 'number'
|
||||
if (!isAddress && !isTemplateIndex) {
|
||||
throw new Error('Invalid template! Must be a "number" or a "string"')
|
||||
}
|
||||
const chainID = (await owner.provider.getNetwork()).chainId
|
||||
|
||||
const config = new ConfigHelper().getConfig(parseInt(String(chainID)))
|
||||
|
||||
let templateIndex = await calculateActiveTemplateIndex(
|
||||
owner,
|
||||
config.nftFactoryAddress,
|
||||
templateIDorAddress
|
||||
)
|
||||
|
||||
if (templateIndex < 1) {
|
||||
// for testing purposes only
|
||||
if (chainID === DEVELOPMENT_CHAIN_ID) {
|
||||
templateIndex = 1
|
||||
} else throw new Error(`Invalid template index: ${templateIndex}`)
|
||||
}
|
||||
|
||||
const nft = new Nft(owner, chainID)
|
||||
|
||||
const nftFactory = new NftFactory(config.nftFactoryAddress, owner)
|
||||
|
||||
// get nft owner
|
||||
const account = await owner.getAddress()
|
||||
|
||||
// from hex to number format
|
||||
ddo.chainId = parseInt(chainID.toString(10))
|
||||
const nftParamsAsset: NftCreateData = {
|
||||
name,
|
||||
symbol,
|
||||
templateIndex: 1,
|
||||
tokenURI: 'aaa',
|
||||
transferable: true,
|
||||
owner: account
|
||||
}
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: account,
|
||||
feeToken: providerFeeToken || config.oceanTokenAddress,
|
||||
minter: account,
|
||||
mpFeeAddress: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
// include fileObject in the DT constructor
|
||||
if (config.confidentialEVM) {
|
||||
datatokenParams.filesObject = assetUrl
|
||||
datatokenParams.accessListFactory = accessListFactory || config.accessListFactory
|
||||
datatokenParams.allowAccessList = allowAccessList
|
||||
datatokenParams.denyAccessList = denyAccessList
|
||||
}
|
||||
|
||||
let bundleNFT
|
||||
try {
|
||||
if (!ddo.stats?.price?.value) {
|
||||
bundleNFT = await nftFactory.createNftWithDatatoken(nftParamsAsset, datatokenParams)
|
||||
} else if (ddo.stats?.price?.value === '0') {
|
||||
const dispenserParams: DispenserCreationParams = {
|
||||
dispenserAddress: config.dispenserAddress,
|
||||
maxTokens: '1',
|
||||
maxBalance: '100000000',
|
||||
withMint: true,
|
||||
allowedSwapper: ZERO_ADDRESS
|
||||
}
|
||||
bundleNFT = await nftFactory.createNftWithDatatokenWithDispenser(
|
||||
nftParamsAsset,
|
||||
datatokenParams,
|
||||
dispenserParams
|
||||
)
|
||||
} else {
|
||||
// fixed price
|
||||
const fixedPriceParams: FreCreationParams = {
|
||||
fixedRateAddress: config.fixedRateExchangeAddress,
|
||||
baseTokenAddress: config.oceanTokenAddress,
|
||||
owner: account,
|
||||
marketFeeCollector: account,
|
||||
baseTokenDecimals: 18,
|
||||
datatokenDecimals: 18,
|
||||
fixedRate: ddo.stats.price.value,
|
||||
marketFee: '0',
|
||||
allowedConsumer: account,
|
||||
withMint: true
|
||||
}
|
||||
bundleNFT = await nftFactory.createNftWithDatatokenWithFixedRate(
|
||||
nftParamsAsset,
|
||||
datatokenParams,
|
||||
fixedPriceParams
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('ERROR creating NFT bundle', err)
|
||||
return null
|
||||
}
|
||||
|
||||
const trxReceipt = await bundleNFT.wait()
|
||||
// events have been emitted
|
||||
const nftCreatedEvent = getEventFromTx(trxReceipt, 'NFTCreated')
|
||||
const tokenCreatedEvent = getEventFromTx(trxReceipt, 'TokenCreated')
|
||||
|
||||
const nftAddress = nftCreatedEvent.args.newTokenAddress
|
||||
const datatokenAddressAsset = tokenCreatedEvent.args.newTokenAddress
|
||||
// create the files encrypted string
|
||||
assetUrl.datatokenAddress = datatokenAddressAsset
|
||||
assetUrl.nftAddress = nftAddress
|
||||
|
||||
if (config.confidentialEVM) {
|
||||
// we need to update files object on the SC otherwise it will fail validation on provider
|
||||
// because DDO datatokenAddress and nftAddress will not match the values on files object
|
||||
const contract = new ethers.Contract(datatokenAddressAsset, ERC20Template4.abi, owner)
|
||||
try {
|
||||
const tx = await contract.setFilesObject(
|
||||
ethers.utils.toUtf8Bytes(JSON.stringify(assetUrl))
|
||||
)
|
||||
if (tx.wait) {
|
||||
await tx.wait()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Error updating files object with data token and nft addresses: ', err)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// if confidential EVM no need to make encrypt call here
|
||||
if (config.confidentialEVM) {
|
||||
ddo.services[0].files = '' // on confidental EVM it needs to be empty string not null, for schema validation
|
||||
} else {
|
||||
ddo.services[0].files = await ProviderInstance.encrypt(assetUrl, chainID, providerUrl)
|
||||
}
|
||||
|
||||
ddo.services[0].datatokenAddress = datatokenAddressAsset
|
||||
ddo.services[0].serviceEndpoint = providerUrl
|
||||
|
||||
ddo.nftAddress = nftAddress
|
||||
ddo.id = 'did:op:' + SHA256(ethers.utils.getAddress(nftAddress) + chainID.toString(10))
|
||||
|
||||
let metadata
|
||||
let metadataHash
|
||||
let flags
|
||||
if (encryptDDO) {
|
||||
metadata = await ProviderInstance.encrypt(ddo, chainID, providerUrl)
|
||||
const validateResult = await aquariusInstance.validate(ddo)
|
||||
metadataHash = validateResult.hash
|
||||
flags = 2
|
||||
} else {
|
||||
const stringDDO = JSON.stringify(ddo)
|
||||
const bytes = Buffer.from(stringDDO)
|
||||
metadata = hexlify(bytes)
|
||||
metadataHash = '0x' + createHash('sha256').update(metadata).digest('hex')
|
||||
flags = 0
|
||||
}
|
||||
|
||||
await nft.setMetadata(
|
||||
nftAddress,
|
||||
await owner.getAddress(),
|
||||
0,
|
||||
providerUrl,
|
||||
'',
|
||||
ethers.utils.hexlify(flags),
|
||||
metadata,
|
||||
metadataHash
|
||||
)
|
||||
return ddo.id
|
||||
}
|
||||
|
||||
/**
|
||||
* deploy new access list factory if needed
|
||||
* @param accessListFactory accessListFactory address
|
||||
* @param owner owner account
|
||||
* @param addressesList list of addresses to deploy
|
||||
* @returns accessListFactory address
|
||||
*/
|
||||
export async function createAccessListFactory(
|
||||
accessListFactory: string,
|
||||
owner: Signer,
|
||||
addressesList?: string[]
|
||||
): Promise<any> {
|
||||
const factory = new ethers.Contract(accessListFactory, AccessListFactory.abi, owner)
|
||||
const ownerAccount = await owner.getAddress()
|
||||
try {
|
||||
const accessListTx = await factory.deployAccessListContract(
|
||||
'AllowList',
|
||||
'ALLOW',
|
||||
true,
|
||||
ownerAccount,
|
||||
addressesList || [ownerAccount],
|
||||
['https://oceanprotocol.com/nft/']
|
||||
)
|
||||
if (accessListTx && accessListTx.wait) {
|
||||
const trxReceipt = await accessListTx.wait()
|
||||
const events = getEventFromTx(trxReceipt, 'NewAccessList')
|
||||
return events.args[0]
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('ERROR createAccessListFactory(): ', error)
|
||||
}
|
||||
return null
|
||||
}
|
@ -66,6 +66,7 @@ export async function orderAsset(
|
||||
)
|
||||
|
||||
const templateIndex = await datatoken.getId(asset.datatokens[datatokenIndex].address)
|
||||
|
||||
const fixedRates = await datatoken.getFixedRates(
|
||||
asset.datatokens[datatokenIndex].address
|
||||
)
|
||||
@ -137,7 +138,7 @@ export async function orderAsset(
|
||||
orderParams._consumeMarketFee
|
||||
)
|
||||
}
|
||||
if (templateIndex === 2) {
|
||||
if (templateIndex === 2 || templateIndex === 4) {
|
||||
return await datatoken.buyFromDispenserAndOrder(
|
||||
asset.services[serviceIndex].datatokenAddress,
|
||||
orderParams,
|
||||
@ -210,7 +211,7 @@ export async function orderAsset(
|
||||
orderParams._consumeMarketFee
|
||||
)
|
||||
}
|
||||
if (templateIndex === 2) {
|
||||
if (templateIndex === 2 || templateIndex === 4) {
|
||||
const tx: any = await approve(
|
||||
consumerAccount,
|
||||
config,
|
||||
|
@ -10,3 +10,4 @@ export * from './SignatureUtils'
|
||||
export * from './TokenUtils'
|
||||
export * from './ProviderErrors'
|
||||
export * from './OrderUtils'
|
||||
export * from './Assets'
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
Files
|
||||
} from '../../src/@types'
|
||||
|
||||
import { createAsset } from '../../src/utils'
|
||||
function delay(interval: number) {
|
||||
return it('should delay', (done) => {
|
||||
setTimeout(() => done(), interval)
|
||||
@ -198,6 +199,25 @@ describe('Publish tests', async () => {
|
||||
|
||||
delay(19000)
|
||||
|
||||
it('should publish a dataset with fixed price (create NFT + Datoken + fixed price) using createAsset() fn', async () => {
|
||||
const fixedPriceDdo: DDO = { ...genericAsset }
|
||||
const ownerAddress = publisherAccount
|
||||
const asset = await createAsset(
|
||||
'test asset',
|
||||
'TEST',
|
||||
ownerAddress,
|
||||
assetUrl,
|
||||
1, // template 1 on dev network
|
||||
fixedPriceDdo,
|
||||
true, // encrypted ddo
|
||||
providerUrl,
|
||||
ZERO_ADDRESS, // provider fee token
|
||||
aquarius
|
||||
)
|
||||
|
||||
assert(asset !== null, 'Could not publish asset!')
|
||||
})
|
||||
|
||||
it('should resolve the fixed price dataset', async () => {
|
||||
const resolvedDDO = await aquarius.waitForAqua(fixedPricedDID)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
47
test/unit/AssetUtils.test.ts
Normal file
47
test/unit/AssetUtils.test.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { assert } from 'chai'
|
||||
import { KNOWN_CONFIDENTIAL_EVMS } from '../../src/config'
|
||||
import { provider, getAddresses } from '../config'
|
||||
import { calculateActiveTemplateIndex, isConfidentialEVM } from '../../src/utils'
|
||||
import { Signer } from 'ethers/lib/ethers'
|
||||
|
||||
let nftOwner: Signer
|
||||
let addresses: any
|
||||
describe('Asset utils (createAsset)', () => {
|
||||
before(async () => {
|
||||
nftOwner = (await provider.getSigner(0)) as Signer
|
||||
addresses = await getAddresses()
|
||||
})
|
||||
|
||||
it('should check if confidential EVM', async () => {
|
||||
for (const chain of KNOWN_CONFIDENTIAL_EVMS) {
|
||||
assert(
|
||||
isConfidentialEVM(chain) === true,
|
||||
`Chain Id: "${chain}" is not a confidental EVM`
|
||||
)
|
||||
}
|
||||
|
||||
// optimism sepolia
|
||||
// 11155420
|
||||
assert(
|
||||
isConfidentialEVM(11155420) === false,
|
||||
`Chain Id: "11155420" is wrongly considered a confidental EVM`
|
||||
)
|
||||
})
|
||||
|
||||
// checking if active by connecting to the smart contract as well
|
||||
it('Calculate index - Should get correct template index from contract getId() (using template ID as template)', async () => {
|
||||
const okTemplate = await calculateActiveTemplateIndex(
|
||||
nftOwner,
|
||||
addresses.ERC721Factory,
|
||||
3
|
||||
)
|
||||
assert(okTemplate === 3, 'wrong template index, should be index 3!')
|
||||
|
||||
const wrongOne = await calculateActiveTemplateIndex(
|
||||
nftOwner,
|
||||
addresses.ERC721Factory,
|
||||
6
|
||||
)
|
||||
assert(wrongOne === -1, 'wrong template index, should only exist 3!')
|
||||
})
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user