mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
merge v4 into v4-c2d
This commit is contained in:
commit
0085174e8d
@ -406,7 +406,7 @@ The style can be changed by altering the `style` prop in the `PrivacyPreferenceC
|
|||||||
## 🏛 License
|
## 🏛 License
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Copyright 2021 Ocean Protocol Foundation Ltd.
|
Copyright 2022 Ocean Protocol Foundation Ltd.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
36
package-lock.json
generated
36
package-lock.json
generated
@ -4668,6 +4668,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/abi-utils": {
|
"node_modules/@truffle/abi-utils": {
|
||||||
"version": "0.2.9",
|
"version": "0.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.9.tgz",
|
||||||
|
"integrity": "sha512-Nv4MGsA2vdI7G34nI0DfR/eSd5pbAUu+5EafYNqzgrS46y0LWhbIrSZ1NcM7cbhIrkpUn6OfNk49AjNM67TkSg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"change-case": "3.0.2",
|
"change-case": "3.0.2",
|
||||||
@ -4681,6 +4683,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/codec": {
|
"node_modules/@truffle/codec": {
|
||||||
"version": "0.11.27",
|
"version": "0.11.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.27.tgz",
|
||||||
|
"integrity": "sha512-zPlbrGSZ975jscoJ4NhQpaJGwJXkasnpSoUAEjzppr6FCLKtutxssy6yfz4EUHaQDTg1SqxlVBfBhqYcrCyjvw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@truffle/abi-utils": "^0.2.9",
|
"@truffle/abi-utils": "^0.2.9",
|
||||||
@ -4750,6 +4754,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/compile-common": {
|
"node_modules/@truffle/compile-common": {
|
||||||
"version": "0.7.28",
|
"version": "0.7.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.28.tgz",
|
||||||
|
"integrity": "sha512-mZCEQ6fkOqbKYCJDT82q0vZCxOEsKRQ0zrPfKuSJEb0gF9DXIQcnMkyJpBSWzmyvien9/A7/jPiGQoC7PmNEUg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@truffle/error": "^0.1.0",
|
"@truffle/error": "^0.1.0",
|
||||||
@ -4758,6 +4764,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/contract": {
|
"node_modules/@truffle/contract": {
|
||||||
"version": "4.4.9",
|
"version": "4.4.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.4.9.tgz",
|
||||||
|
"integrity": "sha512-LSIxnpFDr824wUp4tiw2UHmDPr8io5UnzjlZX/QKuNIq+BB+JPRmkzItjwtvWzzIG3QOAGiqjtIgp1U6Mab/bw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ensdomains/ensjs": "^2.0.1",
|
"@ensdomains/ensjs": "^2.0.1",
|
||||||
@ -4778,6 +4786,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/contract-schema": {
|
"node_modules/@truffle/contract-schema": {
|
||||||
"version": "3.4.5",
|
"version": "3.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.5.tgz",
|
||||||
|
"integrity": "sha512-heaGV9QWqef259HaF+0is/tsmhlZIbUSWhqvj0iwKmxoN92fghKijWwdVYhPIbsmGlrQuwPTZHSCnaOlO+gsFg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.10.0",
|
"ajv": "^6.10.0",
|
||||||
@ -5083,6 +5093,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@truffle/debug-utils": {
|
"node_modules/@truffle/debug-utils": {
|
||||||
"version": "6.0.9",
|
"version": "6.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.9.tgz",
|
||||||
|
"integrity": "sha512-CVKVsbEWE0TzmTdGcxEeQvNhTKxkojIRox3LWh2Z8ZARtPiWwYl/lmPqfugh1665xmc2NVLI9qyP4ygVFPkvIQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@truffle/codec": "^0.11.27",
|
"@truffle/codec": "^0.11.27",
|
||||||
@ -5543,6 +5555,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@trufflesuite/chromafi": {
|
"node_modules/@trufflesuite/chromafi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"camelcase": "^4.1.0",
|
"camelcase": "^4.1.0",
|
||||||
@ -13451,6 +13465,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/he": {
|
"node_modules/he": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -18744,6 +18760,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/simple-get": {
|
"node_modules/simple-get": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decompress-response": "^3.3.0",
|
"decompress-response": "^3.3.0",
|
||||||
@ -24635,6 +24653,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/abi-utils": {
|
"@truffle/abi-utils": {
|
||||||
"version": "0.2.9",
|
"version": "0.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.9.tgz",
|
||||||
|
"integrity": "sha512-Nv4MGsA2vdI7G34nI0DfR/eSd5pbAUu+5EafYNqzgrS46y0LWhbIrSZ1NcM7cbhIrkpUn6OfNk49AjNM67TkSg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"change-case": "3.0.2",
|
"change-case": "3.0.2",
|
||||||
"faker": "^5.3.1",
|
"faker": "^5.3.1",
|
||||||
@ -24646,6 +24666,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/codec": {
|
"@truffle/codec": {
|
||||||
"version": "0.11.27",
|
"version": "0.11.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.27.tgz",
|
||||||
|
"integrity": "sha512-zPlbrGSZ975jscoJ4NhQpaJGwJXkasnpSoUAEjzppr6FCLKtutxssy6yfz4EUHaQDTg1SqxlVBfBhqYcrCyjvw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@truffle/abi-utils": "^0.2.9",
|
"@truffle/abi-utils": "^0.2.9",
|
||||||
"@truffle/compile-common": "^0.7.28",
|
"@truffle/compile-common": "^0.7.28",
|
||||||
@ -24705,6 +24727,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/compile-common": {
|
"@truffle/compile-common": {
|
||||||
"version": "0.7.28",
|
"version": "0.7.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.28.tgz",
|
||||||
|
"integrity": "sha512-mZCEQ6fkOqbKYCJDT82q0vZCxOEsKRQ0zrPfKuSJEb0gF9DXIQcnMkyJpBSWzmyvien9/A7/jPiGQoC7PmNEUg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@truffle/error": "^0.1.0",
|
"@truffle/error": "^0.1.0",
|
||||||
"colors": "1.4.0"
|
"colors": "1.4.0"
|
||||||
@ -24712,6 +24736,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/contract": {
|
"@truffle/contract": {
|
||||||
"version": "4.4.9",
|
"version": "4.4.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.4.9.tgz",
|
||||||
|
"integrity": "sha512-LSIxnpFDr824wUp4tiw2UHmDPr8io5UnzjlZX/QKuNIq+BB+JPRmkzItjwtvWzzIG3QOAGiqjtIgp1U6Mab/bw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ensdomains/ensjs": "^2.0.1",
|
"@ensdomains/ensjs": "^2.0.1",
|
||||||
"@truffle/blockchain-utils": "^0.1.0",
|
"@truffle/blockchain-utils": "^0.1.0",
|
||||||
@ -24945,6 +24971,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/contract-schema": {
|
"@truffle/contract-schema": {
|
||||||
"version": "3.4.5",
|
"version": "3.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.5.tgz",
|
||||||
|
"integrity": "sha512-heaGV9QWqef259HaF+0is/tsmhlZIbUSWhqvj0iwKmxoN92fghKijWwdVYhPIbsmGlrQuwPTZHSCnaOlO+gsFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^6.10.0",
|
"ajv": "^6.10.0",
|
||||||
"debug": "^4.3.1"
|
"debug": "^4.3.1"
|
||||||
@ -24952,6 +24980,8 @@
|
|||||||
},
|
},
|
||||||
"@truffle/debug-utils": {
|
"@truffle/debug-utils": {
|
||||||
"version": "6.0.9",
|
"version": "6.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.9.tgz",
|
||||||
|
"integrity": "sha512-CVKVsbEWE0TzmTdGcxEeQvNhTKxkojIRox3LWh2Z8ZARtPiWwYl/lmPqfugh1665xmc2NVLI9qyP4ygVFPkvIQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@truffle/codec": "^0.11.27",
|
"@truffle/codec": "^0.11.27",
|
||||||
"@trufflesuite/chromafi": "^3.0.0",
|
"@trufflesuite/chromafi": "^3.0.0",
|
||||||
@ -25319,6 +25349,8 @@
|
|||||||
},
|
},
|
||||||
"@trufflesuite/chromafi": {
|
"@trufflesuite/chromafi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"camelcase": "^4.1.0",
|
"camelcase": "^4.1.0",
|
||||||
"chalk": "^2.3.2",
|
"chalk": "^2.3.2",
|
||||||
@ -30872,6 +30904,8 @@
|
|||||||
},
|
},
|
||||||
"he": {
|
"he": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"header-case": {
|
"header-case": {
|
||||||
@ -34237,6 +34271,8 @@
|
|||||||
},
|
},
|
||||||
"simple-get": {
|
"simple-get": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"decompress-response": "^3.3.0",
|
"decompress-response": "^3.3.0",
|
||||||
"once": "^1.3.1",
|
"once": "^1.3.1",
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
import {
|
import { Asset, LoggerInstance } from '@oceanprotocol/lib'
|
||||||
Asset,
|
|
||||||
LoggerInstance,
|
|
||||||
PublisherTrustedAlgorithm
|
|
||||||
} from '@oceanprotocol/lib'
|
|
||||||
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
||||||
import { PriceList } from './subgraph'
|
|
||||||
import axios, { CancelToken, AxiosResponse } from 'axios'
|
import axios, { CancelToken, AxiosResponse } from 'axios'
|
||||||
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
|
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
|
||||||
import { metadataCacheUri } from '../../app.config'
|
import { metadataCacheUri } from '../../app.config'
|
||||||
@ -12,7 +7,7 @@ import {
|
|||||||
SortDirectionOptions,
|
SortDirectionOptions,
|
||||||
SortTermOptions
|
SortTermOptions
|
||||||
} from '../@types/aquarius/SearchQuery'
|
} from '../@types/aquarius/SearchQuery'
|
||||||
import { getServiceByName } from './ddo'
|
import { transformAssetToAssetSelection } from './assetConvertor'
|
||||||
|
|
||||||
export const MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS = 476
|
export const MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS = 476
|
||||||
|
|
||||||
@ -202,58 +197,6 @@ export async function retrieveDDOListByDIDs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transformDDOToAssetSelection(
|
|
||||||
datasetProviderEndpoint: string,
|
|
||||||
ddoList: Asset[],
|
|
||||||
selectedAlgorithms?: PublisherTrustedAlgorithm[],
|
|
||||||
cancelToken?: CancelToken
|
|
||||||
): Promise<AssetSelectionAsset[]> {
|
|
||||||
const didList: string[] = []
|
|
||||||
// const priceList: PriceList = await getAssetsPriceList(ddoList)
|
|
||||||
const priceList: PriceList = null
|
|
||||||
const symbolList: any = {}
|
|
||||||
const didProviderEndpointMap: any = {}
|
|
||||||
for (const ddo of ddoList) {
|
|
||||||
didList.push(ddo.id)
|
|
||||||
symbolList[ddo.id] = ddo.datatokens[0].symbol
|
|
||||||
const algoComputeService = getServiceByName(ddo, 'compute')
|
|
||||||
algoComputeService?.serviceEndpoint &&
|
|
||||||
(didProviderEndpointMap[ddo.id] = algoComputeService?.serviceEndpoint)
|
|
||||||
}
|
|
||||||
const ddoNames = await getAssetsNames(didList, cancelToken)
|
|
||||||
const algorithmList: AssetSelectionAsset[] = []
|
|
||||||
didList?.forEach((did: string) => {
|
|
||||||
if (
|
|
||||||
priceList[did] &&
|
|
||||||
(!didProviderEndpointMap[did] ||
|
|
||||||
didProviderEndpointMap[did] === datasetProviderEndpoint)
|
|
||||||
) {
|
|
||||||
let selected = false
|
|
||||||
selectedAlgorithms?.forEach((algorithm: PublisherTrustedAlgorithm) => {
|
|
||||||
if (algorithm.did === did) {
|
|
||||||
selected = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
selected
|
|
||||||
? algorithmList.unshift({
|
|
||||||
did: did,
|
|
||||||
name: ddoNames[did],
|
|
||||||
price: priceList[did],
|
|
||||||
checked: selected,
|
|
||||||
symbol: symbolList[did]
|
|
||||||
})
|
|
||||||
: algorithmList.push({
|
|
||||||
did: did,
|
|
||||||
name: ddoNames[did],
|
|
||||||
price: priceList[did],
|
|
||||||
checked: selected,
|
|
||||||
symbol: symbolList[did]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return algorithmList
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAlgorithmDatasetsForCompute(
|
export async function getAlgorithmDatasetsForCompute(
|
||||||
algorithmId: string,
|
algorithmId: string,
|
||||||
datasetProviderUri: string,
|
datasetProviderUri: string,
|
||||||
@ -264,7 +207,7 @@ export async function getAlgorithmDatasetsForCompute(
|
|||||||
chainIds: [datasetChainId],
|
chainIds: [datasetChainId],
|
||||||
filters: [
|
filters: [
|
||||||
getFilterTerm(
|
getFilterTerm(
|
||||||
'service.attributes.main.privacy.publisherTrustedAlgorithms.did',
|
'service.compite.publisherTrustedAlgorithms.did',
|
||||||
algorithmId
|
algorithmId
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -279,11 +222,10 @@ export async function getAlgorithmDatasetsForCompute(
|
|||||||
|
|
||||||
if (computeDatasets.totalResults === 0) return []
|
if (computeDatasets.totalResults === 0) return []
|
||||||
|
|
||||||
const datasets = await transformDDOToAssetSelection(
|
const datasets = await transformAssetToAssetSelection(
|
||||||
datasetProviderUri,
|
datasetProviderUri,
|
||||||
computeDatasets.results,
|
computeDatasets.results,
|
||||||
[],
|
[]
|
||||||
cancelToken
|
|
||||||
)
|
)
|
||||||
return datasets
|
return datasets
|
||||||
}
|
}
|
||||||
|
43
src/@utils/assetConvertor.ts
Normal file
43
src/@utils/assetConvertor.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { getAccessDetailsForAssets } from './accessDetailsAndPricing'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { PublisherTrustedAlgorithm, Asset } from '@oceanprotocol/lib'
|
||||||
|
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
||||||
|
import { getServiceByName } from './ddo'
|
||||||
|
|
||||||
|
export async function transformAssetToAssetSelection(
|
||||||
|
datasetProviderEndpoint: string,
|
||||||
|
assets: Asset[],
|
||||||
|
selectedAlgorithms?: PublisherTrustedAlgorithm[]
|
||||||
|
): Promise<AssetSelectionAsset[]> {
|
||||||
|
const extendedAssets: AssetExtended[] = await getAccessDetailsForAssets(
|
||||||
|
assets
|
||||||
|
)
|
||||||
|
const algorithmList: AssetSelectionAsset[] = []
|
||||||
|
|
||||||
|
for (const asset of extendedAssets) {
|
||||||
|
const algoComputeService = getServiceByName(asset, 'compute')
|
||||||
|
|
||||||
|
if (
|
||||||
|
asset?.accessDetails.price &&
|
||||||
|
algoComputeService?.serviceEndpoint === datasetProviderEndpoint
|
||||||
|
) {
|
||||||
|
let selected = false
|
||||||
|
selectedAlgorithms?.forEach((algorithm: PublisherTrustedAlgorithm) => {
|
||||||
|
if (algorithm.did === asset.id) {
|
||||||
|
selected = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const algorithmAsset: AssetSelectionAsset = {
|
||||||
|
did: asset.id,
|
||||||
|
name: asset.datatokens[0].name,
|
||||||
|
price: asset.accessDetails.price,
|
||||||
|
checked: selected,
|
||||||
|
symbol: asset.datatokens[0].symbol
|
||||||
|
}
|
||||||
|
selected
|
||||||
|
? algorithmList.unshift(algorithmAsset)
|
||||||
|
: algorithmList.push(algorithmAsset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return algorithmList
|
||||||
|
}
|
@ -1,11 +1,20 @@
|
|||||||
|
// import {
|
||||||
|
// ServiceComputePrivacy,
|
||||||
|
// publisherTrustedAlgorithm as PublisherTrustedAlgorithm,
|
||||||
|
// Service,
|
||||||
|
// LoggerInstance,
|
||||||
|
// Provider,
|
||||||
|
// Config,
|
||||||
|
// Ocean,
|
||||||
|
// Account
|
||||||
|
// } from '@oceanprotocol/lib'
|
||||||
|
// import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
|
||||||
import {
|
import {
|
||||||
Asset,
|
Asset,
|
||||||
DDO,
|
ServiceComputeOptions,
|
||||||
ComputeAlgorithm,
|
PublisherTrustedAlgorithm,
|
||||||
Service,
|
getHash,
|
||||||
LoggerInstance,
|
LoggerInstance
|
||||||
ProviderInstance,
|
|
||||||
PublisherTrustedAlgorithm
|
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { CancelToken } from 'axios'
|
import { CancelToken } from 'axios'
|
||||||
import { gql } from 'urql'
|
import { gql } from 'urql'
|
||||||
@ -13,7 +22,7 @@ import {
|
|||||||
queryMetadata,
|
queryMetadata,
|
||||||
getFilterTerm,
|
getFilterTerm,
|
||||||
generateBaseQuery,
|
generateBaseQuery,
|
||||||
transformDDOToAssetSelection
|
retrieveDDOListByDIDs
|
||||||
} from './aquarius'
|
} from './aquarius'
|
||||||
import { fetchDataForMultipleChains } from './subgraph'
|
import { fetchDataForMultipleChains } from './subgraph'
|
||||||
import { getServiceById, getServiceByName } from './ddo'
|
import { getServiceById, getServiceByName } from './ddo'
|
||||||
@ -364,37 +373,50 @@ function getServiceEndpoints(data: TokenOrder[], assets: Asset[]): string[] {
|
|||||||
// return computeResult
|
// return computeResult
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// export async function createTrustedAlgorithmList(
|
export async function createTrustedAlgorithmList(
|
||||||
// selectedAlgorithms: string[], // list of DIDs
|
selectedAlgorithms: string[], // list of DIDs,
|
||||||
// ocean: Ocean
|
assetChainId: number,
|
||||||
// ): Promise<PublisherTrustedAlgorithm[]> {
|
cancelToken: CancelToken
|
||||||
// const trustedAlgorithms = []
|
): Promise<PublisherTrustedAlgorithm[]> {
|
||||||
|
const trustedAlgorithms: PublisherTrustedAlgorithm[] = []
|
||||||
|
|
||||||
// for (const selectedAlgorithm of selectedAlgorithms) {
|
const selectedAssets = await retrieveDDOListByDIDs(
|
||||||
// const trustedAlgorithm =
|
selectedAlgorithms,
|
||||||
// await ocean.compute.createPublisherTrustedAlgorithmfromDID(
|
[assetChainId],
|
||||||
// selectedAlgorithm
|
cancelToken
|
||||||
// )
|
)
|
||||||
// trustedAlgorithms.push(trustedAlgorithm)
|
|
||||||
// }
|
|
||||||
// return trustedAlgorithms
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export async function transformComputeFormToServiceComputePrivacy(
|
for (const selectedAlgorithm of selectedAssets) {
|
||||||
// values: ComputePrivacyForm,
|
const trustedAlgorithm = {
|
||||||
// ocean: Ocean
|
did: selectedAlgorithm.id,
|
||||||
// ): Promise<ServiceComputePrivacy> {
|
containerSectionChecksum: getHash(
|
||||||
// const { allowAllPublishedAlgorithms } = values
|
JSON.stringify(selectedAlgorithm.metadata.algorithm.container)
|
||||||
// const publisherTrustedAlgorithms = values.allowAllPublishedAlgorithms
|
),
|
||||||
// ? []
|
filesChecksum: getHash(selectedAlgorithm.services[0].files)
|
||||||
// : await createTrustedAlgorithmList(values.publisherTrustedAlgorithms, ocean)
|
}
|
||||||
|
trustedAlgorithms.push(trustedAlgorithm)
|
||||||
|
}
|
||||||
|
return trustedAlgorithms
|
||||||
|
}
|
||||||
|
|
||||||
// const privacy: ServiceComputePrivacy = {
|
export async function transformComputeFormToServiceComputeOptions(
|
||||||
// allowNetworkAccess: false,
|
values: ComputePrivacyForm,
|
||||||
// allowRawAlgorithm: false,
|
currentOptions: ServiceComputeOptions,
|
||||||
// allowAllPublishedAlgorithms,
|
assetChainId: number,
|
||||||
// publisherTrustedAlgorithms
|
cancelToken: CancelToken
|
||||||
// }
|
): Promise<ServiceComputeOptions> {
|
||||||
|
const publisherTrustedAlgorithms = values.allowAllPublishedAlgorithms
|
||||||
|
? []
|
||||||
|
: await createTrustedAlgorithmList(
|
||||||
|
values.publisherTrustedAlgorithms,
|
||||||
|
assetChainId,
|
||||||
|
cancelToken
|
||||||
|
)
|
||||||
|
|
||||||
// return privacy
|
const privacy: ServiceComputeOptions = {
|
||||||
// }
|
...currentOptions,
|
||||||
|
publisherTrustedAlgorithms
|
||||||
|
}
|
||||||
|
|
||||||
|
return privacy
|
||||||
|
}
|
||||||
|
48
src/@utils/dispenser.ts
Normal file
48
src/@utils/dispenser.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { LoggerInstance, Dispenser, Datatoken } from '@oceanprotocol/lib'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import { TransactionReceipt } from 'web3-core'
|
||||||
|
|
||||||
|
export async function setMinterToPublisher(
|
||||||
|
web3: Web3,
|
||||||
|
dispenserAddress: string,
|
||||||
|
datatokenAddress: string,
|
||||||
|
accountId: string,
|
||||||
|
setError: (msg: string) => void
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
const dispenserInstance = new Dispenser(web3, dispenserAddress)
|
||||||
|
const status = await dispenserInstance.status(datatokenAddress)
|
||||||
|
if (!status?.active) return
|
||||||
|
|
||||||
|
const datatokenInstance = new Datatoken(web3)
|
||||||
|
|
||||||
|
const response = await datatokenInstance.removeMinter(
|
||||||
|
datatokenAddress,
|
||||||
|
accountId,
|
||||||
|
accountId
|
||||||
|
)
|
||||||
|
if (!response) {
|
||||||
|
setError('Updating DDO failed.')
|
||||||
|
LoggerInstance.error('Failed at cancelMinter')
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setMinterToDispenser(
|
||||||
|
web3: Web3,
|
||||||
|
datatokenAddress: string,
|
||||||
|
accountId: string,
|
||||||
|
setError: (msg: string) => void
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
const datatokenInstance = new Datatoken(web3)
|
||||||
|
|
||||||
|
const response = await datatokenInstance.addMinter(
|
||||||
|
datatokenAddress,
|
||||||
|
accountId,
|
||||||
|
accountId
|
||||||
|
)
|
||||||
|
if (!response) {
|
||||||
|
setError('Updating DDO failed.')
|
||||||
|
LoggerInstance.error('Failed at makeMinter')
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
@ -11,6 +11,13 @@ export function getOrderFeedback(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCollectTokensFeedback(
|
||||||
|
baseTokenSymbol: string,
|
||||||
|
baseTokenBalance: string
|
||||||
|
) {
|
||||||
|
return `Collecting ${baseTokenBalance} ${baseTokenSymbol} from asset `
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: customize for compute
|
// TODO: customize for compute
|
||||||
export const computeFeedback: { [key in number]: string } = {
|
export const computeFeedback: { [key in number]: string } = {
|
||||||
0: 'Ordering asset...',
|
0: 'Ordering asset...',
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
import { SvgWaves } from './SvgWaves'
|
import { SvgWaves } from './SvgWaves'
|
||||||
|
import {
|
||||||
|
Asset,
|
||||||
|
LoggerInstance,
|
||||||
|
getHash,
|
||||||
|
Nft,
|
||||||
|
ProviderInstance,
|
||||||
|
DDO
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import { TransactionReceipt } from 'web3-core'
|
||||||
|
|
||||||
// https://docs.opensea.io/docs/metadata-standards
|
// https://docs.opensea.io/docs/metadata-standards
|
||||||
export interface NftMetadata {
|
export interface NftMetadata {
|
||||||
@ -71,3 +81,50 @@ export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
|||||||
|
|
||||||
return nftCreateData
|
return nftCreateData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setNftMetadata(
|
||||||
|
asset: Asset | DDO,
|
||||||
|
accountId: string,
|
||||||
|
web3: Web3,
|
||||||
|
signal: AbortSignal
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
const encryptedDdo = await ProviderInstance.encrypt(
|
||||||
|
asset,
|
||||||
|
asset.services[0].serviceEndpoint,
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
LoggerInstance.log('[setNftMetadata] Got encrypted DDO', encryptedDdo)
|
||||||
|
|
||||||
|
const metadataHash = getHash(JSON.stringify(asset))
|
||||||
|
const nft = new Nft(web3)
|
||||||
|
|
||||||
|
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
||||||
|
const flags = '0x2'
|
||||||
|
|
||||||
|
const estGasSetMetadata = await nft.estGasSetMetadata(
|
||||||
|
asset.nftAddress,
|
||||||
|
accountId,
|
||||||
|
0,
|
||||||
|
asset.services[0].serviceEndpoint,
|
||||||
|
'',
|
||||||
|
flags,
|
||||||
|
encryptedDdo,
|
||||||
|
'0x' + metadataHash,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('[setNftMetadata] est Gas set metadata --', estGasSetMetadata)
|
||||||
|
|
||||||
|
const setMetadataTx = await nft.setMetadata(
|
||||||
|
asset.nftAddress,
|
||||||
|
accountId,
|
||||||
|
0,
|
||||||
|
asset.services[0].serviceEndpoint,
|
||||||
|
'',
|
||||||
|
flags,
|
||||||
|
encryptedDdo,
|
||||||
|
'0x' + metadataHash
|
||||||
|
)
|
||||||
|
|
||||||
|
return setMetadataTx
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
OrdersData_orders_datatoken as OrdersDatatoken
|
OrdersData_orders_datatoken as OrdersDatatoken
|
||||||
} from '../@types/subgraph/OrdersData'
|
} from '../@types/subgraph/OrdersData'
|
||||||
import { UserSalesQuery as UsersSalesList } from '../@types/subgraph/UserSalesQuery'
|
import { UserSalesQuery as UsersSalesList } from '../@types/subgraph/UserSalesQuery'
|
||||||
|
import { OpcFeesQuery as OpcFeesData } from '../@types/subgraph/OpcFeesQuery'
|
||||||
|
|
||||||
export interface UserLiquidity {
|
export interface UserLiquidity {
|
||||||
price: string
|
price: string
|
||||||
@ -188,6 +189,17 @@ const TopSalesQuery = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const OpcFeesQuery = gql`
|
||||||
|
query OpcFeesQuery($id: ID!) {
|
||||||
|
opc(id: $id) {
|
||||||
|
swapOceanFee
|
||||||
|
swapNonOceanFee
|
||||||
|
consumeFee
|
||||||
|
providerFee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export function getSubgraphUri(chainId: number): string {
|
export function getSubgraphUri(chainId: number): string {
|
||||||
const config = getOceanConfig(chainId)
|
const config = getOceanConfig(chainId)
|
||||||
return config.subgraphUri
|
return config.subgraphUri
|
||||||
@ -242,6 +254,26 @@ export async function fetchDataForMultipleChains(
|
|||||||
return datas
|
return datas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getOpcFees(chainId: number) {
|
||||||
|
let opcFees
|
||||||
|
const variables = {
|
||||||
|
id: 1
|
||||||
|
}
|
||||||
|
const context = getQueryContext(chainId)
|
||||||
|
try {
|
||||||
|
const response: OperationResult<OpcFeesData> = await fetchData(
|
||||||
|
OpcFeesQuery,
|
||||||
|
variables,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
opcFees = response?.data?.opc
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetchData: ', error.message)
|
||||||
|
throw Error(error.message)
|
||||||
|
}
|
||||||
|
return opcFees
|
||||||
|
}
|
||||||
|
|
||||||
export async function getPreviousOrders(
|
export async function getPreviousOrders(
|
||||||
id: string,
|
id: string,
|
||||||
account: string,
|
account: string,
|
||||||
|
@ -4,7 +4,7 @@ import styles from './index.module.css'
|
|||||||
import Loader from '../atoms/Loader'
|
import Loader from '../atoms/Loader'
|
||||||
|
|
||||||
interface ButtonBuyProps {
|
interface ButtonBuyProps {
|
||||||
action: 'download' | 'compute'
|
action: 'download' | 'compute' | 'collect'
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
hasPreviousOrder: boolean
|
hasPreviousOrder: boolean
|
||||||
hasDatatoken: boolean
|
hasDatatoken: boolean
|
||||||
@ -153,6 +153,8 @@ export default function ButtonBuy({
|
|||||||
? 'Start Compute Job'
|
? 'Start Compute Job'
|
||||||
: priceType === 'free' && algorithmPriceType === 'free'
|
: priceType === 'free' && algorithmPriceType === 'free'
|
||||||
? 'Order Compute Job'
|
? 'Order Compute Job'
|
||||||
|
: action === 'collect'
|
||||||
|
? `Collect ${dtBalance} ${dtSymbol}`
|
||||||
: `Buy Compute Job`
|
: `Buy Compute Job`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
|
||||||
import { useField, useFormikContext } from 'formik'
|
import { useField, useFormikContext } from 'formik'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import FileInfo from './Info'
|
import FileInfo from './Info'
|
||||||
@ -13,24 +13,43 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const { values } = useFormikContext<FormPublishData>()
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
function loadFileInfo(url: string) {
|
const loadFileInfo = useCallback(
|
||||||
const providerUri = values.services[0].providerUrl.url
|
(url: string) => {
|
||||||
|
const providerUri =
|
||||||
|
(values.services && values.services[0].providerUrl.url) ||
|
||||||
|
'https://provider.mainnet.oceanprotocol.com'
|
||||||
|
|
||||||
async function validateUrl() {
|
async function validateUrl() {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
const checkedFile = await getFileUrlInfo(url, providerUri)
|
const checkedFile = await getFileUrlInfo(url, providerUri)
|
||||||
checkedFile && helpers.setValue([{ url, ...checkedFile[0] }])
|
checkedFile && helpers.setValue([{ url, ...checkedFile[0] }])
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('Could not fetch file info. Please check URL and try again')
|
toast.error(
|
||||||
console.error(error.message)
|
'Could not fetch file info. Please check URL and try again'
|
||||||
} finally {
|
)
|
||||||
setIsLoading(false)
|
console.error(error.message)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
validateUrl()
|
validateUrl()
|
||||||
}
|
},
|
||||||
|
[helpers, values.services]
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// try load from initial values, kinda hacky but it works
|
||||||
|
if (
|
||||||
|
props.value &&
|
||||||
|
props.value.length > 0 &&
|
||||||
|
typeof props.value[0] === 'string'
|
||||||
|
) {
|
||||||
|
console.log('loadFileInfo eff')
|
||||||
|
loadFileInfo(props.value[0].toString())
|
||||||
|
}
|
||||||
|
}, [loadFileInfo, props])
|
||||||
|
|
||||||
async function handleButtonClick(e: React.SyntheticEvent, url: string) {
|
async function handleButtonClick(e: React.SyntheticEvent, url: string) {
|
||||||
// File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
|
// File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
|
||||||
|
@ -38,8 +38,6 @@
|
|||||||
color: var(--brand-grey-light);
|
color: var(--brand-grey-light);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
/* for hiding spin buttons in Firefox */
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input[readonly]::-webkit-inner-spin-button,
|
.input[readonly]::-webkit-inner-spin-button,
|
||||||
|
@ -29,8 +29,7 @@ import { useWeb3 } from '@context/Web3'
|
|||||||
import {
|
import {
|
||||||
generateBaseQuery,
|
generateBaseQuery,
|
||||||
getFilterTerm,
|
getFilterTerm,
|
||||||
queryMetadata,
|
queryMetadata
|
||||||
transformDDOToAssetSelection
|
|
||||||
} from '@utils/aquarius'
|
} from '@utils/aquarius'
|
||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import { getInitialValues, validationSchema } from './_constants'
|
import { getInitialValues, validationSchema } from './_constants'
|
||||||
@ -59,6 +58,7 @@ import { TransactionReceipt } from 'web3-core'
|
|||||||
import { useAbortController } from '@hooks/useAbortController'
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
||||||
import { AccessDetails } from 'src/@types/Price'
|
import { AccessDetails } from 'src/@types/Price'
|
||||||
|
import { transformAssetToAssetSelection } from '@utils/assetConvertor'
|
||||||
|
|
||||||
export default function Compute({
|
export default function Compute({
|
||||||
asset,
|
asset,
|
||||||
@ -143,6 +143,54 @@ export default function Compute({
|
|||||||
setHasAlgoAssetDatatoken(Number(AssetDtBalance) >= 1)
|
setHasAlgoAssetDatatoken(Number(AssetDtBalance) >= 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getQuerryString(
|
||||||
|
trustedAlgorithmList: PublisherTrustedAlgorithm[],
|
||||||
|
chainId?: number
|
||||||
|
): SearchQuery {
|
||||||
|
const algorithmDidList = trustedAlgorithmList.map((x) => x.did)
|
||||||
|
|
||||||
|
const baseParams = {
|
||||||
|
chainIds: [chainId],
|
||||||
|
sort: { sortBy: SortTermOptions.Created },
|
||||||
|
filters: [
|
||||||
|
getFilterTerm('service.attributes.main.type', 'algorithm'),
|
||||||
|
getFilterTerm('id', algorithmDidList)
|
||||||
|
]
|
||||||
|
} as BaseQueryParams
|
||||||
|
|
||||||
|
const query = generateBaseQuery(baseParams)
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAlgorithmList(): Promise<AssetSelectionAsset[]> {
|
||||||
|
const source = axios.CancelToken.source()
|
||||||
|
const computeService = ddo.services[0]
|
||||||
|
let algorithmSelectionList: AssetSelectionAsset[]
|
||||||
|
if (
|
||||||
|
!computeService.compute ||
|
||||||
|
!computeService.compute.publisherTrustedAlgorithms ||
|
||||||
|
computeService.compute.publisherTrustedAlgorithms.length === 0
|
||||||
|
) {
|
||||||
|
algorithmSelectionList = []
|
||||||
|
} else {
|
||||||
|
const gueryResults = await queryMetadata(
|
||||||
|
getQuerryString(
|
||||||
|
computeService.compute.publisherTrustedAlgorithms,
|
||||||
|
ddo.chainId
|
||||||
|
),
|
||||||
|
source.token
|
||||||
|
)
|
||||||
|
setDdoAlgorithmList(gueryResults.results)
|
||||||
|
|
||||||
|
algorithmSelectionList = await transformAssetToAssetSelection(
|
||||||
|
computeService?.serviceEndpoint,
|
||||||
|
gueryResults.results,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return algorithmSelectionList
|
||||||
|
}
|
||||||
|
|
||||||
const initMetadata = useCallback(async (asset: Asset): Promise<void> => {
|
const initMetadata = useCallback(async (asset: Asset): Promise<void> => {
|
||||||
if (!asset) return
|
if (!asset) return
|
||||||
const accessDetails = await getAccessDetails(
|
const accessDetails = await getAccessDetails(
|
||||||
|
@ -16,3 +16,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: calc(var(--spacer));
|
margin-top: calc(var(--spacer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collect {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: calc(var(--spacer) / 2);
|
||||||
|
}
|
||||||
|
@ -7,16 +7,37 @@ import ButtonBuy from '@shared/ButtonBuy'
|
|||||||
import { secondsToString } from '@utils/ddo'
|
import { secondsToString } from '@utils/ddo'
|
||||||
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
||||||
import styles from './Download.module.css'
|
import styles from './Download.module.css'
|
||||||
import { FileMetadata, LoggerInstance, ZERO_ADDRESS } from '@oceanprotocol/lib'
|
import {
|
||||||
|
FileMetadata,
|
||||||
|
LoggerInstance,
|
||||||
|
ZERO_ADDRESS,
|
||||||
|
FixedRateExchange
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
import { order } from '@utils/order'
|
import { order } from '@utils/order'
|
||||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
import { buyDtFromPool, calculateBuyPrice } from '@utils/pool'
|
import { buyDtFromPool } from '@utils/pool'
|
||||||
import { downloadFile } from '@utils/provider'
|
import { downloadFile } from '@utils/provider'
|
||||||
import { getOrderFeedback } from '@utils/feedback'
|
import { getCollectTokensFeedback, getOrderFeedback } from '@utils/feedback'
|
||||||
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
||||||
import { OrderPriceAndFees } from 'src/@types/Price'
|
import { OrderPriceAndFees } from 'src/@types/Price'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
import { gql, OperationResult } from 'urql'
|
||||||
|
import { fetchData, getQueryContext } from '@utils/subgraph'
|
||||||
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import { FixedRateExchanges } from 'src/@types/subgraph/FixedRateExchanges'
|
||||||
|
|
||||||
|
const FixedRateExchangesQuery = gql`
|
||||||
|
query FixedRateExchanges($user: String, $exchangeId: String) {
|
||||||
|
fixedRateExchanges(where: { owner: $user, exchangeId: $exchangeId }) {
|
||||||
|
id
|
||||||
|
owner {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
exchangeId
|
||||||
|
baseTokenBalance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
export default function Download({
|
export default function Download({
|
||||||
asset,
|
asset,
|
||||||
file,
|
file,
|
||||||
@ -40,6 +61,9 @@ export default function Download({
|
|||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [isOwned, setIsOwned] = useState(false)
|
const [isOwned, setIsOwned] = useState(false)
|
||||||
const [validOrderTx, setValidOrderTx] = useState('')
|
const [validOrderTx, setValidOrderTx] = useState('')
|
||||||
|
const [isCollectLoading, setIsCollectLoading] = useState(false)
|
||||||
|
const [baseTokenBalance, setBaseTokenBalance] = useState(0)
|
||||||
|
const [collectStatusText, setCollectStatusText] = useState('')
|
||||||
const [orderPriceAndFees, setOrderPriceAndFees] =
|
const [orderPriceAndFees, setOrderPriceAndFees] =
|
||||||
useState<OrderPriceAndFees>()
|
useState<OrderPriceAndFees>()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,6 +104,29 @@ export default function Download({
|
|||||||
isOwned
|
isOwned
|
||||||
])
|
])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!accountId || asset.nft.owner !== accountId) return
|
||||||
|
const queryContext = getQueryContext(Number(asset.chainId))
|
||||||
|
|
||||||
|
async function getBaseTokenBalance() {
|
||||||
|
const variables = {
|
||||||
|
user: accountId.toLowerCase(),
|
||||||
|
exchangeId: asset?.accessDetails?.addressOrId
|
||||||
|
}
|
||||||
|
const result: OperationResult<FixedRateExchanges> = await fetchData(
|
||||||
|
FixedRateExchangesQuery,
|
||||||
|
variables,
|
||||||
|
queryContext
|
||||||
|
)
|
||||||
|
result?.data?.fixedRateExchanges[0]?.baseTokenBalance
|
||||||
|
? setBaseTokenBalance(
|
||||||
|
parseInt(result?.data?.fixedRateExchanges[0]?.baseTokenBalance)
|
||||||
|
)
|
||||||
|
: setBaseTokenBalance(0)
|
||||||
|
}
|
||||||
|
getBaseTokenBalance()
|
||||||
|
}, [accountId, asset?.accessDetails?.addressOrId, asset.chainId, asset.nft])
|
||||||
|
|
||||||
async function handleOrderOrDownload() {
|
async function handleOrderOrDownload() {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
if (isOwned) {
|
if (isOwned) {
|
||||||
@ -127,6 +174,37 @@ export default function Download({
|
|||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleCollectTokens() {
|
||||||
|
setIsCollectLoading(true)
|
||||||
|
const config = getOceanConfig(asset?.chainId)
|
||||||
|
const fixed = new FixedRateExchange(web3, config.fixedRateExchangeAddress)
|
||||||
|
try {
|
||||||
|
setCollectStatusText(
|
||||||
|
getCollectTokensFeedback(
|
||||||
|
asset.accessDetails.baseToken?.symbol,
|
||||||
|
baseTokenBalance.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const tx = await fixed.collectBT(
|
||||||
|
accountId,
|
||||||
|
asset?.accessDetails?.addressOrId
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!tx) {
|
||||||
|
setIsCollectLoading(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBaseTokenBalance(0)
|
||||||
|
return tx
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.log(error.message)
|
||||||
|
setIsCollectLoading(false)
|
||||||
|
} finally {
|
||||||
|
setIsCollectLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const PurchaseButton = () => (
|
const PurchaseButton = () => (
|
||||||
<ButtonBuy
|
<ButtonBuy
|
||||||
action="download"
|
action="download"
|
||||||
@ -149,6 +227,26 @@ export default function Download({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const CollectTokensButton = () => (
|
||||||
|
<ButtonBuy
|
||||||
|
action="collect"
|
||||||
|
onClick={handleCollectTokens}
|
||||||
|
disabled={baseTokenBalance === 0 || !baseTokenBalance}
|
||||||
|
hasPreviousOrder={false}
|
||||||
|
hasDatatoken={false}
|
||||||
|
dtSymbol={asset?.accessDetails?.baseToken.symbol}
|
||||||
|
dtBalance={baseTokenBalance.toString()}
|
||||||
|
datasetLowPoolLiquidity={false}
|
||||||
|
assetType=""
|
||||||
|
stepText={collectStatusText}
|
||||||
|
assetTimeout=""
|
||||||
|
isConsumable={false}
|
||||||
|
consumableFeedback=""
|
||||||
|
isBalanceSufficient={false}
|
||||||
|
isLoading={isCollectLoading}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={styles.consume}>
|
<aside className={styles.consume}>
|
||||||
<div className={styles.info}>
|
<div className={styles.info}>
|
||||||
@ -164,6 +262,9 @@ export default function Download({
|
|||||||
{!isInPurgatory && <PurchaseButton />}
|
{!isInPurgatory && <PurchaseButton />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={styles.collect}>
|
||||||
|
{asset.nft.owner === accountId && <CollectTokensButton />}
|
||||||
|
</div>
|
||||||
{asset?.metadata?.type === 'algorithm' && (
|
{asset?.metadata?.type === 'algorithm' && (
|
||||||
<AlgorithmDatasetsListForCompute
|
<AlgorithmDatasetsListForCompute
|
||||||
algorithmDid={asset.id}
|
algorithmDid={asset.id}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useState, useEffect } from 'react'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import Link from 'next/link'
|
||||||
import Markdown from '@shared/Markdown'
|
import Markdown from '@shared/Markdown'
|
||||||
import MetaFull from './MetaFull'
|
import MetaFull from './MetaFull'
|
||||||
import MetaSecondary from './MetaSecondary'
|
import MetaSecondary from './MetaSecondary'
|
||||||
@ -15,39 +15,32 @@ import styles from './index.module.css'
|
|||||||
import NetworkName from '@shared/NetworkName'
|
import NetworkName from '@shared/NetworkName'
|
||||||
import content from '../../../../content/purgatory.json'
|
import content from '../../../../content/purgatory.json'
|
||||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
import Button from '@shared/atoms/Button'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { getServiceById, getServiceByName } from '@utils/ddo'
|
|
||||||
import EditComputeDataset from '../Edit/EditComputeDataset'
|
|
||||||
|
|
||||||
export default function AssetContent({
|
export default function AssetContent({
|
||||||
asset
|
asset
|
||||||
}: {
|
}: {
|
||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { owner, isInPurgatory, purgatoryData, isAssetNetwork } = useAsset()
|
|
||||||
const [isOwner, setIsOwner] = useState(false)
|
const [isOwner, setIsOwner] = useState(false)
|
||||||
const [isComputeType, setIsComputeType] = useState<boolean>(false)
|
const { accountId } = useWeb3()
|
||||||
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
const { isInPurgatory, purgatoryData, owner, isAssetNetwork } = useAsset()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!accountId || !owner) return
|
||||||
|
|
||||||
|
const isOwner = accountId.toLowerCase() === owner.toLowerCase()
|
||||||
|
setIsOwner(isOwner)
|
||||||
|
}, [accountId, owner, asset])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!accountId || !owner) return
|
if (!accountId || !owner) return
|
||||||
|
|
||||||
const isOwner = accountId.toLowerCase() === owner.toLowerCase()
|
const isOwner = accountId.toLowerCase() === owner.toLowerCase()
|
||||||
setIsOwner(isOwner)
|
setIsOwner(isOwner)
|
||||||
// setShowPricing(isOwner && price.type === '')
|
|
||||||
setIsComputeType(Boolean(getServiceByName(asset, 'compute')))
|
|
||||||
}, [accountId, asset?.accessDetails, owner, asset])
|
}, [accountId, asset?.accessDetails, owner, asset])
|
||||||
|
|
||||||
function handleEditComputeButton() {
|
|
||||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
|
||||||
setShowEditCompute(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// return showEditCompute ? (
|
|
||||||
// <EditComputeDataset setShowEdit={setShowEditCompute} />
|
|
||||||
// ) : (
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.networkWrap}>
|
<div className={styles.networkWrap}>
|
||||||
@ -87,33 +80,11 @@ export default function AssetContent({
|
|||||||
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<AssetActions asset={asset} />
|
<AssetActions asset={asset} />
|
||||||
|
|
||||||
{/*
|
|
||||||
TODO: restore edit actions, ideally put edit screens on new page
|
|
||||||
with own URL instead of switching out AssetContent in place.
|
|
||||||
Simple way would be modal usage
|
|
||||||
*/}
|
|
||||||
{isOwner && isAssetNetwork && (
|
{isOwner && isAssetNetwork && (
|
||||||
<div className={styles.ownerActions}>
|
<div className={styles.ownerActions}>
|
||||||
{/* <Button
|
<Link href={`/asset/${asset?.id}/edit`}>
|
||||||
style="text"
|
<a>Edit</a>
|
||||||
size="small"
|
</Link>
|
||||||
onClick={handleEditComputeButton}
|
|
||||||
>
|
|
||||||
Edit Metadata
|
|
||||||
</Button> */}
|
|
||||||
{isComputeType && asset.metadata.type === 'dataset' && (
|
|
||||||
<>
|
|
||||||
<span className={styles.separator}>|</span>
|
|
||||||
<Button
|
|
||||||
style="text"
|
|
||||||
size="small"
|
|
||||||
onClick={handleEditComputeButton}
|
|
||||||
>
|
|
||||||
Edit Compute Settings
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,24 +2,32 @@ import { Asset, ServiceComputeOptions } from '@oceanprotocol/lib'
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
// import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
|
// import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
|
||||||
import DebugOutput from '@shared/DebugOutput'
|
import DebugOutput from '@shared/DebugOutput'
|
||||||
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
|
import { transformComputeFormToServiceComputeOptions } from '@utils/compute'
|
||||||
|
|
||||||
export default function DebugEditCompute({
|
export default function DebugEditCompute({
|
||||||
values,
|
values,
|
||||||
ddo
|
asset
|
||||||
}: {
|
}: {
|
||||||
values: ComputePrivacyForm
|
values: ComputePrivacyForm
|
||||||
ddo: Asset
|
asset: Asset
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [formTransformed, setFormTransformed] =
|
const [formTransformed, setFormTransformed] =
|
||||||
useState<ServiceComputeOptions>()
|
useState<ServiceComputeOptions>()
|
||||||
|
const newCancelToken = useCancelToken()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// async function transformValues() {
|
async function transformValues() {
|
||||||
// const privacy = await transformComputeFormToServiceComputePrivacy(values)
|
const privacy = await transformComputeFormToServiceComputeOptions(
|
||||||
// setFormTransformed(privacy)
|
values,
|
||||||
// }
|
asset.services[0].compute,
|
||||||
// transformValues()
|
asset.chainId,
|
||||||
}, [values, ddo])
|
newCancelToken()
|
||||||
|
)
|
||||||
|
setFormTransformed(privacy)
|
||||||
|
}
|
||||||
|
transformValues()
|
||||||
|
}, [values, asset])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
39
src/components/Asset/Edit/DebugEditMetadata.tsx
Normal file
39
src/components/Asset/Edit/DebugEditMetadata.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Asset, Metadata, Service } from '@oceanprotocol/lib'
|
||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import DebugOutput from '@shared/DebugOutput'
|
||||||
|
import { MetadataEditForm } from './_types'
|
||||||
|
import { mapTimeoutStringToSeconds } from '@utils/ddo'
|
||||||
|
|
||||||
|
export default function DebugEditMetadata({
|
||||||
|
values,
|
||||||
|
asset
|
||||||
|
}: {
|
||||||
|
values: Partial<MetadataEditForm>
|
||||||
|
asset: Asset
|
||||||
|
}): ReactElement {
|
||||||
|
const linksTransformed = values.links?.length &&
|
||||||
|
values.links[0].valid && [values.links[0].url.replace('javascript:', '')]
|
||||||
|
const newMetadata: Metadata = {
|
||||||
|
...asset.metadata,
|
||||||
|
name: values.name,
|
||||||
|
description: values.description,
|
||||||
|
links: linksTransformed,
|
||||||
|
author: values.author
|
||||||
|
}
|
||||||
|
const updatedService: Service = {
|
||||||
|
...asset.services[0],
|
||||||
|
timeout: mapTimeoutStringToSeconds(values.timeout)
|
||||||
|
}
|
||||||
|
const updatedAsset: Asset = {
|
||||||
|
...asset,
|
||||||
|
metadata: newMetadata,
|
||||||
|
services: [updatedService]
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DebugOutput title="Collected Form Values" output={values} />
|
||||||
|
<DebugOutput title="Transformed Asset Values" output={updatedAsset} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
@ -1,95 +1,131 @@
|
|||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useState } from 'react'
|
||||||
import { useAsset } from '@context/Asset'
|
|
||||||
import FormEditComputeDataset from './FormEditComputeDataset'
|
import FormEditComputeDataset from './FormEditComputeDataset'
|
||||||
import { LoggerInstance, ServiceComputeOptions } from '@oceanprotocol/lib'
|
import {
|
||||||
|
LoggerInstance,
|
||||||
|
ServiceComputeOptions,
|
||||||
|
Service,
|
||||||
|
ProviderInstance,
|
||||||
|
getHash,
|
||||||
|
Nft,
|
||||||
|
Asset
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import DebugEditCompute from './DebugEditCompute'
|
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
// import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
|
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import { getInitialValues, validationSchema } from './_constants'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
|
import {
|
||||||
|
getComputeSettingsInitialValues,
|
||||||
|
computeSettingsValidationSchema
|
||||||
|
} from './_constants'
|
||||||
import content from '../../../../content/pages/editComputeDataset.json'
|
import content from '../../../../content/pages/editComputeDataset.json'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { getServiceByName } from '@utils/ddo'
|
||||||
|
import { setMinterToPublisher, setMinterToDispenser } from '@utils/dispenser'
|
||||||
|
import { transformComputeFormToServiceComputeOptions } from '@utils/compute'
|
||||||
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
|
import DebugEditCompute from './DebugEditCompute'
|
||||||
|
import { useAsset } from '@context/Asset'
|
||||||
|
import EditFeedback from './EditFeedback'
|
||||||
|
import { setNftMetadata } from '@utils/nft'
|
||||||
|
|
||||||
export default function EditComputeDataset({
|
export default function EditComputeDataset({
|
||||||
setShowEdit
|
asset
|
||||||
}: {
|
}: {
|
||||||
setShowEdit: (show: boolean) => void
|
asset: AssetExtended
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { accountId } = useWeb3()
|
const { accountId, web3 } = useWeb3()
|
||||||
const { asset, isAssetNetwork, fetchAsset } = useAsset()
|
const { fetchAsset, isAssetNetwork } = useAsset()
|
||||||
const [success, setSuccess] = useState<string>()
|
const [success, setSuccess] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
|
const newAbortController = useAbortController()
|
||||||
|
const newCancelToken = useCancelToken()
|
||||||
const hasFeedback = error || success
|
const hasFeedback = error || success
|
||||||
|
|
||||||
async function handleSubmit(
|
async function handleSubmit(
|
||||||
values: ComputePrivacyForm,
|
values: ComputePrivacyForm,
|
||||||
resetForm: () => void
|
resetForm: () => void
|
||||||
) {
|
) {
|
||||||
// try {
|
try {
|
||||||
// if (price.type === 'free') {
|
if (asset?.accessDetails?.type === 'free') {
|
||||||
// const tx = await setMinterToPublisher(
|
const tx = await setMinterToPublisher(
|
||||||
// ocean,
|
web3,
|
||||||
// ddo.services[0].datatokenAddress,
|
asset?.accessDetails?.addressOrId,
|
||||||
// accountId,
|
asset?.accessDetails?.datatoken?.address,
|
||||||
// setError
|
accountId,
|
||||||
// )
|
setError
|
||||||
// if (!tx) return
|
)
|
||||||
// }
|
if (!tx) return
|
||||||
// const privacy = await transformComputeFormToServiceComputePrivacy(
|
}
|
||||||
// values,
|
const newComputeSettings: ServiceComputeOptions =
|
||||||
// ocean
|
await transformComputeFormToServiceComputeOptions(
|
||||||
// )
|
values,
|
||||||
// const ddoEditedComputePrivacy = await ocean.compute.editComputePrivacy(
|
asset.services[0].compute,
|
||||||
// ddo,
|
asset.chainId,
|
||||||
// 1,
|
newCancelToken()
|
||||||
// privacy as ServiceComputePrivacy
|
)
|
||||||
// )
|
|
||||||
// if (!ddoEditedComputePrivacy) {
|
LoggerInstance.log(
|
||||||
// setError(content.form.error)
|
'[edit compute settings] newComputeSettings',
|
||||||
// LoggerInstance.error(content.form.error)
|
newComputeSettings
|
||||||
// return
|
)
|
||||||
// }
|
|
||||||
// const storedddo = await ocean.assets.updateMetadata(
|
const updatedService: Service = {
|
||||||
// ddoEditedComputePrivacy,
|
...asset.services[0],
|
||||||
// accountId
|
compute: newComputeSettings
|
||||||
// )
|
}
|
||||||
// if (!storedddo) {
|
|
||||||
// setError(content.form.error)
|
LoggerInstance.log(
|
||||||
// LoggerInstance.error(content.form.error)
|
'[edit compute settings] updatedService',
|
||||||
// return
|
updatedService
|
||||||
// } else {
|
)
|
||||||
// if (price.type === 'free') {
|
|
||||||
// const tx = await setMinterToDispenser(
|
const updatedAsset: Asset = {
|
||||||
// ocean,
|
...asset,
|
||||||
// ddo.services[0].datatokenAddress,
|
services: [updatedService]
|
||||||
// accountId,
|
}
|
||||||
// setError
|
|
||||||
// )
|
const setMetadataTx = await setNftMetadata(
|
||||||
// if (!tx) return
|
updatedAsset,
|
||||||
// }
|
accountId,
|
||||||
// // Edit succeeded
|
web3,
|
||||||
// setSuccess(content.form.success)
|
newAbortController()
|
||||||
// resetForm()
|
)
|
||||||
// }
|
|
||||||
// } catch (error) {
|
LoggerInstance.log('[edit] setMetadata result', setMetadataTx)
|
||||||
// LoggerInstance.error(error.message)
|
|
||||||
// setError(error.message)
|
if (!setMetadataTx) {
|
||||||
// }
|
setError(content.form.error)
|
||||||
|
LoggerInstance.error(content.form.error)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
if (asset.accessDetails.type === 'free') {
|
||||||
|
const tx = await setMinterToDispenser(
|
||||||
|
web3,
|
||||||
|
asset?.accessDetails?.datatoken?.address,
|
||||||
|
accountId,
|
||||||
|
setError
|
||||||
|
)
|
||||||
|
if (!tx) return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit succeeded
|
||||||
|
setSuccess(content.form.success)
|
||||||
|
resetForm()
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error(error.message)
|
||||||
|
setError(error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={
|
initialValues={getComputeSettingsInitialValues(
|
||||||
{}
|
getServiceByName(asset, 'compute')?.compute
|
||||||
// getInitialValues(
|
)}
|
||||||
// ddo.findServiceByType('compute').attributes.main.privacy
|
validationSchema={computeSettingsValidationSchema}
|
||||||
// )
|
|
||||||
}
|
|
||||||
validationSchema={validationSchema}
|
|
||||||
onSubmit={async (values, { resetForm }) => {
|
onSubmit={async (values, { resetForm }) => {
|
||||||
// move user's focus to top of screen
|
// move user's focus to top of screen
|
||||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
@ -99,15 +135,26 @@ export default function EditComputeDataset({
|
|||||||
>
|
>
|
||||||
{({ values, isSubmitting }) =>
|
{({ values, isSubmitting }) =>
|
||||||
isSubmitting || hasFeedback ? (
|
isSubmitting || hasFeedback ? (
|
||||||
<div />
|
<EditFeedback
|
||||||
|
title="Updating Data Set"
|
||||||
|
error={error}
|
||||||
|
success={success}
|
||||||
|
setError={setError}
|
||||||
|
successAction={{
|
||||||
|
name: 'View Asset',
|
||||||
|
onClick: async () => {
|
||||||
|
await fetchAsset()
|
||||||
|
},
|
||||||
|
to: `/asset/${asset.id}`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<p className={styles.description}>{content.description}</p>
|
<p className={styles.description}>{content.description}</p>
|
||||||
<article className={styles.grid}>
|
<article>
|
||||||
<FormEditComputeDataset
|
<FormEditComputeDataset
|
||||||
title={content.form.title}
|
title={content.form.title}
|
||||||
data={content.form.data}
|
data={content.form.data}
|
||||||
setShowEdit={setShowEdit}
|
|
||||||
/>
|
/>
|
||||||
</article>
|
</article>
|
||||||
<Web3Feedback
|
<Web3Feedback
|
||||||
@ -116,7 +163,7 @@ export default function EditComputeDataset({
|
|||||||
/>
|
/>
|
||||||
{debug === true && (
|
{debug === true && (
|
||||||
<div className={styles.grid}>
|
<div className={styles.grid}>
|
||||||
{/* <DebugEditCompute values={values} ddo={ddo} /> */}
|
<DebugEditCompute values={values} asset={asset} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
43
src/components/Asset/Edit/EditFeedback.module.css
Normal file
43
src/components/Asset/Edit/EditFeedback.module.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
.feedback {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 40vh;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
composes: box from '@shared/atoms/Box.module.css';
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback h3 {
|
||||||
|
font-size: var(--font-size-large);
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: calc(var(--spacer) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback h3 + div {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 40rem) {
|
||||||
|
.feedback {
|
||||||
|
max-width: 30rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback [class*='loaderWrap'] {
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
margin-top: calc(var(--spacer) / 1.5);
|
||||||
|
}
|
||||||
|
.moreInfo {
|
||||||
|
padding: calc(var(--spacer) / 4) calc(var(--spacer) / 2) !important;
|
||||||
|
}
|
94
src/components/Asset/Edit/EditFeedback.tsx
Normal file
94
src/components/Asset/Edit/EditFeedback.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import Alert from '@shared/atoms/Alert'
|
||||||
|
import Button from '@shared/atoms/Button'
|
||||||
|
import Loader from '@shared/atoms/Loader'
|
||||||
|
import SuccessConfetti from '@shared/SuccessConfetti'
|
||||||
|
import React, { ReactElement, useState, FormEvent } from 'react'
|
||||||
|
import styles from './EditFeedback.module.css'
|
||||||
|
|
||||||
|
interface Action {
|
||||||
|
name: string
|
||||||
|
onClick?: () => void
|
||||||
|
to?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function ActionSuccess({ action }: { action: Action }) {
|
||||||
|
const { name, onClick, to } = action
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
style="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={onClick || null}
|
||||||
|
to={to || null}
|
||||||
|
className={styles.action}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ActionError({ setError }: { setError: (error: string) => void }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
style="primary"
|
||||||
|
size="small"
|
||||||
|
className={styles.action}
|
||||||
|
onClick={() => setError(undefined)}
|
||||||
|
>
|
||||||
|
Try Again
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function EditFeedback({
|
||||||
|
title,
|
||||||
|
error,
|
||||||
|
success,
|
||||||
|
loading,
|
||||||
|
successAction,
|
||||||
|
setError
|
||||||
|
}: {
|
||||||
|
title: string
|
||||||
|
error: string
|
||||||
|
success: string
|
||||||
|
loading?: string
|
||||||
|
successAction: Action
|
||||||
|
setError: (error: string) => void
|
||||||
|
}): ReactElement {
|
||||||
|
const [moreInfo, setMoreInfo] = useState<boolean>(false)
|
||||||
|
|
||||||
|
function toggleMoreInfo(e: FormEvent<Element>) {
|
||||||
|
e.preventDefault()
|
||||||
|
moreInfo === true ? setMoreInfo(false) : setMoreInfo(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.feedback}>
|
||||||
|
<div className={styles.box}>
|
||||||
|
<h3>{title}</h3>
|
||||||
|
{error ? (
|
||||||
|
<>
|
||||||
|
<p>Sorry, something went wrong. Please try again.</p>
|
||||||
|
{moreInfo && <Alert text={error} state="error" />}
|
||||||
|
<Button
|
||||||
|
style="text"
|
||||||
|
size="small"
|
||||||
|
onClick={toggleMoreInfo}
|
||||||
|
className={styles.moreInfo}
|
||||||
|
>
|
||||||
|
{moreInfo === false ? 'More Info' : 'Hide error'}
|
||||||
|
</Button>
|
||||||
|
<ActionError setError={setError} />
|
||||||
|
</>
|
||||||
|
) : success ? (
|
||||||
|
<SuccessConfetti
|
||||||
|
success={success}
|
||||||
|
action={<ActionSuccess action={successAction} />}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Loader message={loading} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
178
src/components/Asset/Edit/EditMetadata.tsx
Normal file
178
src/components/Asset/Edit/EditMetadata.tsx
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import React, { ReactElement, useState } from 'react'
|
||||||
|
import { Formik } from 'formik'
|
||||||
|
import {
|
||||||
|
LoggerInstance,
|
||||||
|
Metadata,
|
||||||
|
FixedRateExchange,
|
||||||
|
Asset,
|
||||||
|
Service
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
|
import { validationSchema, getInitialValues } from './_constants'
|
||||||
|
import { MetadataEditForm } from './_types'
|
||||||
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
|
import FormEditMetadata from './FormEditMetadata'
|
||||||
|
import { mapTimeoutStringToSeconds } from '@utils/ddo'
|
||||||
|
import styles from './index.module.css'
|
||||||
|
import content from '../../../../content/pages/edit.json'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { setMinterToPublisher, setMinterToDispenser } from '@utils/dispenser'
|
||||||
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
|
import DebugEditMetadata from './DebugEditMetadata'
|
||||||
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import EditFeedback from './EditFeedback'
|
||||||
|
import { useAsset } from '@context/Asset'
|
||||||
|
import { setNftMetadata } from '@utils/nft'
|
||||||
|
|
||||||
|
export default function Edit({
|
||||||
|
asset
|
||||||
|
}: {
|
||||||
|
asset: AssetExtended
|
||||||
|
}): ReactElement {
|
||||||
|
const { debug } = useUserPreferences()
|
||||||
|
const { fetchAsset, isAssetNetwork } = useAsset()
|
||||||
|
const { accountId, web3 } = useWeb3()
|
||||||
|
const newAbortController = useAbortController()
|
||||||
|
const [success, setSuccess] = useState<string>()
|
||||||
|
const [error, setError] = useState<string>()
|
||||||
|
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
||||||
|
const isComputeType = asset?.services[0]?.type === 'compute'
|
||||||
|
const hasFeedback = error || success
|
||||||
|
|
||||||
|
async function updateFixedPrice(newPrice: string) {
|
||||||
|
const config = getOceanConfig(asset.chainId)
|
||||||
|
|
||||||
|
const fixedRateInstance = new FixedRateExchange(
|
||||||
|
web3,
|
||||||
|
config.fixedRateExchangeAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
const setPriceResp = await fixedRateInstance.setRate(
|
||||||
|
accountId,
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
newPrice
|
||||||
|
)
|
||||||
|
LoggerInstance.log('[edit] setFixedRate result', setPriceResp)
|
||||||
|
if (!setPriceResp) {
|
||||||
|
setError(content.form.error)
|
||||||
|
LoggerInstance.error(content.form.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit(
|
||||||
|
values: Partial<MetadataEditForm>,
|
||||||
|
resetForm: () => void
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const linksTransformed = values.links?.length &&
|
||||||
|
values.links[0].valid && [
|
||||||
|
values.links[0].url.replace('javascript:', '')
|
||||||
|
]
|
||||||
|
const updatedMetadata: Metadata = {
|
||||||
|
...asset.metadata,
|
||||||
|
name: values.name,
|
||||||
|
description: values.description,
|
||||||
|
links: linksTransformed,
|
||||||
|
author: values.author
|
||||||
|
}
|
||||||
|
|
||||||
|
asset?.accessDetails?.type === 'fixed' &&
|
||||||
|
values.price !== asset.accessDetails.price &&
|
||||||
|
(await updateFixedPrice(values.price))
|
||||||
|
|
||||||
|
const updatedService: Service = {
|
||||||
|
...asset.services[0],
|
||||||
|
timeout: mapTimeoutStringToSeconds(values.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedAsset: Asset = {
|
||||||
|
...asset,
|
||||||
|
metadata: updatedMetadata,
|
||||||
|
services: [updatedService]
|
||||||
|
}
|
||||||
|
|
||||||
|
const setMetadataTx = await setNftMetadata(
|
||||||
|
updatedAsset,
|
||||||
|
accountId,
|
||||||
|
web3,
|
||||||
|
newAbortController()
|
||||||
|
)
|
||||||
|
|
||||||
|
LoggerInstance.log('[edit] setMetadata result', setMetadataTx)
|
||||||
|
|
||||||
|
if (!setMetadataTx) {
|
||||||
|
setError(content.form.error)
|
||||||
|
LoggerInstance.error(content.form.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Edit succeeded
|
||||||
|
setSuccess(content.form.success)
|
||||||
|
resetForm()
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error(error.message)
|
||||||
|
setError(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik
|
||||||
|
initialValues={getInitialValues(
|
||||||
|
asset?.metadata,
|
||||||
|
asset?.services[0]?.timeout,
|
||||||
|
asset?.accessDetails?.price
|
||||||
|
)}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={async (values, { resetForm }) => {
|
||||||
|
// move user's focus to top of screen
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
|
// kick off editing
|
||||||
|
await handleSubmit(values, resetForm)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, values, initialValues }) =>
|
||||||
|
isSubmitting || hasFeedback ? (
|
||||||
|
<EditFeedback
|
||||||
|
title="Updating Data Set"
|
||||||
|
error={error}
|
||||||
|
success={success}
|
||||||
|
setError={setError}
|
||||||
|
successAction={{
|
||||||
|
name: 'View Asset',
|
||||||
|
onClick: async () => {
|
||||||
|
await fetchAsset()
|
||||||
|
},
|
||||||
|
to: `/asset/${asset.id}`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className={styles.description}>{content.description}</p>
|
||||||
|
<article>
|
||||||
|
<FormEditMetadata
|
||||||
|
data={content.form.data}
|
||||||
|
setTimeoutStringValue={setTimeoutStringValue}
|
||||||
|
values={initialValues}
|
||||||
|
showPrice={asset?.accessDetails?.type === 'fixed'}
|
||||||
|
isComputeDataset={isComputeType}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<Web3Feedback
|
||||||
|
networkId={asset?.chainId}
|
||||||
|
isAssetNetwork={isAssetNetwork}
|
||||||
|
/>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
{debug === true && (
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<DebugEditMetadata values={values} asset={asset} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</article>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Formik>
|
||||||
|
)
|
||||||
|
}
|
@ -3,12 +3,11 @@ import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
|||||||
import Input, { InputProps } from '@shared/FormInput'
|
import Input, { InputProps } from '@shared/FormInput'
|
||||||
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
||||||
import stylesIndex from './index.module.css'
|
import stylesIndex from './index.module.css'
|
||||||
import styles from './FormEditMetadata.module.css'
|
import styles from './FormEdit.module.css'
|
||||||
import {
|
import {
|
||||||
generateBaseQuery,
|
generateBaseQuery,
|
||||||
getFilterTerm,
|
getFilterTerm,
|
||||||
queryMetadata,
|
queryMetadata
|
||||||
transformDDOToAssetSelection
|
|
||||||
} from '@utils/aquarius'
|
} from '@utils/aquarius'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { PublisherTrustedAlgorithm } from '@oceanprotocol/lib'
|
import { PublisherTrustedAlgorithm } from '@oceanprotocol/lib'
|
||||||
@ -17,25 +16,25 @@ import FormActions from './FormActions'
|
|||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { SortTermOptions } from '../../../@types/aquarius/SearchQuery'
|
import { SortTermOptions } from '../../../@types/aquarius/SearchQuery'
|
||||||
import { getServiceByName } from '@utils/ddo'
|
import { getServiceByName } from '@utils/ddo'
|
||||||
|
import { transformAssetToAssetSelection } from '@utils/assetConvertor'
|
||||||
|
|
||||||
export default function FormEditComputeDataset({
|
export default function FormEditComputeDataset({
|
||||||
data,
|
data,
|
||||||
title,
|
title
|
||||||
setShowEdit
|
|
||||||
}: {
|
}: {
|
||||||
data: InputProps[]
|
data: InputProps[]
|
||||||
title: string
|
title: string
|
||||||
setShowEdit: (show: boolean) => void
|
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
const { asset } = useAsset()
|
const { asset } = useAsset()
|
||||||
|
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
||||||
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
||||||
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
const { publisherTrustedAlgorithms } = getServiceByName(
|
const { publisherTrustedAlgorithms } = getServiceByName(
|
||||||
asset,
|
asset,
|
||||||
'compute'
|
'compute'
|
||||||
).compute
|
)?.compute
|
||||||
|
|
||||||
async function getAlgorithmList(
|
async function getAlgorithmList(
|
||||||
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
|
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
|
||||||
@ -43,17 +42,16 @@ export default function FormEditComputeDataset({
|
|||||||
const baseParams = {
|
const baseParams = {
|
||||||
chainIds: [asset.chainId],
|
chainIds: [asset.chainId],
|
||||||
sort: { sortBy: SortTermOptions.Created },
|
sort: { sortBy: SortTermOptions.Created },
|
||||||
filters: [getFilterTerm('service.attributes.main.type', 'algorithm')]
|
filters: [getFilterTerm('metadata.type', 'algorithm')]
|
||||||
} as BaseQueryParams
|
} as BaseQueryParams
|
||||||
|
|
||||||
const query = generateBaseQuery(baseParams)
|
const query = generateBaseQuery(baseParams)
|
||||||
const querryResult = await queryMetadata(query, newCancelToken())
|
const querryResult = await queryMetadata(query, newCancelToken())
|
||||||
const datasetComputeService = getServiceByName(asset, 'compute')
|
const datasetComputeService = getServiceByName(asset, 'compute')
|
||||||
const algorithmSelectionList = await transformDDOToAssetSelection(
|
const algorithmSelectionList = await transformAssetToAssetSelection(
|
||||||
datasetComputeService?.serviceEndpoint,
|
datasetComputeService?.serviceEndpoint,
|
||||||
querryResult.results,
|
querryResult?.results,
|
||||||
publisherTrustedAlgorithms,
|
publisherTrustedAlgorithms
|
||||||
newCancelToken()
|
|
||||||
)
|
)
|
||||||
return algorithmSelectionList
|
return algorithmSelectionList
|
||||||
}
|
}
|
||||||
@ -85,7 +83,8 @@ export default function FormEditComputeDataset({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<FormActions setShowEdit={setShowEdit} />
|
{/* <FormActions setShowEdit={setShowEdit} /> */}
|
||||||
|
<FormActions setShowEdit={setShowEditCompute} />
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,64 +1,75 @@
|
|||||||
import React, { ChangeEvent, ReactElement } from 'react'
|
import React, { ChangeEvent, ReactElement, useState } from 'react'
|
||||||
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
||||||
import Input, { InputProps } from '@shared/FormInput'
|
import Input, { InputProps } from '@shared/FormInput'
|
||||||
import FormActions from './FormActions'
|
import FormActions from './FormActions'
|
||||||
import styles from './FormEditMetadata.module.css'
|
import styles from './FormEdit.module.css'
|
||||||
import { FormPublishData } from '../../Publish/_types'
|
import { FormPublishData } from '../../Publish/_types'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
|
import { MetadataEditForm } from './_types'
|
||||||
|
|
||||||
|
export function checkIfTimeoutInPredefinedValues(
|
||||||
|
timeout: string,
|
||||||
|
timeoutOptions: string[]
|
||||||
|
): boolean {
|
||||||
|
if (timeoutOptions.indexOf(timeout) > -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTimeoutCustomOption(
|
||||||
|
data: FormFieldContent[],
|
||||||
|
values: Partial<FormPublishData>
|
||||||
|
) {
|
||||||
|
const timeoutFieldContent = data.filter(
|
||||||
|
(field) => field.name === 'timeout'
|
||||||
|
)[0]
|
||||||
|
const timeoutInputIndex = data.findIndex(
|
||||||
|
(element) => element.name === 'timeout'
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
data[timeoutInputIndex].options.length < 6 &&
|
||||||
|
!checkIfTimeoutInPredefinedValues(
|
||||||
|
values?.services[0]?.timeout,
|
||||||
|
timeoutFieldContent.options
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
data[timeoutInputIndex].options.push(values?.services[0]?.timeout)
|
||||||
|
} else if (
|
||||||
|
data[timeoutInputIndex].options.length === 6 &&
|
||||||
|
checkIfTimeoutInPredefinedValues(
|
||||||
|
values?.services[0]?.timeout,
|
||||||
|
timeoutFieldContent.options
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
data[timeoutInputIndex].options.pop()
|
||||||
|
} else if (
|
||||||
|
data[timeoutInputIndex].options.length === 6 &&
|
||||||
|
data[timeoutInputIndex].options[5] !== values?.services[0]?.timeout
|
||||||
|
) {
|
||||||
|
data[timeoutInputIndex].options[5] = values?.services[0]?.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// function handleTimeoutCustomOption(
|
|
||||||
// data: FormFieldContent[],
|
|
||||||
// values: Partial<FormPublishData>
|
|
||||||
// ) {
|
|
||||||
// const timeoutFieldContent = data.filter(
|
|
||||||
// (field) => field.name === 'timeout'
|
|
||||||
// )[0]
|
|
||||||
// const timeoutInputIndex = data.findIndex(
|
|
||||||
// (element) => element.name === 'timeout'
|
|
||||||
// )
|
|
||||||
// if (
|
|
||||||
// data[timeoutInputIndex].options.length < 6 &&
|
|
||||||
// !checkIfTimeoutInPredefinedValues(
|
|
||||||
// values.timeout,
|
|
||||||
// timeoutFieldContent.options
|
|
||||||
// )
|
|
||||||
// ) {
|
|
||||||
// data[timeoutInputIndex].options.push(values.timeout)
|
|
||||||
// } else if (
|
|
||||||
// data[timeoutInputIndex].options.length === 6 &&
|
|
||||||
// checkIfTimeoutInPredefinedValues(
|
|
||||||
// values.timeout,
|
|
||||||
// timeoutFieldContent.options
|
|
||||||
// )
|
|
||||||
// ) {
|
|
||||||
// data[timeoutInputIndex].options.pop()
|
|
||||||
// } else if (
|
|
||||||
// data[timeoutInputIndex].options.length === 6 &&
|
|
||||||
// data[timeoutInputIndex].options[5] !== values.timeout
|
|
||||||
// ) {
|
|
||||||
// data[timeoutInputIndex].options[5] = values.timeout
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
export default function FormEditMetadata({
|
export default function FormEditMetadata({
|
||||||
data,
|
data,
|
||||||
setShowEdit,
|
|
||||||
setTimeoutStringValue,
|
setTimeoutStringValue,
|
||||||
values,
|
values,
|
||||||
showPrice,
|
showPrice,
|
||||||
isComputeDataset
|
isComputeDataset
|
||||||
}: {
|
}: {
|
||||||
data: InputProps[]
|
data: InputProps[]
|
||||||
setShowEdit: (show: boolean) => void
|
|
||||||
setTimeoutStringValue: (value: string) => void
|
setTimeoutStringValue: (value: string) => void
|
||||||
values: Partial<FormPublishData>
|
values: Partial<MetadataEditForm>
|
||||||
showPrice: boolean
|
showPrice: boolean
|
||||||
isComputeDataset: boolean
|
isComputeDataset: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { oceanConfig } = useAsset()
|
const { oceanConfig } = useAsset()
|
||||||
|
const [showEdit, setShowEdit] = useState<boolean>()
|
||||||
const {
|
const {
|
||||||
validateField,
|
validateField,
|
||||||
setFieldValue
|
setFieldValue
|
||||||
}: FormikContextType<Partial<FormPublishData>> = useFormikContext()
|
}: FormikContextType<Partial<MetadataEditForm>> = useFormikContext()
|
||||||
|
|
||||||
// Manually handle change events instead of using `handleChange` from Formik.
|
// Manually handle change events instead of using `handleChange` from Formik.
|
||||||
// Workaround for default `validateOnChange` not kicking in
|
// Workaround for default `validateOnChange` not kicking in
|
||||||
@ -78,12 +89,12 @@ export default function FormEditMetadata({
|
|||||||
(field) => field.name === 'timeout'
|
(field) => field.name === 'timeout'
|
||||||
)[0].options
|
)[0].options
|
||||||
|
|
||||||
// if (isComputeDataset && timeoutOptionsArray.includes('Forever')) {
|
if (isComputeDataset && timeoutOptionsArray.includes('Forever')) {
|
||||||
// const foreverOptionIndex = timeoutOptionsArray.indexOf('Forever')
|
const foreverOptionIndex = timeoutOptionsArray.indexOf('Forever')
|
||||||
// timeoutOptionsArray.splice(foreverOptionIndex, 1)
|
timeoutOptionsArray.splice(foreverOptionIndex, 1)
|
||||||
// } else if (!isComputeDataset && !timeoutOptionsArray.includes('Forever')) {
|
} else if (!isComputeDataset && !timeoutOptionsArray.includes('Forever')) {
|
||||||
// timeoutOptionsArray.push('Forever')
|
timeoutOptionsArray.push('Forever')
|
||||||
// }
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form className={styles.form}>
|
<Form className={styles.form}>
|
||||||
@ -107,10 +118,10 @@ export default function FormEditMetadata({
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* <FormActions
|
<FormActions
|
||||||
setShowEdit={setShowEdit}
|
setShowEdit={setShowEdit}
|
||||||
handleClick={() => setTimeoutStringValue(values.timeout)}
|
// handleClick={() => setTimeoutStringValue(values?.services[0]?.timeout)}
|
||||||
/> */}
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Metadata } from '@oceanprotocol/lib'
|
import { Metadata, ServiceComputeOptions } from '@oceanprotocol/lib'
|
||||||
import { mapTimeoutStringToSeconds, secondsToString } from '@utils/ddo'
|
import { mapTimeoutStringToSeconds, secondsToString } from '@utils/ddo'
|
||||||
// import { EditableMetadataLinks } from '@oceanprotocol/lib'
|
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { MetadataEditForm } from './_types'
|
import { MetadataEditForm } from './_types'
|
||||||
|
|
||||||
@ -18,35 +17,41 @@ export const validationSchema = Yup.object().shape({
|
|||||||
export function getInitialValues(
|
export function getInitialValues(
|
||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
timeout: number,
|
timeout: number,
|
||||||
price: number
|
price: string
|
||||||
): Partial<MetadataEditForm> {
|
): Partial<MetadataEditForm> {
|
||||||
return {
|
return {
|
||||||
name: metadata.name,
|
name: metadata?.name,
|
||||||
description: metadata.description,
|
description: metadata?.description,
|
||||||
price,
|
price,
|
||||||
timeout,
|
links: metadata?.links,
|
||||||
author: metadata.author
|
timeout: secondsToString(timeout),
|
||||||
|
author: metadata?.author
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// export const validationSchema: Yup.SchemaOf<ComputePrivacyForm> =
|
export const computeSettingsValidationSchema = Yup.object().shape({
|
||||||
// Yup.object().shape({
|
allowAllPublishedAlgorithms: Yup.boolean().nullable(),
|
||||||
// allowAllPublishedAlgorithms: Yup.boolean().nullable(),
|
publisherTrustedAlgorithms: Yup.array().nullable()
|
||||||
// publisherTrustedAlgorithms: Yup.array().nullable()
|
})
|
||||||
// })
|
|
||||||
|
|
||||||
// export function getInitialValues(
|
export function getComputeSettingsInitialValues(
|
||||||
// compute: ServiceComputePrivacy
|
compute: ServiceComputeOptions
|
||||||
// ): ComputePrivacyForm {
|
): ComputePrivacyForm {
|
||||||
// // TODO: ocean.js needs allowAllAlgoritms setting
|
const { publisherTrustedAlgorithmPublishers, publisherTrustedAlgorithms } =
|
||||||
// const { allowAllPublishedAlgorithms, publisherTrustedAlgorithms } = compute
|
compute
|
||||||
|
const allowAllPublishedAlgorithms = !(
|
||||||
|
publisherTrustedAlgorithms?.length > 0 ||
|
||||||
|
publisherTrustedAlgorithmPublishers?.length > 0
|
||||||
|
)
|
||||||
|
|
||||||
// const publisherTrustedAlgorithmsForForm = (
|
const publisherTrustedAlgorithmsForForm = (
|
||||||
// publisherTrustedAlgorithms || []
|
publisherTrustedAlgorithms || []
|
||||||
// ).map((algo) => algo.did)
|
).map((algo) => algo.did)
|
||||||
|
|
||||||
// return {
|
// TODO: should we add publisherTrustedAlgorithmPublishers to the form?
|
||||||
// allowAllPublishedAlgorithms,
|
|
||||||
// publisherTrustedAlgorithms: publisherTrustedAlgorithmsForForm
|
return {
|
||||||
// }
|
allowAllPublishedAlgorithms,
|
||||||
// }
|
publisherTrustedAlgorithms: publisherTrustedAlgorithmsForForm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
export interface MetadataEditForm {
|
export interface MetadataEditForm {
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
timeout: number
|
timeout: string
|
||||||
price?: number
|
price?: string
|
||||||
links?: string | any[]
|
links?: string | any[]
|
||||||
author?: string
|
author?: string
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,37 @@
|
|||||||
|
.edit ul > li[class*='Tabs_tab'] {
|
||||||
|
padding: calc(var(--spacer) / 4) var(--spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit [class*='Tabs_tabContent'] {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
composes: grid from '../../AssetContent/index.module.css';
|
display: grid;
|
||||||
margin-top: var(--spacer);
|
gap: calc(var(--spacer) * 1.5);
|
||||||
|
position: relative;
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contianer {
|
||||||
|
composes: box from '@shared/atoms/Box.module.css';
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 60rem) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-size: var(--font-size-large);
|
font-size: var(--font-size-large);
|
||||||
margin-top: -1.5rem;
|
|
||||||
max-width: 50rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -1,161 +1,73 @@
|
|||||||
import { Formik } from 'formik'
|
import React, { ReactElement, useState, useEffect } from 'react'
|
||||||
import React, { ReactElement, useState } from 'react'
|
|
||||||
import { validationSchema, getInitialValues } from './_constants'
|
|
||||||
import { useAsset } from '@context/Asset'
|
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
|
||||||
// import Debug from './DebugEditMetadata'
|
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
|
||||||
import FormEditMetadata from './FormEditMetadata'
|
|
||||||
import { getServiceByName, mapTimeoutStringToSeconds } from '@utils/ddo'
|
|
||||||
import styles from './index.module.css'
|
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
|
import { useAsset } from '@context/Asset'
|
||||||
|
import styles from './index.module.css'
|
||||||
|
import Tabs from '@shared/atoms/Tabs'
|
||||||
|
import EditMetadata from './EditMetadata'
|
||||||
|
import EditComputeDataset from './EditComputeDataset'
|
||||||
|
import Page from '@shared/Page'
|
||||||
|
import Loader from '@shared/atoms/Loader'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import content from '../../../../content/pages/edit.json'
|
import Alert from '@shared/atoms/Alert'
|
||||||
import { MetadataEditForm } from './_types'
|
|
||||||
|
|
||||||
export default function Edit({
|
export default function Edit({ uri }: { uri: string }): ReactElement {
|
||||||
setShowEdit,
|
const { asset, error, loading, owner } = useAsset()
|
||||||
isComputeType
|
const [isCompute, setIsCompute] = useState(false)
|
||||||
}: {
|
const [isOnwer, setIsOwner] = useState(false)
|
||||||
setShowEdit: (show: boolean) => void
|
|
||||||
isComputeType?: boolean
|
|
||||||
}): ReactElement {
|
|
||||||
const { debug } = useUserPreferences()
|
|
||||||
const { accountId } = useWeb3()
|
const { accountId } = useWeb3()
|
||||||
const { asset, fetchAsset } = useAsset()
|
|
||||||
const [success, setSuccess] = useState<string>()
|
|
||||||
const [error, setError] = useState<string>()
|
|
||||||
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
|
||||||
const { timeout } = asset.services[0]
|
|
||||||
|
|
||||||
const hasFeedback = error || success
|
// Switch type value upon tab change
|
||||||
|
function handleTabChange(tabName: string) {
|
||||||
async function updateFixedPrice(newPrice: number) {
|
LoggerInstance.log('switched to tab', tabName)
|
||||||
// const setPriceResp = await ocean.fixedRateExchange.setRate(
|
// add store restore from
|
||||||
// price.address,
|
|
||||||
// newPrice,
|
|
||||||
// accountId
|
|
||||||
// )
|
|
||||||
// if (!setPriceResp) {
|
|
||||||
// setError(content.form.error)
|
|
||||||
// LoggerInstance.error(content.form.error)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit(
|
useEffect(() => {
|
||||||
values: Partial<MetadataEditForm>,
|
if (!asset || error) {
|
||||||
resetForm: () => void
|
return
|
||||||
) {
|
}
|
||||||
// try {
|
setIsCompute(asset?.services[0]?.type === 'compute')
|
||||||
// if (price.type === 'free') {
|
setIsOwner(owner === accountId)
|
||||||
// const tx = await setMinterToPublisher(
|
}, [asset, error])
|
||||||
// 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)
|
|
||||||
// LoggerInstance.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)
|
|
||||||
// LoggerInstance.error(content.form.error)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// const storedddo = await ocean.assets.updateMetadata(
|
|
||||||
// ddoEditedTimeout,
|
|
||||||
// accountId
|
|
||||||
// )
|
|
||||||
// if (!storedddo) {
|
|
||||||
// setError(content.form.error)
|
|
||||||
// LoggerInstance.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) {
|
|
||||||
// LoggerInstance.error(error.message)
|
|
||||||
// setError(error.message)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
const tabs = [
|
||||||
<Formik
|
{
|
||||||
initialValues={getInitialValues(
|
title: 'Edit Metadata',
|
||||||
asset.metadata,
|
content: <EditMetadata asset={asset} />
|
||||||
timeout,
|
},
|
||||||
asset.accessDetails.price
|
{
|
||||||
)}
|
title: 'Edit Compute Settings',
|
||||||
validationSchema={validationSchema}
|
content: <EditComputeDataset asset={asset} />,
|
||||||
onSubmit={async (values, { resetForm }) => {
|
disabled: !isCompute
|
||||||
// move user's focus to top of screen
|
}
|
||||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
].filter((tab) => tab !== undefined)
|
||||||
// kick off editing
|
|
||||||
await handleSubmit(values, resetForm)
|
return asset && !loading && isOnwer ? (
|
||||||
}}
|
<Page uri={uri}>
|
||||||
|
<div className={styles.contianer}>
|
||||||
|
<Tabs
|
||||||
|
items={tabs}
|
||||||
|
handleTabChange={handleTabChange}
|
||||||
|
defaultIndex={0}
|
||||||
|
className={styles.edit}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Page>
|
||||||
|
) : !isOnwer ? (
|
||||||
|
<Page
|
||||||
|
title="Edit action available only to asset owner"
|
||||||
|
noPageHeader
|
||||||
|
uri={uri}
|
||||||
>
|
>
|
||||||
{({ isSubmitting, values, initialValues }) =>
|
<Alert
|
||||||
isSubmitting || hasFeedback ? (
|
title="Edit action available only to asset owner"
|
||||||
<div />
|
text={error}
|
||||||
) : (
|
state="error"
|
||||||
<>
|
/>
|
||||||
<p className={styles.description}>{content.description}</p>
|
</Page>
|
||||||
<article className={styles.grid}>
|
) : (
|
||||||
{/* <FormEditMetadata
|
<Page title={undefined} uri={uri}>
|
||||||
data={content.form.data}
|
<Loader />
|
||||||
setShowEdit={setShowEdit}
|
</Page>
|
||||||
setTimeoutStringValue={setTimeoutStringValue}
|
|
||||||
// values={initialValues}
|
|
||||||
showPrice={price.type === 'exchange'}
|
|
||||||
isComputeDataset={isComputeType}
|
|
||||||
/> */}
|
|
||||||
|
|
||||||
<aside>
|
|
||||||
<Web3Feedback networkId={asset?.chainId} />
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
{/* {debug === true && <Debug values={values} ddo={ddo} />} */}
|
|
||||||
</article>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Formik>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,24 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import styles from './Fees.module.css'
|
import styles from './Fees.module.css'
|
||||||
import { useField } from 'formik'
|
import { useField } from 'formik'
|
||||||
import Input from '@shared/FormInput'
|
import Input from '@shared/FormInput'
|
||||||
import Error from './Error'
|
import Error from './Error'
|
||||||
|
import { getOpcFees } from '../../../@utils/subgraph'
|
||||||
|
import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery'
|
||||||
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
|
|
||||||
const Default = ({
|
const Default = ({
|
||||||
title,
|
title,
|
||||||
name,
|
name,
|
||||||
tooltip
|
tooltip,
|
||||||
|
value
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
name: string
|
name: string
|
||||||
tooltip: string
|
tooltip: string
|
||||||
|
value: string
|
||||||
}) => (
|
}) => (
|
||||||
<Input
|
<Input
|
||||||
label={
|
label={
|
||||||
@ -21,7 +27,7 @@ const Default = ({
|
|||||||
<Tooltip content={tooltip} />
|
<Tooltip content={tooltip} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
value="0.1"
|
value={value}
|
||||||
name={name}
|
name={name}
|
||||||
postfix="%"
|
postfix="%"
|
||||||
readOnly
|
readOnly
|
||||||
@ -37,6 +43,15 @@ export default function Fees({
|
|||||||
pricingType: 'dynamic' | 'fixed'
|
pricingType: 'dynamic' | 'fixed'
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [field, meta] = useField('pricing.swapFee')
|
const [field, meta] = useField('pricing.swapFee')
|
||||||
|
const [opcFees, setOpcFees] = useState<OpcFeesData>(undefined)
|
||||||
|
const { chainId } = useWeb3()
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getOpcFees(chainId || 1).then((response: OpcFeesData) => {
|
||||||
|
setOpcFees(response)
|
||||||
|
})
|
||||||
|
}, [chainId])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -64,12 +79,18 @@ export default function Fees({
|
|||||||
title="Community Fee"
|
title="Community Fee"
|
||||||
name="communityFee"
|
name="communityFee"
|
||||||
tooltip={tooltips.communityFee}
|
tooltip={tooltips.communityFee}
|
||||||
|
value={opcFees?.swapOceanFee || '0'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Default
|
<Default
|
||||||
title="Marketplace Fee"
|
title="Marketplace Fee"
|
||||||
name="marketplaceFee"
|
name="marketplaceFee"
|
||||||
tooltip={tooltips.marketplaceFee}
|
tooltip={tooltips.marketplaceFee}
|
||||||
|
value={
|
||||||
|
pricingType === 'dynamic'
|
||||||
|
? appConfig.publisherMarketPoolSwapFee
|
||||||
|
: appConfig.publisherMarketFixedSwapFee
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
import { validationSchema } from './_validation'
|
import { validationSchema } from './_validation'
|
||||||
import { useAbortController } from '@hooks/useAbortController'
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
|
import { setNftMetadata } from '@utils/nft'
|
||||||
|
|
||||||
// TODO: restore FormikPersist, add back clear form action
|
// TODO: restore FormikPersist, add back clear form action
|
||||||
const formName = 'ocean-publish-form'
|
const formName = 'ocean-publish-form'
|
||||||
@ -172,23 +173,11 @@ export default function PublishPage({
|
|||||||
|
|
||||||
if (!_ddo || !_encryptedDdo) throw new Error('No DDO received.')
|
if (!_ddo || !_encryptedDdo) throw new Error('No DDO received.')
|
||||||
|
|
||||||
// TODO: this whole setMetadata needs to go in a function ,too many hardcoded/calculated params
|
const res = await setNftMetadata(
|
||||||
// TODO: hash generation : this needs to be moved in a function (probably on ocean.js) after we figure out what is going on in provider, leave it here for now
|
_ddo,
|
||||||
const metadataHash = getHash(JSON.stringify(_ddo))
|
|
||||||
const nft = new Nft(web3)
|
|
||||||
|
|
||||||
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
|
||||||
const flags = '0x2'
|
|
||||||
|
|
||||||
const res = await nft.setMetadata(
|
|
||||||
_erc721Address,
|
|
||||||
accountId,
|
accountId,
|
||||||
0,
|
web3,
|
||||||
values.services[0].providerUrl.url,
|
newAbortController()
|
||||||
'',
|
|
||||||
flags,
|
|
||||||
_encryptedDdo,
|
|
||||||
'0x' + metadataHash
|
|
||||||
)
|
)
|
||||||
|
|
||||||
LoggerInstance.log('[publish] setMetadata result', res)
|
LoggerInstance.log('[publish] setMetadata result', res)
|
||||||
|
14
src/pages/asset/[did]/edit.tsx
Normal file
14
src/pages/asset/[did]/edit.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import EditPage from '../../../components/Asset/Edit'
|
||||||
|
import AssetProvider from '@context/Asset'
|
||||||
|
|
||||||
|
export default function PageEditAsset(): ReactElement {
|
||||||
|
const router = useRouter()
|
||||||
|
const { did } = router.query
|
||||||
|
return (
|
||||||
|
<AssetProvider did={did as string}>
|
||||||
|
<EditPage uri={router.pathname} />
|
||||||
|
</AssetProvider>
|
||||||
|
)
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import PageTemplateAssetDetails from '../../components/Asset'
|
import PageTemplateAssetDetails from '../../../components/Asset'
|
||||||
import AssetProvider from '@context/Asset'
|
import AssetProvider from '@context/Asset'
|
||||||
|
|
||||||
export default function PageAssetDetails(): ReactElement {
|
export default function PageAssetDetails(): ReactElement {
|
Loading…
x
Reference in New Issue
Block a user