* type out new DDO

* remove all DDO ocean.js imports

* move over as much as possible to new DDO structure

* DDO/Asset split-up

* use Asset typing instead of DDO almost everywhere

* more typings

* more DDO refactor

* ddo typings updates

* more DDO updates

* updates

* ddo updates
This commit is contained in:
Matthias Kretschmann 2021-11-11 07:51:13 +00:00 committed by GitHub
parent 0fb4e630c1
commit 3d4b30c00f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 838 additions and 777 deletions

View File

@ -97,9 +97,9 @@
},
{
"name": "providerUri",
"name": "providerUrl",
"label": "Custom Provider URL",
"type": "providerUri",
"type": "providerUrl",
"help": "Enter the URL for your custom provider or leave blank to use the default provider. [Learn more](https://github.com/oceanprotocol/provider/).",
"placeholder": "e.g. https://provider.polygon.oceanprotocol.com/"
}

View File

@ -7,7 +7,7 @@ import React, {
useCallback,
ReactNode
} from 'react'
import { Logger, DDO, MetadataMain } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData'
import getAssetPurgatoryData from '@utils/purgatory'
import { CancelToken } from 'axios'
@ -20,13 +20,10 @@ import { useCancelToken } from '@hooks/useCancelToken'
interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: PurgatoryData
ddo: DDO
did: string
metadata: MetadataMarket
ddo: Asset
title: string
owner: string
price: BestPrice
type: MetadataMain['type']
error?: string
refreshInterval: number
isAssetNetwork: boolean
@ -42,7 +39,7 @@ function AssetProvider({
asset,
children
}: {
asset: string | DDO
asset: string | Asset
children: ReactNode
}): ReactElement {
const { appConfig } = useSiteMetadata()
@ -50,17 +47,17 @@ function AssetProvider({
const { networkId } = useWeb3()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>()
const [ddo, setDDO] = useState<DDO>()
const [ddo, setDDO] = useState<Asset>()
const [did, setDID] = useState<string>()
const [metadata, setMetadata] = useState<MetadataMarket>()
const [title, setTitle] = useState<string>()
const [price, setPrice] = useState<BestPrice>()
const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>()
const [type, setType] = useState<MetadataMain['type']>()
const [loading, setLoading] = useState(false)
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
const newCancelToken = useCancelToken()
const fetchDdo = async (token?: CancelToken) => {
Logger.log('[asset] Init asset, get DDO')
setLoading(true)
@ -85,27 +82,6 @@ function AssetProvider({
setLoading(false)
}
//
// Get and set DDO based on passed DDO or DID
//
useEffect(() => {
if (!asset || !appConfig.metadataCacheUri) return
let isMounted = true
async function init() {
const ddo = await fetchDdo(newCancelToken())
if (!isMounted) return
Logger.debug('[asset] Got DDO', ddo)
setDDO(ddo)
setDID(asset as string)
}
init()
return () => {
isMounted = false
}
}, [asset, appConfig.metadataCacheUri])
const setPurgatory = useCallback(async (did: string): Promise<void> => {
if (!did) return
@ -119,29 +95,41 @@ function AssetProvider({
}
}, [])
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
//
// Get and set DDO based on passed DDO or DID
//
useEffect(() => {
if (!asset || !appConfig.metadataCacheUri) return
let isMounted = true
async function init() {
const ddo = await fetchDdo(newCancelToken())
if (!isMounted || !ddo) return
Logger.debug('[asset] Got DDO', ddo)
setDDO(ddo)
setDID(asset as string)
setTitle(ddo.metadata.name)
setOwner(ddo.nft.owner)
setIsInPurgatory(ddo.isInPurgatory === 'true')
await setPurgatory(ddo.id)
}
init()
return () => {
isMounted = false
}
}, [asset, appConfig.metadataCacheUri])
const initPrice = useCallback(async (ddo: Asset): Promise<void> => {
if (!ddo) return
setLoading(true)
const returnedPrice = await getPrice(ddo)
setPrice({ ...returnedPrice })
// Get metadata from DDO
const { attributes } = ddo.findServiceByType('metadata')
setMetadata(attributes as unknown as MetadataMarket)
setTitle(attributes?.main.name)
setType(attributes.main.type)
setOwner(ddo.publicKey[0].owner)
Logger.log('[asset] Got Metadata from DDO', attributes)
setIsInPurgatory(ddo.isInPurgatory === 'true')
await setPurgatory(ddo.id)
setLoading(false)
}, [])
useEffect(() => {
if (!ddo) return
initMetadata(ddo)
}, [ddo, initMetadata])
initPrice(ddo)
}, [ddo, initPrice])
// Check user network against asset network
useEffect(() => {
@ -157,11 +145,9 @@ function AssetProvider({
{
ddo,
did,
metadata,
title,
owner,
price,
type,
error,
isInPurgatory,
purgatoryData,

View File

@ -14,7 +14,7 @@ import {
} from '@utils/subgraph'
import { useUserPreferences } from './UserPreferences'
import { PoolShares_poolShares as PoolShare } from '../@types/apollo/PoolShares'
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { getDownloadAssets, getPublishedAssets } from '@utils/aquarius'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { accountTruncate } from '@utils/web3'
@ -27,7 +27,7 @@ interface ProfileProviderValue {
profile: Profile
poolShares: PoolShare[]
isPoolSharesLoading: boolean
assets: DDO[]
assets: Asset[]
assetsTotal: number
isEthAddress: boolean
downloads: DownloadedAsset[]
@ -170,7 +170,7 @@ function ProfileProvider({
//
// PUBLISHED ASSETS
//
const [assets, setAssets] = useState<DDO[]>()
const [assets, setAssets] = useState<Asset[]>()
const [assetsTotal, setAssetsTotal] = useState(0)
// const [assetsWithPrices, setAssetsWithPrices] = useState<AssetListPrices[]>()

View File

@ -1,4 +1,4 @@
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { useState } from 'react'
import { TransactionReceipt } from 'web3-core'
import { Decimal } from 'decimal.js'
@ -14,17 +14,17 @@ import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
interface UsePricing {
getDTSymbol: (ddo: DDO) => Promise<string>
getDTName: (ddo: DDO) => Promise<string>
getDTSymbol: (ddo: Asset) => Promise<string>
getDTName: (ddo: Asset) => Promise<string>
createPricing: (
priceOptions: PriceOptions,
ddo: DDO
ddo: Asset
) => Promise<TransactionReceipt | string | void>
mint: (tokensToMint: string, ddo: DDO) => Promise<TransactionReceipt | void>
mint: (tokensToMint: string, ddo: Asset) => Promise<TransactionReceipt | void>
buyDT: (
amountDataToken: number | string,
price: BestPrice,
ddo: DDO
ddo: Asset
) => Promise<TransactionReceipt | void>
pricingStep?: number
pricingStepText?: string
@ -40,28 +40,28 @@ function usePricing(): UsePricing {
const [pricingStepText, setPricingStepText] = useState<string>()
const [pricingError, setPricingError] = useState<string>()
async function getDTSymbol(ddo: DDO): Promise<string> {
async function getDTSymbol(ddo: Asset): Promise<string> {
if (!ocean || !accountId) return
const { dataToken, dataTokenInfo } = ddo
const { dataTokenInfo } = ddo
return dataTokenInfo
? dataTokenInfo.symbol
: await ocean?.datatokens.getSymbol(dataToken)
: await ocean?.datatokens.getSymbol(dataTokenInfo.address)
}
async function getDTName(ddo: DDO): Promise<string> {
async function getDTName(ddo: Asset): Promise<string> {
if (!ocean || !accountId) return
const { dataToken, dataTokenInfo } = ddo
const { dataTokenInfo } = ddo
return dataTokenInfo
? dataTokenInfo.name
: await ocean?.datatokens.getName(dataToken)
: await ocean?.datatokens.getName(dataTokenInfo.address)
}
// Helper for setting steps & feedback for all flows
async function setStep(
index: number,
type: 'pool' | 'exchange' | 'free' | 'buy' | 'dispense',
ddo: DDO
ddo: Asset
) {
const dtSymbol = await getDTSymbol(ddo)
setPricingStep(index)
@ -92,18 +92,18 @@ function usePricing(): UsePricing {
async function mint(
tokensToMint: string,
ddo: DDO
ddo: Asset
): Promise<TransactionReceipt | void> {
const { dataToken } = ddo
Logger.log('mint function', dataToken, accountId)
const { dataTokenInfo } = ddo
Logger.log('mint function', dataTokenInfo.address, accountId)
const balance = new Decimal(
await ocean.datatokens.balance(dataToken, accountId)
await ocean.datatokens.balance(dataTokenInfo.address, accountId)
)
const tokens = new Decimal(tokensToMint)
if (tokens.greaterThan(balance)) {
const mintAmount = tokens.minus(balance)
const tx = await ocean.datatokens.mint(
dataToken,
dataTokenInfo.address,
accountId,
mintAmount.toString()
)
@ -114,7 +114,7 @@ function usePricing(): UsePricing {
async function buyDT(
amountDataToken: number | string,
price: BestPrice,
ddo: DDO
ddo: Asset
): Promise<TransactionReceipt | void> {
if (!ocean || !accountId) return
@ -181,18 +181,20 @@ function usePricing(): UsePricing {
case 'free': {
setStep(1, 'dispense', ddo)
const isDispensable = await ocean.OceanDispenser.isDispensable(
ddo.dataToken,
ddo?.services[0].datatokenAddress,
accountId,
'1'
)
if (!isDispensable) {
Logger.error(`Dispenser for ${ddo.dataToken} failed to dispense`)
Logger.error(
`Dispenser for ${ddo?.services[0].datatokenAddress} failed to dispense`
)
return
}
tx = await ocean.OceanDispenser.dispense(
ddo.dataToken,
ddo?.services[0].datatokenAddress,
accountId,
'1'
)
@ -215,9 +217,9 @@ function usePricing(): UsePricing {
async function createPricing(
priceOptions: PriceOptions,
ddo: DDO
ddo: Asset
): Promise<TransactionReceipt | void> {
const { dataToken } = ddo
const dataToken = ddo?.services[0].datatokenAddress
const dtSymbol = await getDTSymbol(ddo)
if (!ocean || !accountId || !dtSymbol) return

View File

@ -1,11 +1,10 @@
import { DDO, Logger, Metadata } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import {
Service,
ServiceComputePrivacy,
ServiceType
} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service'
import { useEffect, useState } from 'react'
import { sleep } from '@utils/index'
import { publishFeedback } from '@utils/feedback'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
@ -19,12 +18,12 @@ export interface DataTokenOptions {
interface UsePublish {
publish: (
asset: Metadata,
asset: DDO,
serviceType: ServiceType,
dataTokenOptions?: DataTokenOptions,
timeout?: number,
providerUri?: string
) => Promise<DDO | undefined | null>
) => Promise<Asset>
publishStep?: number
publishStepText?: string
publishError?: string
@ -63,15 +62,15 @@ function usePublish(): UsePublish {
* @param {PriceOptions} priceOptions : number of tokens to mint, datatoken weight , liquidity fee, type : fixed, dynamic
* @param {ServiceType} serviceType Desired service type of the asset access or compute
* @param {DataTokenOptions} dataTokenOptions custom name, symbol and cap for datatoken
* @return {Promise<DDO>} Returns the newly published ddo
* @return {Promise<Asset>} Returns the newly published ddo
*/
async function publish(
asset: Metadata,
asset: Asset,
serviceType: ServiceType,
dataTokenOptions?: DataTokenOptions,
timeout?: number,
providerUri?: string
): Promise<DDO | undefined | null> {
): Promise<Asset> {
if (!ocean || !account) return null
setIsLoading(true)
setPublishError(undefined)
@ -82,7 +81,7 @@ function usePublish(): UsePublish {
new Date(Date.now()).toISOString().split('.')[0] + 'Z'
const services: Service[] = []
const price = '1'
asset.main.dateCreated = asset.main.datePublished = publishedDate
asset.created = publishedDate
switch (serviceType) {
case 'access': {
@ -125,24 +124,24 @@ function usePublish(): UsePublish {
Logger.log('services created', services)
const ddo = await ocean.assets
.create(
asset,
account,
services,
undefined,
dataTokenOptions?.cap,
dataTokenOptions?.name,
dataTokenOptions?.symbol,
providerUri
)
.next(setStep)
Logger.log('ddo created', ddo)
await ocean.assets.publishDdo(ddo, account.getId())
Logger.log('ddo published')
await sleep(20000)
setStep(7)
return ddo
// const ddo = await ocean.assets
// .create(
// asset,
// account,
// services,
// undefined,
// dataTokenOptions?.cap,
// dataTokenOptions?.name,
// dataTokenOptions?.symbol,
// providerUri
// )
// .next(setStep)
// Logger.log('ddo created', ddo)
// await ocean.assets.publishDdo(ddo, account.getId())
// Logger.log('ddo published')
// await sleep(20000)
// setStep(7)
// return ddo
} catch (error) {
setPublishError(error.message)
Logger.error(error)

33
src/@types/Asset.d.ts vendored Normal file
View File

@ -0,0 +1,33 @@
interface AssetNft {
address: string
name: string
symbol: string
owner: string
state: 0 | 1 | 2 | 3 | 4
}
interface AssetDatatoken {
name: string
symbol: string
address: string
serviceId: string
}
interface AssetLastEvent {
tx: string
block: number
from: string
contract: string
}
interface Asset extends DDO {
nft: AssetNft
datatokens: AssetDatatoken[]
event: AssetLastEvent
stats: { consume: number }
isInPurgatory: string
// This is fake and most likely won't be used like this.
// Just here so we can continue to have successful builds.
dataTokenInfo: AssetDatatoken
}

9
src/@types/DDO/Credentials.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
interface Credential {
type: string
values: string[]
}
interface Credentials {
allow: Credential[]
deny: Credential[]
}

18
src/@types/DDO/File.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
// This is all super questionable,
// but we most likely need something to represent what we get
// back from fileinfo endpoint in Provider. But then should be moved out of DDO typings.
interface FileMetadata {
url: string
contentType: string
name?: string
checksum?: string
checksumType?: string
contentLength?: string
encoding?: string
compression?: string
encrypted?: boolean
encryptionMode?: string
resourceId?: string
attributes?: { [key: string]: any }
}

24
src/@types/DDO/Metadata.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
interface MetadataAlgorithm {
language?: string
version?: string
container: {
entrypoint: string
image: string
tag: string
checksum: string
}
}
interface Metadata {
name: string
description: string
type: 'dataset' | 'algorithm'
author: string
license: string
links?: string[]
tags?: string[]
copyrightHolder?: string
contentLanguage?: string
algorithm?: MetadataAlgorithm
additionalInformation?: any
}

23
src/@types/DDO/Services.d.ts vendored Normal file
View File

@ -0,0 +1,23 @@
interface PublisherTrustedAlgorithm {
did: string
filesChecksum: string
containerSectionChecksum: string
}
interface ServiceComputePrivacy {
allowRawAlgorithm: boolean
allowNetworkAccess: boolean
publisherTrustedAlgorithmPublishers: string[]
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
}
interface Service {
type: 'access' | 'compute' | string
files: string
datatokenAddress: string
serviceEndpoint: string
timeout: string
name?: string
description?: string
privacy?: ServiceComputePrivacy
}

12
src/@types/DDO/index.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
// DDO spec
interface DDO {
'@context': string[]
id: string
version: string
chainId: number
created: string
updated?: string
metadata: Metadata
services: Service[]
credentials?: Credentials
}

View File

@ -1,12 +1,6 @@
import { DDO } from '@oceanprotocol/lib'
// declaring into global scope to be able to use this as
// ambiant types despite the above imports
declare global {
interface DownloadedAsset {
dtSymbol: string
timestamp: number
networkId: number
ddo: DDO
}
interface DownloadedAsset {
dtSymbol: string
timestamp: number
networkId: number
ddo: Asset
}

View File

@ -1,34 +0,0 @@
import {
Metadata,
AdditionalInformation,
EditableMetadataLinks
} from '@oceanprotocol/lib'
// declaring into global scope to be able to use this as
// ambiant types despite the above imports
declare global {
interface DdoMarket {
metadata: any
services: any[]
}
interface AdditionalInformationMarket extends AdditionalInformation {
termsAndConditions: boolean
}
interface MetadataMarket extends Metadata {
// While required for this market, Aquarius/Plecos will keep this as optional
// allowing external pushes of assets without `additionalInformation`.
// Making it optional here helps safeguarding against those assets.
additionalInformation?: AdditionalInformationMarket
}
interface MetadataEditForm {
name: string
description: string
timeout: string
price?: number
links?: string | EditableMetadataLinks[]
author?: string
}
}

View File

@ -1,12 +1,6 @@
import { DDO } from '@oceanprotocol/lib'
// declaring into global scope to be able to use this as
// ambiant types despite the above imports
declare global {
interface PagedAssets {
results: DDO[]
page: number
totalPages: number
totalResults: number
}
interface PagedAssets {
results: Asset[]
page: number
totalPages: number
totalResults: number
}

View File

@ -1,46 +1,41 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable camelcase */
import { DDO } from '@oceanprotocol/lib'
// declaring into global scope to be able to use this as
// ambiant types despite the above imports
declare global {
interface Explanation {
value: number
description: string
details: Explanation[]
}
interface ShardsResponse {
total: number
successful: number
failed: number
skipped: number
}
interface SearchResponse {
took: number
timed_out: boolean
_scroll_id?: string | undefined
_shards: ShardsResponse
hits: {
total: number
max_score: number
hits: Array<{
_index: string
_type: string
_id: string
_score: number
_source: DDO
_version?: number | undefined
_explanation?: Explanation | undefined
fields?: any
highlight?: any
inner_hits?: any
matched_queries?: string[] | undefined
sort?: string[] | undefined
}>
}
aggregations?: any
}
interface Explanation {
value: number
description: string
details: Explanation[]
}
interface ShardsResponse {
total: number
successful: number
failed: number
skipped: number
}
interface SearchResponse {
took: number
timed_out: boolean
_scroll_id?: string | undefined
_shards: ShardsResponse
hits: {
total: number
max_score: number
hits: Array<{
_index: string
_type: string
_id: string
_score: number
_source: Asset
_version?: number | undefined
_explanation?: Explanation | undefined
fields?: any
highlight?: any
inner_hits?: any
matched_queries?: string[] | undefined
sort?: string[] | undefined
}>
}
aggregations?: any
}

View File

@ -1,9 +1,4 @@
import {
DDO,
DID,
Logger,
publisherTrustedAlgorithm as PublisherTrustedAlgorithm
} from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
import { PriceList, getAssetsPriceList } from './subgraph'
import axios, { CancelToken, AxiosResponse } from 'axios'
@ -13,6 +8,7 @@ import {
SortDirectionOptions,
SortTermOptions
} from '../@types/aquarius/SearchQuery'
import { getServiceByName } from './ddo'
export const MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS = 476
@ -77,7 +73,7 @@ export function transformQueryResult(
}
result.results = (queryResult.hits.hits || []).map(
(hit) => new DDO(hit._source as DDO)
(hit) => hit._source as Asset
)
result.totalResults = queryResult.hits.total
result.totalPages =
@ -111,18 +107,18 @@ export async function queryMetadata(
}
export async function retrieveDDO(
did: string | DID,
did: string,
cancelToken: CancelToken
): Promise<DDO> {
): Promise<Asset> {
try {
const response: AxiosResponse<DDO> = await axios.get(
const response: AxiosResponse<Asset> = await axios.get(
`${metadataCacheUri}/api/v1/aquarius/assets/ddo/${did}`,
{ cancelToken }
)
if (!response || response.status !== 200 || !response.data) return
const data = { ...response.data }
return new DDO(data)
return data
} catch (error) {
if (axios.isCancel(error)) {
Logger.log(error.message)
@ -133,7 +129,7 @@ export async function retrieveDDO(
}
export async function getAssetsNames(
didList: string[] | DID[],
didList: string[],
cancelToken: CancelToken
): Promise<Record<string, string>> {
try {
@ -179,10 +175,10 @@ export async function retrieveDDOListByDIDs(
didList: string[],
chainIds: number[],
cancelToken: CancelToken
): Promise<DDO[]> {
): Promise<Asset[]> {
try {
if (didList?.length === 0 || chainIds?.length === 0) return []
const orderedDDOListByDIDList: DDO[] = []
const orderedDDOListByDIDList: Asset[] = []
const baseQueryparams = {
chainIds,
filters: [getFilterTerm('id', didList)],
@ -190,8 +186,8 @@ export async function retrieveDDOListByDIDs(
} as BaseQueryParams
const query = generateBaseQuery(baseQueryparams)
const result = await queryMetadata(query, cancelToken)
didList.forEach((did: string | DID) => {
const ddo: DDO = result.results.find((ddo: DDO) => ddo.id === did)
didList.forEach((did: string) => {
const ddo = result.results.find((ddo: Asset) => ddo.id === did)
orderedDDOListByDIDList.push(ddo)
})
return orderedDDOListByDIDList
@ -202,7 +198,7 @@ export async function retrieveDDOListByDIDs(
export async function transformDDOToAssetSelection(
datasetProviderEndpoint: string,
ddoList: DDO[],
ddoList: Asset[],
selectedAlgorithms?: PublisherTrustedAlgorithm[],
cancelToken?: CancelToken
): Promise<AssetSelectionAsset[]> {
@ -213,7 +209,7 @@ export async function transformDDOToAssetSelection(
for (const ddo of ddoList) {
didList.push(ddo.id)
symbolList[ddo.id] = ddo.dataTokenInfo.symbol
const algoComputeService = ddo.findServiceByType('compute')
const algoComputeService = getServiceByName(ddo, 'compute')
algoComputeService?.serviceEndpoint &&
(didProviderEndpointMap[ddo.id] = algoComputeService?.serviceEndpoint)
}
@ -350,7 +346,8 @@ export async function getDownloadAssets(
.map((ddo) => {
const order = tokenOrders.find(
({ datatokenId }) =>
datatokenId?.address.toLowerCase() === ddo.dataToken.toLowerCase()
datatokenId?.address.toLowerCase() ===
ddo.services[0].datatokenAddress.toLowerCase()
)
return {

View File

@ -1,21 +1,23 @@
import { DDO, Ocean, ServiceType } from '@oceanprotocol/lib'
import { Ocean } from '@oceanprotocol/lib'
import { getServiceByName } from './ddo'
export default async function checkPreviousOrder(
ocean: Ocean,
accountId: string,
ddo: DDO,
serviceType: ServiceType
ddo: Asset,
serviceType: 'access' | 'compute'
): Promise<string> {
if (!ocean) return
const service = ddo.findServiceByType(serviceType)
const service = getServiceByName(ddo, serviceType)
// apparenlty cost and timeout are not found, even though they are there...
const previousOrder = await ocean.datatokens.getPreviousValidOrders(
ddo.dataToken,
(service.attributes.main as any).cost,
service.index,
(service.attributes.main as any).timeout,
accountId
)
return previousOrder
// const previousOrder = await ocean.datatokens.getPreviousValidOrders(
// ddo?.services[0].datatokenAddress,
// service.cost,
// service.index,
// service.timeout,
// accountId
// )
// return previousOrder
return 'dummy'
}

View File

@ -1,7 +1,6 @@
import {
ServiceComputePrivacy,
publisherTrustedAlgorithm as PublisherTrustedAlgorithm,
DDO,
Service,
Logger,
Provider,
@ -59,7 +58,7 @@ async function getAssetMetadata(
queryDtList: string[],
cancelToken: CancelToken,
chainIds: number[]
): Promise<DDO[]> {
): Promise<Asset[]> {
const baseQueryparams = {
chainIds,
filters: [
@ -75,35 +74,37 @@ async function getAssetMetadata(
return result.results
}
function getServiceEndpoints(data: TokenOrder[], assets: DDO[]): string[] {
const serviceEndpoints: string[] = []
function getServiceEndpoints(data: TokenOrder[], assets: Asset[]): string[] {
// const serviceEndpoints: string[] = []
for (let i = 0; i < data.length; i++) {
try {
const did = web3.utils
.toChecksumAddress(data[i].datatokenId.address)
.replace('0x', 'did:op:')
const ddo = assets.filter((x) => x.id === did)[0]
if (ddo === undefined) continue
// for (let i = 0; i < data.length; i++) {
// try {
// const did = web3.utils
// .toChecksumAddress(data[i].datatokenId.address)
// .replace('0x', 'did:op:')
// const ddo = assets.filter((x) => x.id === did)[0]
// if (ddo === undefined) continue
const service = ddo.service.filter(
(x: Service) => x.index === data[i].serviceId
)[0]
// const service = ddo.services.filter(
// (x: Service) => x.index === data[i].serviceId
// )[0]
if (!service || service.type !== 'compute') continue
const { serviceEndpoint } = service
// if (!service || service.type !== 'compute') continue
// const { providerEndpoint } = service
const wasProviderQueried =
serviceEndpoints?.filter((x) => x === serviceEndpoint).length > 0
// const wasProviderQueried =
// serviceEndpoints?.filter((x) => x === providerEndpoint).length > 0
if (wasProviderQueried) continue
serviceEndpoints.push(serviceEndpoint)
} catch (err) {
Logger.error(err.message)
}
}
// if (wasProviderQueried) continue
// serviceEndpoints.push(providerEndpoint)
// } catch (err) {
// Logger.error(err.message)
// }
// }
return serviceEndpoints
// return serviceEndpoints
return ['dummy']
}
async function getProviders(
@ -138,7 +139,7 @@ async function getProviders(
async function getJobs(
providers: Provider[],
account: Account,
assets: DDO[]
assets: Asset[]
): Promise<ComputeJobMetaData[]> {
const computeJobs: ComputeJobMetaData[] = []
@ -170,13 +171,10 @@ async function getJobs(
const ddo = assets.filter((x) => x.id === did)[0]
if (!ddo) continue
const serviceMetadata = ddo.service.filter(
(x: Service) => x.type === 'metadata'
)[0]
const compJob: ComputeJobMetaData = {
...job,
assetName: serviceMetadata.attributes.main.name,
assetName: ddo.metadata.name,
assetDtSymbol: ddo.dataTokenInfo.symbol,
networkId: ddo.chainId
}
@ -205,7 +203,7 @@ export async function getComputeJobs(
config: Config,
ocean: Ocean,
account: Account,
ddo?: DDO,
ddo?: Asset,
token?: CancelToken
): Promise<ComputeResults> {
const assetDTAddress = ddo?.dataTokenInfo?.address

View File

@ -1,8 +1,15 @@
import axios from 'axios'
import { toast } from 'react-toastify'
import isUrl from 'is-url-superb'
import slugify from 'slugify'
import { MetadataAlgorithm, Logger } from '@oceanprotocol/lib'
import { MetadataAlgorithm } from '@oceanprotocol/lib'
export function getServiceByName(
ddo: Asset | DDO,
name: 'access' | 'compute'
): Service {
if (!ddo) return
const service = ddo.services.filter((service) => service.type === name)[0]
return service
}
export function dateToStringNoMS(date: Date): string {
return date.toISOString().replace(/\.[0-9]{3}Z/, 'Z')

View File

@ -1,6 +1,6 @@
import axios, { CancelToken, AxiosResponse } from 'axios'
import { toast } from 'react-toastify'
import { DID, File as FileMetadata, Logger } from '@oceanprotocol/lib'
import { DID, Logger } from '@oceanprotocol/lib'
export async function fileinfo(
url: string,

View File

@ -1,5 +1,5 @@
import { gql, OperationResult, TypedDocumentNode, OperationContext } from 'urql'
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { getUrqlClientInstance } from '@context/UrqlProvider'
import { getOceanConfig } from './ocean'
import {
@ -35,7 +35,7 @@ export interface PriceList {
}
export interface AssetListPrices {
ddo: DDO
ddo: Asset
price: BestPrice
}
@ -402,7 +402,7 @@ function transformPriceToBestPrice(
}
async function getAssetsPoolsExchangesAndDatatokenMap(
assets: DDO[]
assets: Asset[]
): Promise<
[
AssetsPoolPricePool[],
@ -415,13 +415,17 @@ async function getAssetsPoolsExchangesAndDatatokenMap(
const chainAssetLists: any = {}
for (const ddo of assets) {
didDTMap[ddo?.dataToken.toLowerCase()] = ddo.id
didDTMap[ddo?.services[0].datatokenAddress.toLowerCase()] = ddo.id
// harcoded until we have chainId on assets
if (chainAssetLists[ddo.chainId]) {
chainAssetLists[ddo.chainId].push(ddo?.dataToken.toLowerCase())
chainAssetLists[ddo.chainId].push(
ddo?.services[0].datatokenAddress.toLowerCase()
)
} else {
chainAssetLists[ddo.chainId] = []
chainAssetLists[ddo.chainId].push(ddo?.dataToken.toLowerCase())
chainAssetLists[ddo.chainId].push(
ddo?.services[0].datatokenAddress.toLowerCase()
)
}
}
let poolPriceResponse: AssetsPoolPricePool[] = []
@ -464,7 +468,7 @@ async function getAssetsPoolsExchangesAndDatatokenMap(
return [poolPriceResponse, frePriceResponse, freePriceResponse, didDTMap]
}
export async function getAssetsPriceList(assets: DDO[]): Promise<PriceList> {
export async function getAssetsPriceList(assets: Asset[]): Promise<PriceList> {
const priceList: PriceList = {}
const values: [
@ -493,15 +497,15 @@ export async function getAssetsPriceList(assets: DDO[]): Promise<PriceList> {
return priceList
}
export async function getPrice(asset: DDO): Promise<BestPrice> {
export async function getPrice(asset: Asset): Promise<BestPrice> {
const freVariables = {
datatoken: asset?.dataToken.toLowerCase()
datatoken: asset?.services[0].datatokenAddress.toLowerCase()
}
const freeVariables = {
datatoken: asset?.dataToken.toLowerCase()
datatoken: asset?.services[0].datatokenAddress.toLowerCase()
}
const poolVariables = {
datatokenAddress: asset?.dataToken.toLowerCase()
datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase()
}
const queryContext = getQueryContext(Number(asset.chainId))
@ -530,9 +534,9 @@ export async function getPrice(asset: DDO): Promise<BestPrice> {
return bestPrice
}
export async function getSpotPrice(asset: DDO): Promise<number> {
export async function getSpotPrice(asset: Asset): Promise<number> {
const poolVariables = {
datatokenAddress: asset?.dataToken.toLowerCase()
datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase()
}
const queryContext = getQueryContext(Number(asset.chainId))
@ -546,7 +550,7 @@ export async function getSpotPrice(asset: DDO): Promise<number> {
}
export async function getAssetsBestPrices(
assets: DDO[]
assets: Asset[]
): Promise<AssetListPrices[]> {
const assetsWithPrice: AssetListPrices[] = []
@ -561,7 +565,7 @@ export async function getAssetsBestPrices(
const frePriceResponse = values[1]
const freePriceResponse = values[2]
for (const ddo of assets) {
const dataToken = ddo.dataToken.toLowerCase()
const dataToken = ddo.services[0].datatokenAddress.toLowerCase()
const poolPrice: AssetsPoolPricePool[] = []
const frePrice: AssetsFrePriceFixedRateExchange[] = []
const freePrice: AssetFreePriceDispenser[] = []

View File

@ -2,7 +2,6 @@ import AssetTeaser from '@shared/AssetTeaser/AssetTeaser'
import React, { useEffect, useState } from 'react'
import Pagination from '@shared/Pagination'
import styles from './AssetList.module.css'
import { DDO } from '@oceanprotocol/lib'
import classNames from 'classnames/bind'
import { getAssetsBestPrices, AssetListPrices } from '@utils/subgraph'
import Loader from '@shared/atoms/Loader'
@ -20,7 +19,7 @@ function LoaderArea() {
}
declare type AssetListProps = {
assets: DDO[]
assets: Asset[]
showPagination: boolean
page?: number
totalPages?: number

View File

@ -1,4 +1,3 @@
import { DDO } from '@oceanprotocol/lib'
import Link from 'next/link'
import React, { ReactElement, useEffect, useState } from 'react'
import { getAssetsNames } from '@utils/aquarius'
@ -11,7 +10,7 @@ export default function AssetListTitle({
did,
title
}: {
ddo?: DDO
ddo?: Asset
did?: string
title?: string
}): ReactElement {
@ -21,8 +20,7 @@ export default function AssetListTitle({
useEffect(() => {
if (title || !appConfig.metadataCacheUri) return
if (ddo) {
const { attributes } = ddo.findServiceByType('metadata')
setAssetTitle(attributes.main.name)
setAssetTitle(ddo.metadata.name)
return
}

View File

@ -2,15 +2,15 @@ import React from 'react'
import Link from 'next/link'
import Dotdotdot from 'react-dotdotdot'
import Price from '@shared/Price'
import { DDO } from '@oceanprotocol/lib'
import removeMarkdown from 'remove-markdown'
import Publisher from '@shared/Publisher'
import AssetType from '@shared/AssetType'
import NetworkName from '@shared/NetworkName'
import styles from './AssetTeaser.module.css'
import { getServiceByName } from '@utils/ddo'
declare type AssetTeaserProps = {
ddo: DDO
ddo: Asset
price: BestPrice
noPublisher?: boolean
}
@ -20,12 +20,11 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
price,
noPublisher
}: AssetTeaserProps) => {
const { attributes } = ddo.findServiceByType('metadata')
const { name, type } = attributes.main
const { name, type, description } = ddo.metadata
const { dataTokenInfo } = ddo
const isCompute = Boolean(ddo?.findServiceByType('compute'))
const isCompute = Boolean(getServiceByName(ddo, 'compute'))
const accessType = isCompute ? 'compute' : 'access'
const { owner } = ddo.publicKey[0]
const { owner } = ddo.nft
return (
<article className={`${styles.teaser} ${styles[type]}`}>
@ -49,12 +48,7 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
<div className={styles.content}>
<Dotdotdot tagName="p" clamp={3}>
{removeMarkdown(
attributes?.additionalInformation?.description?.substring(
0,
300
) || ''
)}
{removeMarkdown(description?.substring(0, 300) || '')}
</Dotdotdot>
</div>

View File

@ -1,5 +1,4 @@
import React, { ReactElement } from 'react'
import { File as FileMetadata } from '@oceanprotocol/lib'
import filesize from 'filesize'
import classNames from 'classnames/bind'
import cleanupContentType from '@utils/cleanupContentType'

View File

@ -1,5 +1,4 @@
import React, { ReactElement, useEffect } from 'react'
import { File as FileMetadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/File'
import { prettySize } from './utils'
import cleanupContentType from '@utils/cleanupContentType'
import styles from './Info.module.css'

View File

@ -130,7 +130,7 @@ export default function InputElement({
)
case 'files':
return <FilesInput name={name} {...field} {...props} />
case 'providerUri':
case 'providerUrl':
return <CustomProvider name={name} {...field} {...props} />
case 'datatoken':
return <Datatoken name={name} {...field} {...props} />

View File

@ -13,7 +13,7 @@ import { retrieveDDOListByDIDs } from '@utils/aquarius'
import { CancelToken } from 'axios'
import Title from './Title'
import styles from './index.module.css'
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { useCancelToken } from '@hooks/useCancelToken'
const REFETCH_INTERVAL = 20000
@ -77,7 +77,7 @@ export interface Datatoken {
export interface PoolTransaction extends TransactionHistoryPoolTransactions {
networkId: number
ddo: DDO
ddo: Asset
}
const columns = [

View File

@ -26,7 +26,9 @@ export default function TokenApproval({
const config = getOceanConfig(ddo.chainId)
const tokenAddress =
coin === 'OCEAN' ? config.oceanTokenAddress : ddo.dataTokenInfo.address
coin === 'OCEAN'
? config.oceanTokenAddress
: ddo.services[0].datatokenAddress
const spender = price.address
const checkTokenApproval = useCallback(async () => {

View File

@ -4,24 +4,25 @@ import { getAlgorithmDatasetsForCompute } from '@utils/aquarius'
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
import AssetComputeList from '@shared/AssetList/AssetComputeList'
import { useAsset } from '@context/Asset'
import { DDO } from '@oceanprotocol/lib'
import { useCancelToken } from '@hooks/useCancelToken'
import { getServiceByName } from '@utils/ddo'
export default function AlgorithmDatasetsListForCompute({
algorithmDid,
dataset
}: {
algorithmDid: string
dataset: DDO
dataset: Asset
}): ReactElement {
const { type } = useAsset()
const { ddo } = useAsset()
const [datasetsForCompute, setDatasetsForCompute] =
useState<AssetSelectionAsset[]>()
const newCancelToken = useCancelToken()
useEffect(() => {
async function getDatasetsAllowedForCompute() {
const isCompute = Boolean(dataset?.findServiceByType('compute'))
const datasetComputeService = dataset.findServiceByType(
const isCompute = Boolean(getServiceByName(dataset, 'compute'))
const datasetComputeService = getServiceByName(
dataset,
isCompute ? 'compute' : 'access'
)
const datasets = await getAlgorithmDatasetsForCompute(
@ -32,8 +33,8 @@ export default function AlgorithmDatasetsListForCompute({
)
setDatasetsForCompute(datasets)
}
type === 'algorithm' && getDatasetsAllowedForCompute()
}, [type])
ddo.metadata.type === 'algorithm' && getDatasetsAllowedForCompute()
}, [ddo.metadata.type])
return (
<div className={styles.datasetsContainer}>

View File

@ -2,7 +2,6 @@ import React, { ReactElement, useEffect, useState } from 'react'
import styles from './FormComputeDataset.module.css'
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
import Input from '@shared/Form/Input'
import { DDO } from '@oceanprotocol/lib'
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
import { compareAsBN } from '@utils/numbers'
import ButtonBuy from '@shared/ButtonBuy'
@ -38,8 +37,8 @@ export default function FormStartCompute({
consumableFeedback
}: {
algorithms: AssetSelectionAsset[]
ddoListAlgorithms: DDO[]
setSelectedAlgorithm: React.Dispatch<React.SetStateAction<DDO>>
ddoListAlgorithms: Asset[]
setSelectedAlgorithm: React.Dispatch<React.SetStateAction<Asset>>
isLoading: boolean
isComputeButtonDisabled: boolean
hasPreviousOrder: boolean
@ -71,9 +70,9 @@ export default function FormStartCompute({
const [algorithmConsumableStatus, setAlgorithmConsumableStatus] =
useState<number>()
function getAlgorithmAsset(algorithmId: string): DDO {
function getAlgorithmAsset(algorithmId: string): Asset {
let assetDdo = null
ddoListAlgorithms.forEach((ddo: DDO) => {
ddoListAlgorithms.forEach((ddo: Asset) => {
if (ddo.id === algorithmId) assetDdo = ddo
})
return assetDdo
@ -87,7 +86,7 @@ export default function FormStartCompute({
if (!accountId || !isConsumable) return
async function checkIsConsumable() {
const consumable = await ocean.assets.isConsumable(
algorithmDDO,
algorithmDDO as any,
accountId.toLowerCase()
)
if (consumable) setAlgorithmConsumableStatus(consumable.status)

View File

@ -1,10 +1,5 @@
import React, { useState, ReactElement, useEffect, useCallback } from 'react'
import {
DDO,
File as FileMetadata,
Logger,
publisherTrustedAlgorithm
} from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { toast } from 'react-toastify'
import Price from '@shared/Price'
import FileIcon from '@shared/FileIcon'
@ -30,7 +25,7 @@ import axios from 'axios'
import FormStartComputeDataset from './FormComputeDataset'
import styles from './index.module.css'
import SuccessConfetti from '@shared/SuccessConfetti'
import { secondsToString } from '@utils/ddo'
import { getServiceByName, secondsToString } from '@utils/ddo'
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
import { getPreviousOrders, getPrice } from '@utils/subgraph'
@ -56,14 +51,14 @@ export default function Compute({
const { appConfig } = useSiteMetadata()
const { accountId } = useWeb3()
const { ocean, account } = useOcean()
const { price, type, ddo } = useAsset()
const { price, ddo } = useAsset()
const { buyDT, pricingError, pricingStepText } = usePricing()
const [isJobStarting, setIsJobStarting] = useState(false)
const [error, setError] = useState<string>()
const [algorithmList, setAlgorithmList] = useState<AssetSelectionAsset[]>()
const [ddoAlgorithmList, setDdoAlgorithmList] = useState<DDO[]>()
const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = useState<DDO>()
const [ddoAlgorithmList, setDdoAlgorithmList] = useState<Asset[]>()
const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = useState<Asset>()
const [hasAlgoAssetDatatoken, setHasAlgoAssetDatatoken] = useState<boolean>()
const [isPublished, setIsPublished] = useState(false)
const [hasPreviousDatasetOrder, setHasPreviousDatasetOrder] = useState(false)
@ -90,19 +85,19 @@ export default function Compute({
!hasAlgoAssetDatatoken &&
!isAlgoConsumablePrice)
const { timeout } = ddo?.services[0]
async function checkPreviousOrders(ddo: DDO) {
const { timeout } = (
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
).attributes.main
const { type } = ddo.metadata
const orderId = await getPreviousOrders(
ddo.dataToken?.toLowerCase(),
ddo.services[0].datatokenAddress?.toLowerCase(),
accountId?.toLowerCase(),
timeout.toString()
)
const assetType = ddo.findServiceByType('metadata').attributes.main.type
if (!isMounted()) return
if (assetType === 'algorithm') {
if (type === 'algorithm') {
setPreviousAlgorithmOrderId(orderId)
setHasPreviousAlgorithmOrder(!!orderId)
} else {
@ -113,7 +108,7 @@ export default function Compute({
async function checkAssetDTBalance(asset: DDO) {
const AssetDtBalance = await ocean.datatokens.balance(
asset.dataToken,
asset.services[0].datatokenAddress,
accountId
)
setalgorithmDTBalance(AssetDtBalance)
@ -121,7 +116,7 @@ export default function Compute({
}
function getQuerryString(
trustedAlgorithmList: publisherTrustedAlgorithm[],
trustedAlgorithmList: PublisherTrustedAlgorithm[],
chainId?: number
): SearchQuery {
const algorithmDidList = trustedAlgorithmList.map((x) => x.did)
@ -141,28 +136,26 @@ export default function Compute({
async function getAlgorithmList(): Promise<AssetSelectionAsset[]> {
const source = axios.CancelToken.source()
const computeService = ddo.findServiceByType('compute')
const computeService = ddo.services[0]
let algorithmSelectionList: AssetSelectionAsset[]
if (
!computeService.attributes.main.privacy ||
!computeService.attributes.main.privacy.publisherTrustedAlgorithms ||
(computeService.attributes.main.privacy.publisherTrustedAlgorithms
.length === 0 &&
!computeService.attributes.main.privacy.allowAllPublishedAlgorithms)
!computeService.privacy ||
!computeService.privacy.publisherTrustedAlgorithms ||
computeService.privacy.publisherTrustedAlgorithms.length === 0
) {
algorithmSelectionList = []
} else {
const gueryResults = await queryMetadata(
getQuerryString(
computeService.attributes.main.privacy.publisherTrustedAlgorithms,
computeService.privacy.publisherTrustedAlgorithms,
ddo.chainId
),
source.token
)
setDdoAlgorithmList(gueryResults.results)
const datasetComputeService = ddo.findServiceByType('compute')
algorithmSelectionList = await transformDDOToAssetSelection(
datasetComputeService?.serviceEndpoint,
computeService?.serviceEndpoint,
gueryResults.results,
[],
newCancelToken()
@ -171,7 +164,7 @@ export default function Compute({
return algorithmSelectionList
}
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
const initMetadata = useCallback(async (ddo: Asset): Promise<void> => {
if (!ddo) return
const price = await getPrice(ddo)
setAlgorithmPrice(price)
@ -186,6 +179,7 @@ export default function Compute({
: true
)
}, [algorithmPrice])
useEffect(() => {
if (!price) return
@ -194,12 +188,9 @@ export default function Compute({
)
}, [price])
useEffect(() => {
const { timeout } = (
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
).attributes.main
setDatasetTimeout(secondsToString(timeout))
}, [ddo])
// useEffect(() => {
// setDatasetTimeout(secondsToString(timeout))
// }, [ddo])
useEffect(() => {
if (!ddo) return
@ -218,27 +209,26 @@ export default function Compute({
initMetadata(selectedAlgorithmAsset)
const { timeout } = (
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
).attributes.main
setAlgorithmTimeout(secondsToString(timeout))
const { timeout } = ddo.services[0]
// setAlgorithmTimeout(secondsToString(timeout))
if (accountId) {
if (selectedAlgorithmAsset.findServiceByType('access')) {
if (getServiceByName(selectedAlgorithmAsset, 'access')) {
checkPreviousOrders(selectedAlgorithmAsset).then(() => {
if (
!hasPreviousAlgorithmOrder &&
selectedAlgorithmAsset.findServiceByType('compute')
getServiceByName(selectedAlgorithmAsset, 'compute')
) {
checkPreviousOrders(selectedAlgorithmAsset)
}
})
} else if (selectedAlgorithmAsset.findServiceByType('compute')) {
} else if (getServiceByName(selectedAlgorithmAsset, 'compute')) {
checkPreviousOrders(selectedAlgorithmAsset)
}
}
ocean && checkAssetDTBalance(selectedAlgorithmAsset)
}, [selectedAlgorithmAsset, ocean, accountId, hasPreviousAlgorithmOrder])
}, [ddo, selectedAlgorithmAsset, ocean, accountId, hasPreviousAlgorithmOrder])
// Output errors in toast UI
useEffect(() => {
@ -247,153 +237,153 @@ export default function Compute({
toast.error(newError)
}, [error, pricingError])
async function startJob(algorithmId: string) {
try {
if (!ocean) return
// async function startJob(algorithmId: string) {
// try {
// if (!ocean) return
setIsJobStarting(true)
setIsPublished(false)
setError(undefined)
// setIsJobStarting(true)
// setIsPublished(false)
// setError(undefined)
const computeService = ddo.findServiceByType('compute')
const serviceAlgo = selectedAlgorithmAsset.findServiceByType('access')
? selectedAlgorithmAsset.findServiceByType('access')
: selectedAlgorithmAsset.findServiceByType('compute')
// const computeService = getServiceByName(ddo, 'compute')
// const serviceAlgo = getServiceByName(selectedAlgorithmAsset, 'access')
// ? getServiceByName(selectedAlgorithmAsset, 'access')
// : getServiceByName(selectedAlgorithmAsset, 'compute')
const computeAlgorithm: ComputeAlgorithm = {
did: selectedAlgorithmAsset.id,
serviceIndex: serviceAlgo.index,
dataToken: selectedAlgorithmAsset.dataToken
}
const allowed = await ocean.compute.isOrderable(
ddo.id,
computeService.index,
computeAlgorithm
)
Logger.log('[compute] Is data set orderable?', allowed)
// const computeAlgorithm: ComputeAlgorithm = {
// did: selectedAlgorithmAsset.id,
// serviceIndex: serviceAlgo.index,
// dataToken: selectedAlgorithmAsset.services[0].datatokenAddress
// }
// const allowed = await ocean.compute.isOrderable(
// ddo.id,
// computeService.index,
// computeAlgorithm
// )
// Logger.log('[compute] Is data set orderable?', allowed)
if (!allowed) {
setError(
'Data set is not orderable in combination with selected algorithm.'
)
Logger.error(
'[compute] Error starting compute job. Dataset is not orderable in combination with selected algorithm.'
)
return
}
// if (!allowed) {
// setError(
// 'Data set is not orderable in combination with selected algorithm.'
// )
// Logger.error(
// '[compute] Error starting compute job. Dataset is not orderable in combination with selected algorithm.'
// )
// return
// }
if (!hasPreviousDatasetOrder && !hasDatatoken) {
const tx = await buyDT('1', price, ddo)
if (!tx) {
setError('Error buying datatoken.')
Logger.error('[compute] Error buying datatoken for data set ', ddo.id)
return
}
}
// if (!hasPreviousDatasetOrder && !hasDatatoken) {
// const tx = await buyDT('1', price, ddo)
// if (!tx) {
// setError('Error buying datatoken.')
// Logger.error('[compute] Error buying datatoken for data set ', ddo.id)
// return
// }
// }
if (!hasPreviousAlgorithmOrder && !hasAlgoAssetDatatoken) {
const tx = await buyDT('1', algorithmPrice, selectedAlgorithmAsset)
if (!tx) {
setError('Error buying datatoken.')
Logger.error(
'[compute] Error buying datatoken for algorithm ',
selectedAlgorithmAsset.id
)
return
}
}
// if (!hasPreviousAlgorithmOrder && !hasAlgoAssetDatatoken) {
// const tx = await buyDT('1', algorithmPrice, selectedAlgorithmAsset)
// if (!tx) {
// setError('Error buying datatoken.')
// Logger.error(
// '[compute] Error buying datatoken for algorithm ',
// selectedAlgorithmAsset.id
// )
// return
// }
// }
// TODO: pricingError is always undefined even upon errors during buyDT for whatever reason.
// So manually drop out above, but ideally could be replaced with this alone.
if (pricingError) {
setError(pricingError)
return
}
// // TODO: pricingError is always undefined even upon errors during buyDT for whatever reason.
// // So manually drop out above, but ideally could be replaced with this alone.
// if (pricingError) {
// setError(pricingError)
// return
// }
const assetOrderId = hasPreviousDatasetOrder
? previousDatasetOrderId
: await ocean.compute.orderAsset(
accountId,
ddo.id,
computeService.index,
computeAlgorithm,
appConfig.marketFeeAddress,
undefined,
null,
false
)
// const assetOrderId = hasPreviousDatasetOrder
// ? previousDatasetOrderId
// : await ocean.compute.orderAsset(
// accountId,
// ddo.id,
// computeService.index,
// computeAlgorithm,
// appConfig.marketFeeAddress,
// undefined,
// null,
// false
// )
assetOrderId &&
Logger.log(
`[compute] Got ${
hasPreviousDatasetOrder ? 'existing' : 'new'
} order ID for dataset: `,
assetOrderId
)
// assetOrderId &&
// Logger.log(
// `[compute] Got ${
// hasPreviousDatasetOrder ? 'existing' : 'new'
// } order ID for dataset: `,
// assetOrderId
// )
const algorithmAssetOrderId = hasPreviousAlgorithmOrder
? previousAlgorithmOrderId
: await ocean.compute.orderAlgorithm(
algorithmId,
serviceAlgo.type,
accountId,
serviceAlgo.index,
appConfig.marketFeeAddress,
undefined,
null,
false
)
// const algorithmAssetOrderId = hasPreviousAlgorithmOrder
// ? previousAlgorithmOrderId
// : await ocean.compute.orderAlgorithm(
// algorithmId,
// serviceAlgo.type,
// accountId,
// serviceAlgo.index,
// appConfig.marketFeeAddress,
// undefined,
// null,
// false
// )
algorithmAssetOrderId &&
Logger.log(
`[compute] Got ${
hasPreviousAlgorithmOrder ? 'existing' : 'new'
} order ID for algorithm: `,
algorithmAssetOrderId
)
// algorithmAssetOrderId &&
// Logger.log(
// `[compute] Got ${
// hasPreviousAlgorithmOrder ? 'existing' : 'new'
// } order ID for algorithm: `,
// algorithmAssetOrderId
// )
if (!assetOrderId || !algorithmAssetOrderId) {
setError('Error ordering assets.')
return
}
// if (!assetOrderId || !algorithmAssetOrderId) {
// setError('Error ordering assets.')
// return
// }
computeAlgorithm.transferTxId = algorithmAssetOrderId
Logger.log('[compute] Starting compute job.')
// computeAlgorithm.transferTxId = algorithmAssetOrderId
// Logger.log('[compute] Starting compute job.')
const output: ComputeOutput = {
publishAlgorithmLog: true,
publishOutput: true
}
const response = await ocean.compute.start(
ddo.id,
assetOrderId,
ddo.dataToken,
account,
computeAlgorithm,
output,
`${computeService.index}`,
computeService.type
)
// const output: ComputeOutput = {
// publishAlgorithmLog: true,
// publishOutput: true
// }
// const response = await ocean.compute.start(
// ddo.id,
// assetOrderId,
// ddo.services[0].datatokenAddress,
// account,
// computeAlgorithm,
// output,
// `${computeService.index}`,
// computeService.type
// )
if (!response) {
setError('Error starting compute job.')
return
}
// if (!response) {
// setError('Error starting compute job.')
// return
// }
Logger.log('[compute] Starting compute job response: ', response)
// Logger.log('[compute] Starting compute job response: ', response)
await checkPreviousOrders(selectedAlgorithmAsset)
await checkPreviousOrders(ddo)
setIsPublished(true)
} catch (error) {
await checkPreviousOrders(selectedAlgorithmAsset)
await checkPreviousOrders(ddo)
setError('Failed to start job!')
Logger.error('[compute] Failed to start job: ', error.message)
} finally {
setIsJobStarting(false)
}
}
// await checkPreviousOrders(selectedAlgorithmAsset)
// await checkPreviousOrders(ddo)
// setIsPublished(true)
// } catch (error) {
// await checkPreviousOrders(selectedAlgorithmAsset)
// await checkPreviousOrders(ddo)
// setError('Failed to start job!')
// Logger.error('[compute] Failed to start job: ', error.message)
// } finally {
// setIsJobStarting(false)
// }
// }
return (
<>
@ -402,7 +392,7 @@ export default function Compute({
<Price price={price} conversion />
</div>
{type === 'algorithm' ? (
{ddo.metadata.type === 'algorithm' ? (
<>
<Alert
text="This algorithm has been set to private by the publisher and can't be downloaded. You can run it against any allowed data sets though!"
@ -418,7 +408,9 @@ export default function Compute({
initialValues={getInitialValues()}
validateOnMount
validationSchema={validationSchema}
onSubmit={async (values) => await startJob(values.algorithm)}
onSubmit={async (values) => {
// await startJob(values.algorithm)
}}
>
<FormStartComputeDataset
algorithms={algorithmList}
@ -430,7 +422,7 @@ export default function Compute({
hasDatatoken={hasDatatoken}
dtBalance={dtBalance}
datasetLowPoolLiquidity={!isConsumablePrice}
assetType={type}
assetType={ddo.metadata.type}
assetTimeout={datasetTimeout}
hasPreviousOrderSelectedComputeAsset={hasPreviousAlgorithmOrder}
hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken}

View File

@ -1,6 +1,5 @@
import React, { ReactElement, useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { File as FileMetadata, DDO } from '@oceanprotocol/lib'
import FileIcon from '@shared/FileIcon'
import Price from '@shared/Price'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
@ -42,7 +41,7 @@ export default function Consume({
isConsumable,
consumableFeedback
}: {
ddo: DDO
ddo: Asset
file: FileMetadata
isBalanceSufficient: boolean
dtBalance: string
@ -55,7 +54,7 @@ export default function Consume({
const { appConfig } = useSiteMetadata()
const [hasPreviousOrder, setHasPreviousOrder] = useState(false)
const [previousOrderId, setPreviousOrderId] = useState<string>()
const { isInPurgatory, price, type, isAssetNetwork } = useAsset()
const { isInPurgatory, price, isAssetNetwork } = useAsset()
const { buyDT, pricingStepText, pricingError, pricingIsLoading } =
usePricing()
const { consumeStepText, consume, consumeError, isLoading } = useConsume()
@ -70,7 +69,7 @@ export default function Consume({
if (!ddo || !accountId) return
const context = getQueryContext(ddo.chainId)
const variables = {
id: ddo.dataToken?.toLowerCase(),
id: ddo.services[0].datatokenAddress?.toLowerCase(),
account: accountId?.toLowerCase()
}
fetchData(previousOrderQuery, variables, context).then((result: any) => {
@ -105,7 +104,7 @@ export default function Consume({
}, [data, assetTimeout, accountId, isAssetNetwork])
useEffect(() => {
const { timeout } = ddo.findServiceByType('access').attributes.main
const { timeout } = ddo.services[0]
setAssetTimeout(`${timeout}`)
}, [ddo])
@ -154,7 +153,7 @@ export default function Consume({
}
const error = await consume(
ddo.id,
ddo.dataToken,
ddo.services[0].datatokenAddress,
'access',
appConfig.marketFeeAddress,
previousOrderId
@ -177,12 +176,12 @@ export default function Consume({
disabled={isDisabled}
hasPreviousOrder={hasPreviousOrder}
hasDatatoken={hasDatatoken}
dtSymbol={ddo.dataTokenInfo?.symbol}
dtSymbol={ddo?.dataTokenInfo?.symbol}
dtBalance={dtBalance}
datasetLowPoolLiquidity={!isConsumablePrice}
onClick={handleConsume}
assetTimeout={secondsToString(parseInt(assetTimeout))}
assetType={type}
assetType={ddo?.metadata.type}
stepText={consumeStepText || pricingStepText}
isLoading={pricingIsLoading || isLoading}
priceType={price?.type}
@ -203,7 +202,7 @@ export default function Consume({
{!isInPurgatory && <PurchaseButton />}
</div>
</div>
{type === 'algorithm' && (
{ddo.metadata.type === 'algorithm' && (
<AlgorithmDatasetsListForCompute algorithmDid={ddo.id} dataset={ddo} />
)}
</aside>

View File

@ -1,4 +1,4 @@
import { DDO, ServiceComputePrivacy } from '@oceanprotocol/lib'
import { ServiceComputePrivacy } from '@oceanprotocol/lib'
import React, { ReactElement, useEffect, useState } from 'react'
import { useOcean } from '@context/Ocean'
import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
@ -9,7 +9,7 @@ export default function DebugEditCompute({
ddo
}: {
values: ComputePrivacyForm
ddo: DDO
ddo: Asset
}): ReactElement {
const { ocean } = useOcean()
const [formTransformed, setFormTransformed] =

View File

@ -32,59 +32,56 @@ export default function EditComputeDataset({
values: ComputePrivacyForm,
resetForm: () => void
) {
try {
if (price.type === 'free') {
const tx = await setMinterToPublisher(
ocean,
ddo.dataToken,
accountId,
setError
)
if (!tx) return
}
const privacy = await transformComputeFormToServiceComputePrivacy(
values,
ocean
)
const ddoEditedComputePrivacy = await ocean.compute.editComputePrivacy(
ddo,
1,
privacy as ServiceComputePrivacy
)
if (!ddoEditedComputePrivacy) {
setError(content.form.error)
Logger.error(content.form.error)
return
}
const storedddo = await ocean.assets.updateMetadata(
ddoEditedComputePrivacy,
accountId
)
if (!storedddo) {
setError(content.form.error)
Logger.error(content.form.error)
return
} else {
if (price.type === 'free') {
const tx = await setMinterToDispenser(
ocean,
ddo.dataToken,
accountId,
setError
)
if (!tx) return
}
// Edit succeeded
setSuccess(content.form.success)
resetForm()
}
} catch (error) {
Logger.error(error.message)
setError(error.message)
}
// try {
// if (price.type === 'free') {
// const tx = await setMinterToPublisher(
// ocean,
// ddo.services[0].datatokenAddress,
// accountId,
// setError
// )
// if (!tx) return
// }
// const privacy = await transformComputeFormToServiceComputePrivacy(
// values,
// ocean
// )
// const ddoEditedComputePrivacy = await ocean.compute.editComputePrivacy(
// ddo,
// 1,
// privacy as ServiceComputePrivacy
// )
// if (!ddoEditedComputePrivacy) {
// setError(content.form.error)
// Logger.error(content.form.error)
// return
// }
// const storedddo = await ocean.assets.updateMetadata(
// ddoEditedComputePrivacy,
// accountId
// )
// if (!storedddo) {
// setError(content.form.error)
// Logger.error(content.form.error)
// return
// } else {
// if (price.type === 'free') {
// const tx = await setMinterToDispenser(
// ocean,
// ddo.services[0].datatokenAddress,
// accountId,
// setError
// )
// if (!tx) return
// }
// // Edit succeeded
// setSuccess(content.form.success)
// resetForm()
// }
// } catch (error) {
// Logger.error(error.message)
// setError(error.message)
// }
}
return (
@ -100,7 +97,7 @@ export default function EditComputeDataset({
// move user's focus to top of screen
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
// kick off editing
// await handleSubmit(values, resetForm)
await handleSubmit(values as any, resetForm)
}}
>
{({ values, isSubmitting }) =>

View File

@ -16,6 +16,7 @@ import { useSiteMetadata } from '@hooks/useSiteMetadata'
import FormActions from './FormActions'
import { useCancelToken } from '@hooks/useCancelToken'
import { SortTermOptions } from '../../../../@types/aquarius/SearchQuery'
import { getServiceByName } from '@utils/ddo'
export default function FormEditComputeDataset({
data,
@ -31,8 +32,10 @@ export default function FormEditComputeDataset({
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
const newCancelToken = useCancelToken()
const { publisherTrustedAlgorithms } =
ddo?.findServiceByType('compute').attributes.main.privacy
const { publisherTrustedAlgorithms } = getServiceByName(
ddo,
'compute'
).privacy
async function getAlgorithmList(
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
@ -45,7 +48,7 @@ export default function FormEditComputeDataset({
const query = generateBaseQuery(baseParams)
const querryResult = await queryMetadata(query, newCancelToken())
const datasetComputeService = ddo.findServiceByType('compute')
const datasetComputeService = getServiceByName(ddo, 'compute')
const algorithmSelectionList = await transformDDOToAssetSelection(
datasetComputeService?.serviceEndpoint,
querryResult.results,

View File

@ -1,6 +1,7 @@
import { secondsToString } from '@utils/ddo'
import { EditableMetadataLinks } from '@oceanprotocol/lib'
import * as Yup from 'yup'
import { MetadataEditForm } from './_types'
export const validationSchema = Yup.object().shape({
name: Yup.string()
@ -14,16 +15,16 @@ export const validationSchema = Yup.object().shape({
})
export function getInitialValues(
metadata: MetadataMarket,
timeout: number,
metadata: Metadata,
timeout: string,
price: number
): Partial<MetadataEditForm> {
return {
name: metadata.main.name,
description: metadata.additionalInformation.description,
name: metadata.name,
description: metadata.description,
price,
timeout: secondsToString(timeout),
author: metadata.main.author
timeout,
author: metadata.author
}
}

View File

@ -0,0 +1,10 @@
import { EditableMetadataLinks } from '@oceanprotocol/lib'
export interface MetadataEditForm {
name: string
description: string
timeout: string
price?: number
links?: string | EditableMetadataLinks[]
author?: string
}

View File

@ -6,13 +6,14 @@ import { useUserPreferences } from '@context/UserPreferences'
// import Debug from './DebugEditMetadata'
import Web3Feedback from '@shared/Web3Feedback'
import FormEditMetadata from './FormEditMetadata'
import { mapTimeoutStringToSeconds } from '@utils/ddo'
import { getServiceByName, mapTimeoutStringToSeconds } from '@utils/ddo'
import styles from './index.module.css'
import { Logger } from '@oceanprotocol/lib'
import { useWeb3 } from '@context/Web3'
import { useOcean } from '@context/Ocean'
import { setMinterToDispenser, setMinterToPublisher } from '@utils/freePrice'
import content from '../../../../../content/pages/edit.json'
import { MetadataEditForm } from './_types'
export default function Edit({
setShowEdit,
@ -24,13 +25,11 @@ export default function Edit({
const { debug } = useUserPreferences()
const { accountId } = useWeb3()
const { ocean } = useOcean()
const { metadata, ddo, refreshDdo, price } = useAsset()
const { ddo, refreshDdo, price } = useAsset()
const [success, setSuccess] = useState<string>()
const [error, setError] = useState<string>()
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
const timeout = ddo.findServiceByType('access')
? ddo.findServiceByType('access').attributes.main.timeout
: ddo.findServiceByType('compute').attributes.main.timeout
const { timeout } = ddo.services[0]
const hasFeedback = error || success
@ -50,83 +49,79 @@ export default function Edit({
values: Partial<MetadataEditForm>,
resetForm: () => void
) {
try {
if (price.type === 'free') {
const tx = await setMinterToPublisher(
ocean,
ddo.dataToken,
accountId,
setError
)
if (!tx) return
}
// Construct new DDO with new values
const ddoEditedMetdata = await ocean.assets.editMetadata(ddo, {
title: values.name,
description: values.description,
links: typeof values.links !== 'string' ? values.links : [],
author: values.author === '' ? ' ' : values.author
})
price.type === 'exchange' &&
values.price !== price.value &&
(await updateFixedPrice(values.price))
if (!ddoEditedMetdata) {
setError(content.form.error)
Logger.error(content.form.error)
return
}
let ddoEditedTimeout = ddoEditedMetdata
if (timeoutStringValue !== values.timeout) {
const service =
ddoEditedMetdata.findServiceByType('access') ||
ddoEditedMetdata.findServiceByType('compute')
const timeout = mapTimeoutStringToSeconds(values.timeout)
ddoEditedTimeout = await ocean.assets.editServiceTimeout(
ddoEditedMetdata,
service.index,
timeout
)
}
if (!ddoEditedTimeout) {
setError(content.form.error)
Logger.error(content.form.error)
return
}
const storedddo = await ocean.assets.updateMetadata(
ddoEditedTimeout,
accountId
)
if (!storedddo) {
setError(content.form.error)
Logger.error(content.form.error)
return
} else {
if (price.type === 'free') {
const tx = await setMinterToDispenser(
ocean,
ddo.dataToken,
accountId,
setError
)
if (!tx) return
}
// Edit succeeded
setSuccess(content.form.success)
resetForm()
}
} catch (error) {
Logger.error(error.message)
setError(error.message)
}
// try {
// if (price.type === 'free') {
// const tx = await setMinterToPublisher(
// ocean,
// ddo.services[0].datatokenAddress,
// accountId,
// setError
// )
// if (!tx) return
// }
// // Construct new DDO with new values
// const ddoEditedMetdata = await ocean.assets.editMetadata(ddo as any, {
// title: values.name,
// description: values.description,
// links: typeof values.links !== 'string' ? values.links : [],
// author: values.author === '' ? ' ' : values.author
// })
// price.type === 'exchange' &&
// values.price !== price.value &&
// (await updateFixedPrice(values.price))
// if (!ddoEditedMetdata) {
// setError(content.form.error)
// Logger.error(content.form.error)
// return
// }
// let ddoEditedTimeout = ddoEditedMetdata
// if (timeoutStringValue !== values.timeout) {
// const service =
// getServiceByName(ddoEditedMetdata, 'access') ||
// getServiceByName(ddoEditedMetdata, 'compute')
// const timeout = mapTimeoutStringToSeconds(values.timeout)
// ddoEditedTimeout = await ocean.assets.editServiceTimeout(
// ddoEditedMetdata,
// service.index,
// timeout
// )
// }
// if (!ddoEditedTimeout) {
// setError(content.form.error)
// Logger.error(content.form.error)
// return
// }
// const storedddo = await ocean.assets.updateMetadata(
// ddoEditedTimeout,
// accountId
// )
// if (!storedddo) {
// setError(content.form.error)
// Logger.error(content.form.error)
// return
// } else {
// if (price.type === 'free') {
// const tx = await setMinterToDispenser(
// ocean,
// ddo.services[0].datatokenAddress,
// accountId,
// setError
// )
// if (!tx) return
// }
// // Edit succeeded
// setSuccess(content.form.success)
// resetForm()
// }
// } catch (error) {
// Logger.error(error.message)
// setError(error.message)
// }
}
return (
<Formik
initialValues={getInitialValues(metadata, timeout, price.value)}
initialValues={getInitialValues(ddo.metadata, timeout, price.value)}
validationSchema={validationSchema}
onSubmit={async (values, { resetForm }) => {
// move user's focus to top of screen

View File

@ -103,7 +103,7 @@ export default function Pool(): ReactElement {
const queryContext = getQueryContext(ddo.chainId)
const queryVariables = {
id: price.address.toLowerCase(),
shareId: `${price.address.toLowerCase()}-${ddo.publicKey[0].owner.toLowerCase()}`
shareId: `${price.address.toLowerCase()}-${ddo.nft.owner.toLowerCase()}`
}
const queryResult: OperationResult<PoolLiquidity> = await fetchData(
@ -172,7 +172,8 @@ export default function Pool(): ReactElement {
// Get weights
const weightDt = dataLiquidity.pool.tokens.filter(
(token: any) => token.address === ddo.dataToken.toLowerCase()
(token: any) =>
token.address === ddo.services[0].datatokenAddress.toLowerCase()
)[0].denormWeight
const weightDtDecimal = isValidNumber(weightDt)
@ -249,7 +250,7 @@ export default function Pool(): ReactElement {
refetchLiquidity()
}
init()
}, [dataLiquidity, ddo.dataToken, price.datatoken, price.ocean, price?.value])
}, [dataLiquidity, ddo, price.datatoken, price.ocean, price?.value])
useEffect(() => {
setIsRemoveDisabled(isInPurgatory && owner === accountId)
@ -360,7 +361,7 @@ export default function Pool(): ReactElement {
}}
swapFee={swapFee}
dtSymbol={dtSymbol}
dtAddress={ddo.dataToken}
dtAddress={ddo.services[0].datatokenAddress}
/>
) : showRemove ? (
<Remove
@ -388,8 +389,8 @@ export default function Pool(): ReactElement {
networkId={ddo.chainId}
path={
ddo.chainId === 2021000 || ddo.chainId === 1287
? `tokens/${ddo.dataToken}`
: `token/${ddo.dataToken}`
? `tokens/${ddo.services[0].datatokenAddress}`
: `token/${ddo.services[0].datatokenAddress}`
}
>
Datatoken

View File

@ -1,5 +1,5 @@
import React, { ReactElement, useState } from 'react'
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import * as Yup from 'yup'
import { Formik } from 'formik'
import Actions from '../Pool/Actions'
@ -23,7 +23,7 @@ export default function FormTrade({
maxOcean,
price
}: {
ddo: DDO
ddo: Asset
balance: PoolBalance
maxDt: string
maxOcean: string

View File

@ -1,5 +1,4 @@
import React, { ReactElement, useEffect, useState } from 'react'
import { DDO } from '@oceanprotocol/lib'
import styles from './Swap.module.css'
import TradeInput from './TradeInput'
import Button from '@shared/atoms/Button'
@ -26,7 +25,7 @@ export default function Swap({
setMaximumOcean,
setCoin
}: {
ddo: DDO
ddo: Asset
maxDt: string
maxOcean: string
balance: PoolBalance
@ -149,7 +148,7 @@ export default function Swap({
setTotalValue(newValue)
setTokenAmount(value.toString())
tokenIn = ddo.dataToken
tokenIn = ddo.services[0].datatokenAddress
tokenOut = ocean.pool.oceanAddress
} else {
newValue = await ocean.pool.getDTReceived(
@ -160,7 +159,7 @@ export default function Swap({
setTotalValue(value.toString())
setTokenAmount(newValue)
tokenIn = ocean.pool.oceanAddress
tokenOut = ddo.dataToken
tokenOut = ddo.services[0].datatokenAddress
}
} else {
if (values.type === 'sell') {
@ -171,7 +170,7 @@ export default function Swap({
setTotalValue(value.toString())
setTokenAmount(newValue)
tokenIn = ddo.dataToken
tokenIn = ddo.services[0].datatokenAddress
tokenOut = ocean.pool.oceanAddress
} else {
newValue = await ocean.pool.getOceanNeeded(
@ -182,7 +181,7 @@ export default function Swap({
setTotalValue(newValue)
setTokenAmount(value.toString())
tokenIn = ocean.pool.oceanAddress
tokenOut = ddo.dataToken
tokenOut = ddo.services[0].datatokenAddress
}
}

View File

@ -25,19 +25,22 @@ export default function Trade(): ReactElement {
!isAssetNetwork ||
!balance?.ocean ||
!accountId ||
!ddo?.dataToken
!ddo?.services[0].datatokenAddress
)
return
async function getTokenBalance() {
const dtBalance = await ocean.datatokens.balance(ddo.dataToken, accountId)
const dtBalance = await ocean.datatokens.balance(
ddo.services[0].datatokenAddress,
accountId
)
setTokenBalance({
ocean: new Decimal(balance.ocean).toString(),
datatoken: new Decimal(dtBalance).toString()
})
}
getTokenBalance()
}, [balance.ocean, ocean, accountId, ddo.dataToken])
}, [balance.ocean, ocean, accountId, ddo, isAssetNetwork])
// Get maximum amount for either OCEAN or datatoken
useEffect(() => {

View File

@ -1,7 +1,7 @@
import React, { ReactElement, useState, useEffect } from 'react'
import Compute from './Compute'
import Consume from './Consume'
import { Logger, File as FileMetadata, DID } from '@oceanprotocol/lib'
import { Logger, DID } from '@oceanprotocol/lib'
import Tabs from '@shared/atoms/Tabs'
import { compareAsBN } from '@utils/numbers'
import Pool from './Pool'
@ -25,27 +25,30 @@ export default function AssetActions(): ReactElement {
const [dtBalance, setDtBalance] = useState<string>()
const [fileMetadata, setFileMetadata] = useState<FileMetadata>(Object)
const [fileIsLoading, setFileIsLoading] = useState<boolean>(false)
const isCompute = Boolean(ddo?.findServiceByType('compute'))
const isCompute = Boolean(
ddo?.services.filter((service) => service.type === 'compute')[0]
)
const [isConsumable, setIsConsumable] = useState<boolean>(true)
const [consumableFeedback, setConsumableFeedback] = useState<string>('')
const newCancelToken = useCancelToken()
const isMounted = useIsMounted()
useEffect(() => {
if (!ddo || !accountId || !ocean || !isAssetNetwork) return
async function checkIsConsumable() {
const consumable = await ocean.assets.isConsumable(
ddo,
accountId.toLowerCase()
)
if (consumable) {
setIsConsumable(consumable.result)
setConsumableFeedback(consumable.message)
}
}
checkIsConsumable()
}, [accountId, isAssetNetwork, ddo, ocean])
// useEffect(() => {
// if (!ddo || !accountId || !ocean || !isAssetNetwork) return
// async function checkIsConsumable() {
// const consumable = await ocean.assets.isConsumable(
// ddo,
// accountId.toLowerCase()
// )
// if (consumable) {
// setIsConsumable(consumable.result)
// setConsumableFeedback(consumable.message)
// }
// }
// checkIsConsumable()
// }, [accountId, isAssetNetwork, ddo, ocean])
useEffect(() => {
const oceanConfig = getOceanConfig(ddo.chainId)
@ -74,7 +77,7 @@ export default function AssetActions(): ReactElement {
async function init() {
try {
const dtBalance = await ocean.datatokens.balance(
ddo.dataToken,
ddo.services[0].datatokenAddress,
accountId
)
setDtBalance(dtBalance)
@ -83,7 +86,7 @@ export default function AssetActions(): ReactElement {
}
}
init()
}, [ocean, accountId, ddo.dataToken, isAssetNetwork])
}, [ocean, accountId, ddo, isAssetNetwork])
// Check user balance against price
useEffect(() => {

View File

@ -37,7 +37,7 @@ export default function EditHistory(): ReactElement {
const [result] = useQuery({
query: getReceipts,
variables: { address: ddo?.dataToken.toLowerCase() },
variables: { address: ddo?.services[0].datatokenAddress.toLowerCase() },
context: queryContext,
pause: !ddo || !queryContext
})

View File

@ -5,22 +5,20 @@ import Publisher from '@shared/Publisher'
import { useAsset } from '@context/Asset'
export default function MetaFull(): ReactElement {
const { ddo, metadata, isInPurgatory, type } = useAsset()
const { algorithm } = ddo.findServiceByType('metadata').attributes.main
const { ddo, isInPurgatory } = useAsset()
const { type, author, algorithm } = ddo?.metadata
function DockerImage() {
const { image, tag } = algorithm.container
const { image, tag } = algorithm?.container
return <span>{`${image}:${tag}`}</span>
}
return (
<div className={styles.metaFull}>
{!isInPurgatory && (
<MetaItem title="Data Author" content={metadata?.main.author} />
)}
{!isInPurgatory && <MetaItem title="Data Author" content={author} />}
<MetaItem
title="Owner"
content={<Publisher account={ddo?.publicKey[0].owner} />}
content={<Publisher account={ddo?.nft?.owner} />}
/>
{type === 'algorithm' && algorithm && (

View File

@ -7,12 +7,13 @@ import AddToken from '@shared/AddToken'
import Time from '@shared/atoms/Time'
import AssetType from '@shared/AssetType'
import styles from './MetaMain.module.css'
import { getServiceByName } from '@utils/ddo'
export default function MetaMain(): ReactElement {
const { ddo, owner, type, isAssetNetwork } = useAsset()
const { ddo, owner, isAssetNetwork } = useAsset()
const { web3ProviderInfo } = useWeb3()
const isCompute = Boolean(ddo?.findServiceByType('compute'))
const isCompute = Boolean(getServiceByName(ddo, 'compute'))
const accessType = isCompute ? 'compute' : 'access'
const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285]
const isBlockscoutExplorer = blockscoutNetworks.includes(ddo?.chainId)
@ -21,7 +22,7 @@ export default function MetaMain(): ReactElement {
<aside className={styles.meta}>
<header className={styles.asset}>
<AssetType
type={type}
type={ddo?.metadata.type}
accessType={accessType}
className={styles.assetType}
/>
@ -30,8 +31,8 @@ export default function MetaMain(): ReactElement {
networkId={ddo?.chainId}
path={
isBlockscoutExplorer
? `tokens/${ddo?.dataToken}`
: `token/${ddo?.dataToken}`
? `tokens/${ddo?.services[0].datatokenAddress}`
: `token/${ddo?.services[0].datatokenAddress}`
}
>
{`${ddo?.dataTokenInfo.name}${ddo?.dataTokenInfo.symbol}`}
@ -40,7 +41,7 @@ export default function MetaMain(): ReactElement {
{web3ProviderInfo?.name === 'MetaMask' && isAssetNetwork && (
<span className={styles.addWrap}>
<AddToken
address={ddo?.dataTokenInfo.address}
address={ddo?.services[0].datatokenAddress}
symbol={ddo?.dataTokenInfo.symbol}
logo="https://raw.githubusercontent.com/oceanprotocol/art/main/logo/datatoken.png"
text={`Add ${ddo?.dataTokenInfo.symbol} to wallet`}

View File

@ -19,26 +19,19 @@ const SampleButton = ({ url }: { url: string }) => (
)
export default function MetaSecondary(): ReactElement {
const { metadata } = useAsset()
const { ddo } = useAsset()
return (
<aside className={styles.metaSecondary}>
{metadata?.additionalInformation?.links?.length > 0 && (
{ddo?.metadata.links?.length > 0 && (
<div className={styles.samples}>
<MetaItem
title="Sample Data"
content={
<SampleButton
url={metadata?.additionalInformation?.links[0].url}
/>
}
content={<SampleButton url={ddo?.metadata.links[0]} />}
/>
</div>
)}
{metadata?.additionalInformation?.tags?.length > 0 && (
<Tags items={metadata?.additionalInformation?.tags} />
)}
{ddo?.metadata?.tags?.length > 0 && <Tags items={ddo?.metadata?.tags} />}
</aside>
)
}

View File

@ -17,31 +17,27 @@ import { useWeb3 } from '@context/Web3'
import styles from './index.module.css'
import NetworkName from '@shared/NetworkName'
import content from '../../../../content/purgatory.json'
import { DDO } from '@oceanprotocol/lib'
export default function AssetContent({ ddo }: { ddo: DDO }): ReactElement {
export default function AssetContent({ ddo }: { ddo: Asset }): ReactElement {
const { debug } = useUserPreferences()
const { accountId } = useWeb3()
const {
price,
metadata,
type,
owner,
isInPurgatory,
purgatoryData,
isAssetNetwork
} = useAsset()
const { price, owner, isInPurgatory, purgatoryData, isAssetNetwork } =
useAsset()
const [showEdit, setShowEdit] = useState<boolean>()
const [isComputeType, setIsComputeType] = useState<boolean>(false)
const [showEditCompute, setShowEditCompute] = useState<boolean>()
const [isOwner, setIsOwner] = useState(false)
const serviceCompute = ddo.services.filter(
(service) => service.type === 'compute'
)[0]
useEffect(() => {
if (!accountId || !owner) return
const isOwner = accountId.toLowerCase() === owner.toLowerCase()
setIsOwner(isOwner)
setIsComputeType(Boolean(ddo.findServiceByType('compute')))
setIsComputeType(Boolean(serviceCompute))
}, [accountId, price, owner, ddo])
function handleEditButton() {
@ -79,7 +75,7 @@ export default function AssetContent({ ddo }: { ddo: DDO }): ReactElement {
<>
<Markdown
className={styles.description}
text={metadata?.additionalInformation?.description || ''}
text={ddo?.metadata.description || ''}
/>
<MetaSecondary />
@ -93,7 +89,7 @@ export default function AssetContent({ ddo }: { ddo: DDO }): ReactElement {
>
Edit Metadata
</Button>
{ddo.findServiceByType('compute') && type === 'dataset' && (
{serviceCompute && ddo?.metadata.type === 'dataset' && (
<>
<span className={styles.separator}>|</span>
<Button

View File

@ -15,8 +15,8 @@ const columns = [
{
name: 'Data Set',
selector: function getAssetRow(row: AssetListPrices) {
const { attributes } = row.ddo.findServiceByType('metadata')
return <AssetTitle title={attributes.main.name} ddo={row.ddo} />
const { metadata } = row.ddo
return <AssetTitle title={metadata.name} ddo={row.ddo} />
},
maxWidth: '45rem',
grow: 1

View File

@ -8,7 +8,7 @@ import {
queryMetadata
} from '@utils/aquarius'
import { getHighestLiquidityDatatokens } from '@utils/subgraph'
import { DDO, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { useUserPreferences } from '@context/UserPreferences'
import styles from './index.module.css'
import { useIsMounted } from '@hooks/useIsMounted'
@ -31,11 +31,11 @@ async function getQueryHighest(
return [queryHighest, dtList]
}
function sortElements(items: DDO[], sorted: string[]) {
function sortElements(items: Asset[], sorted: string[]) {
items.sort(function (a, b) {
return (
sorted.indexOf(a.dataToken.toLowerCase()) -
sorted.indexOf(b.dataToken.toLowerCase())
sorted.indexOf(a.services[0].datatokenAddress.toLowerCase()) -
sorted.indexOf(b.services[0].datatokenAddress.toLowerCase())
)
})
return items

View File

@ -48,9 +48,7 @@ function DetailsAssets({ job }: { job: ComputeJobMetaData }) {
async function getAlgoMetadata() {
const ddo = await retrieveDDO(job.algoDID, newCancelToken())
setAlgoDtSymbol(ddo.dataTokenInfo.symbol)
const { attributes } = ddo.findServiceByType('metadata')
setAlgoName(attributes?.main.name)
setAlgoName(ddo?.metadata.name)
}
getAlgoMetadata()
}, [appConfig.metadataCacheUri, job.algoDID])

View File

@ -16,7 +16,6 @@ import { CancelToken } from 'axios'
import { isValidNumber } from '@utils/numbers'
import Decimal from 'decimal.js'
import { useProfile } from '@context/Profile'
import { DDO } from '@oceanprotocol/lib'
import { useCancelToken } from '@hooks/useCancelToken'
import { useIsMounted } from '@hooks/useIsMounted'
import { useUserPreferences } from '@context/UserPreferences'
@ -25,12 +24,12 @@ Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
const REFETCH_INTERVAL = 20000
interface Asset {
interface AssetPoolShare {
userLiquidity: number
poolShare: PoolShare
networkId: number
createTime: number
ddo: DDO
ddo: Asset
}
function findTokenByType(tokens: PoolSharePoolIdTokens[], type: string) {
@ -46,7 +45,7 @@ function Symbol({ tokens }: { tokens: PoolSharePoolIdTokens[] }) {
return <>{findTokenByType(tokens, 'datatoken')}</>
}
function Liquidity({ row, type }: { row: Asset; type: string }) {
function Liquidity({ row, type }: { row: AssetPoolShare; type: string }) {
let price = ``
let oceanTokenBalance = ''
let dataTokenBalance = ''
@ -98,33 +97,33 @@ function Liquidity({ row, type }: { row: Asset; type: string }) {
const columns = [
{
name: 'Data Set',
selector: function getAssetRow(row: Asset) {
selector: function getAssetRow(row: AssetPoolShare) {
return <AssetTitle ddo={row.ddo} />
},
grow: 2
},
{
name: 'Network',
selector: function getNetwork(row: Asset) {
selector: function getNetwork(row: AssetPoolShare) {
return <NetworkName networkId={row.networkId} />
}
},
{
name: 'Datatoken',
selector: function getSymbol(row: Asset) {
selector: function getSymbol(row: AssetPoolShare) {
return <Symbol tokens={row.poolShare.poolId.tokens} />
}
},
{
name: 'Liquidity',
selector: function getAssetRow(row: Asset) {
selector: function getAssetRow(row: AssetPoolShare) {
return <Liquidity row={row} type="user" />
},
right: true
},
{
name: 'Pool Liquidity',
selector: function getAssetRow(row: Asset) {
selector: function getAssetRow(row: AssetPoolShare) {
return <Liquidity row={row} type="pool" />
},
right: true
@ -138,7 +137,7 @@ async function getPoolSharesAssets(
) {
if (data.length < 1) return
const assetList: Asset[] = []
const assetList: AssetPoolShare[] = []
const didList: string[] = []
for (let i = 0; i < data.length; i++) {
@ -169,7 +168,7 @@ export default function PoolShares({
accountId: string
}): ReactElement {
const { poolShares, isPoolSharesLoading } = useProfile()
const [assets, setAssets] = useState<Asset[]>()
const [assets, setAssets] = useState<AssetPoolShare[]>()
const [loading, setLoading] = useState<boolean>(false)
const [dataFetchInterval, setDataFetchInterval] = useState<NodeJS.Timeout>()
const { chainIds } = useUserPreferences()

View File

@ -1,5 +1,4 @@
import React, { FormEvent, ReactElement, useState } from 'react'
import { File as FileMetadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/File'
import Markdown from '@shared/Markdown'
import Tags from '@shared/atoms/Tags'
import MetaItem from '../../Asset/AssetContent/MetaItem'

View File

@ -1,6 +1,5 @@
import React, { ReactElement, useEffect } from 'react'
import { useFormikContext } from 'formik'
import { DDO } from '@oceanprotocol/lib'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import Tabs from '@shared/atoms/Tabs'
import { isValidNumber } from '@utils/numbers'

View File

@ -37,9 +37,9 @@ export default function ServicesFields(): ReactElement {
name="services[0].dataTokenOptions"
/>
<Field
{...getFieldContent('providerUri', content.services.fields)}
{...getFieldContent('providerUrl', content.services.fields)}
component={Input}
name="services[0].providerUri"
name="services[0].providerUrl"
/>
<Field
{...getFieldContent('files', content.services.fields)}

View File

@ -1,5 +1,4 @@
import React from 'react'
import { File as FileMetadata } from '@oceanprotocol/lib'
import * as Yup from 'yup'
import { allowDynamicPricing, allowFixedPricing } from '../../../app.config.js'
import { FormPublishData, StepContent } from './_types'
@ -34,6 +33,7 @@ export const wizardSteps: StepContent[] = [
export const initialValues: Partial<FormPublishData> = {
step: 1,
chainId: 1,
metadata: {
type: 'dataset',
name: '',
@ -49,7 +49,7 @@ export const initialValues: Partial<FormPublishData> = {
dataTokenOptions: { name: '', symbol: '' },
timeout: 'Forever',
access: '',
providerUri: ''
providerUrl: ''
}
],
pricing: {
@ -96,7 +96,7 @@ const validationService = {
access: Yup.string()
.matches(/Compute|Download/g, { excludeEmptyString: true })
.required('Required'),
providerUri: Yup.string().url().nullable()
providerUrl: Yup.string().url().nullable()
}
const validationPricing = {
@ -124,6 +124,7 @@ const validationPricing = {
// export const validationSchema: Yup.SchemaOf<FormPublishData> =
export const validationSchema: Yup.SchemaOf<any> = Yup.object().shape({
step: Yup.number(),
chainId: Yup.number(),
metadata: Yup.object().shape(validationMetadata),
services: Yup.array().of(Yup.object().shape(validationService)),
pricing: Yup.object().shape(validationPricing)

View File

@ -1,23 +1,22 @@
import { DataTokenOptions } from '@hooks/usePublish'
import { EditableMetadataLinks, File } from '@oceanprotocol/lib'
import { ReactElement } from 'react'
export interface FormPublishService {
files: string | File[]
links?: string | EditableMetadataLinks[]
files: string | FileMetadata[]
links?: string[]
timeout: string
dataTokenOptions: DataTokenOptions
access: 'Download' | 'Compute' | string
image?: string
containerTag?: string
entrypoint?: string
providerUri?: string
providerUrl?: string
}
export interface FormPublishData {
step: number
metadata: {
type: 'dataset' | 'algorithm' | string
type: 'dataset' | 'algorithm'
name: string
description: string
author: string
@ -26,6 +25,7 @@ export interface FormPublishData {
}
services: FormPublishService[]
pricing: PriceOptions
chainId: number
}
export interface StepContent {

View File

@ -6,6 +6,10 @@ import {
} from '@utils/ddo'
import { FormPublishData } from './_types'
function encryptMe(files: string | FileMetadata[]): string {
throw new Error('Function not implemented.')
}
export function getFieldContent(
fieldName: string,
fields: FormFieldContent[]
@ -13,41 +17,55 @@ export function getFieldContent(
return fields.filter((field: FormFieldContent) => field.name === fieldName)[0]
}
export function transformPublishFormToDdo(
data: Partial<FormPublishData>,
ddo?: DdoMarket
): DdoMarket {
export function transformPublishFormToDdo(data: Partial<FormPublishData>): DDO {
const currentTime = dateToStringNoMS(new Date())
const { type } = data
const { type } = data.metadata
const { name, description, tags, author, termsAndConditions } = data.metadata
const { files, links, image, containerTag, entrypoint, providerUri } =
data.services[0]
const fileUrl = typeof files !== 'string' && files[0].url
const algorithmLanguage = getAlgorithmFileExtension(fileUrl)
const algorithm = getAlgorithmComponent(
const {
access,
files,
links,
image,
containerTag,
entrypoint,
algorithmLanguage
)
providerUrl,
timeout
} = data.services[0]
const service = {
files: typeof files !== 'string' && files,
links: typeof links !== 'string' ? links : [],
...(type === 'algorithm' && { ...algorithm })
const fileUrl = typeof files !== 'string' && files[0].url
const filesEncrypted = encryptMe(files)
const service: Service = {
type: access,
files: filesEncrypted,
datatokenAddress: '',
serviceEndpoint: providerUrl,
timeout
}
const newDdo: DdoMarket = {
const newDdo: DDO = {
'@context': [''],
id: '',
version: '4.0.0',
created: currentTime,
chainId: data.chainId,
metadata: {
type,
name,
description,
tags: transformTags(tags),
author,
dateCreated: ddo ? ddo.metadata.dateCreated : currentTime,
datePublished: '',
termsAndConditions,
license: 'https://market.oceanprotocol.com/terms'
license: 'https://market.oceanprotocol.com/terms',
links,
...(type === 'algorithm' && {
...getAlgorithmComponent(
image,
containerTag,
entrypoint,
getAlgorithmFileExtension(fileUrl)
)
})
},
services: [service]
}

View File

@ -30,7 +30,7 @@ export default function PublishPage({
}: {
content: { title: string; description: string; warning: string }
}): ReactElement {
const { accountId } = useWeb3()
const { accountId, chainId } = useWeb3()
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
const { publish, publishError, isLoading, publishStepText } = usePublish()
const [success, setSuccess] = useState<string>()
@ -101,7 +101,9 @@ export default function PublishPage({
// await handleSubmit(values, resetForm)
}}
>
{({ values }) => {
{({ values, setFieldValue }) => {
setFieldValue('chainId', chainId)
return (
<>
<Form className={styles.form} ref={scrollToRef}>