1
0
mirror of https://github.com/oceanprotocol/react.git synced 2025-02-14 21:10:38 +01:00

Feature/purgatory (#180)

* add purgatory

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* use purgatory

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* added asset context

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* add refresh price

* add context, fixes

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* format

* temp remove unused

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>
This commit is contained in:
mihaisc 2020-11-13 18:22:22 +02:00 committed by GitHub
parent 4f9e73e64a
commit 293a4734c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 246 additions and 9 deletions

17
package-lock.json generated
View File

@ -1521,9 +1521,9 @@
"integrity": "sha512-p0oOHXr60hXZuLNsQ/PsOQtCfia79thm7MjPxTrnnBvD+csJoHzARYMB0IFj/KTw6U5vLXODgjJAn8x6QksLwg==" "integrity": "sha512-p0oOHXr60hXZuLNsQ/PsOQtCfia79thm7MjPxTrnnBvD+csJoHzARYMB0IFj/KTw6U5vLXODgjJAn8x6QksLwg=="
}, },
"@oceanprotocol/lib": { "@oceanprotocol/lib": {
"version": "0.9.9", "version": "0.9.12",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.9.9.tgz", "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.9.12.tgz",
"integrity": "sha512-U7lqkSFYhg0W/45ucK1/BA1Z0XH6wtGw15u5LxCzRhXWghPVzyRCkdx/xhs9LZAMl6vabWcIlnp07tMVRcNzJw==", "integrity": "sha512-R52kWSwwpKNzNHfnNbF6seFPvXEtExK3bWIi4V4eIkgmAf272sa6PVza4mJrtEpTAS1WcJv5ihF7cczIDecxbg==",
"requires": { "requires": {
"@ethereum-navigator/navigator": "^0.5.0", "@ethereum-navigator/navigator": "^0.5.0",
"@oceanprotocol/contracts": "^0.5.7", "@oceanprotocol/contracts": "^0.5.7",
@ -1537,6 +1537,11 @@
"web3-eth-contract": "^1.3.0" "web3-eth-contract": "^1.3.0"
} }
}, },
"@oceanprotocol/list-purgatory": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@oceanprotocol/list-purgatory/-/list-purgatory-1.0.5.tgz",
"integrity": "sha512-mp/Ru7nB/ATawlyefSQ2AJHyEoLxntmtWjx3kvuXRaIxF3NDVcdjcVVB0VgBAOLawccEXZ6p4AsIPEVyjqx8zw=="
},
"@octokit/auth-token": { "@octokit/auth-token": {
"version": "2.4.3", "version": "2.4.3",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.3.tgz", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.3.tgz",
@ -5858,9 +5863,9 @@
"integrity": "sha1-o9fZb+HD/wZex84nwsIea6ksGDI=" "integrity": "sha1-o9fZb+HD/wZex84nwsIea6ksGDI="
}, },
"is-buffer": { "is-buffer": {
"version": "2.0.4", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
}, },
"is-callable": { "is-callable": {
"version": "1.2.0", "version": "1.2.0",

View File

@ -25,7 +25,7 @@
"dist/" "dist/"
], ],
"dependencies": { "dependencies": {
"@oceanprotocol/lib": "^0.9.9", "@oceanprotocol/lib": "^0.9.12",
"axios": "^0.21.0", "axios": "^0.21.0",
"decimal.js": "^10.2.1", "decimal.js": "^10.2.1",
"web3": "^1.3.0", "web3": "^1.3.0",

View File

@ -0,0 +1,172 @@
import React, {
useContext,
useState,
useEffect,
createContext,
ReactElement,
useCallback,
ReactNode
} from 'react'
import {
Logger,
DDO,
Metadata,
BestPrice,
MetadataCache
} from '@oceanprotocol/lib'
import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData'
import { useOcean } from '../index'
import { isDDO, getDataTokenPrice } from 'utils'
import { getAssetPurgatoryData } from '../../utils/getPurgatoryData'
import ProviderStatus from '../OceanProvider/ProviderStatus'
import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper'
interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: PurgatoryData
ddo: DDO | undefined
did: string | undefined
metadata: Metadata | undefined
title: string | undefined
owner: string | undefined
price: BestPrice | undefined
refreshPrice: () => void
}
const AssetContext = createContext({} as AssetProviderValue)
function AssetProvider({
asset,
children
}: {
asset: string | DDO
children: ReactNode
}): ReactElement {
const { ocean, status, config, networkId } = useOcean()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>()
const [internalDdo, setDDO] = useState<DDO>()
const [internalDid, setDID] = useState<string>()
const [metadata, setMetadata] = useState<Metadata>()
const [title, setTitle] = useState<string>()
const [price, setPrice] = useState<BestPrice>()
const [owner, setOwner] = useState<string>()
const init = useCallback(async () => {
Logger.log('Asset Provider init')
if (!config.metadataCacheUri) return
if (isDDO(asset as string | DDO)) {
setDDO(asset as DDO)
setDID((asset as DDO).id)
} else {
// asset is a DID
const metadataCache = new MetadataCache(config.metadataCacheUri, Logger)
const ddo = await metadataCache.retrieveDDO(asset as string)
Logger.debug('DDO asset', ddo)
setDDO(ddo)
setDID(asset as string)
}
}, [asset, config.metadataCacheUri])
const getPrice = useCallback(async (): Promise<BestPrice> => {
if (!internalDdo)
return {
type: '',
address: '',
value: 0,
ocean: 0,
datatoken: 0
} as BestPrice
const price = await getDataTokenPrice(
ocean,
internalDdo.dataToken,
internalDdo?.price?.type,
internalDdo.price.pools[0]
)
return price
}, [ocean, internalDdo])
useEffect(() => {
// removed until we can properly test and refactor market
// init()
}, [init, asset, ocean, status])
const setPurgatory = useCallback(async (did: string): Promise<void> => {
if (!did) return
try {
const result = await getAssetPurgatoryData(did)
if (result.did !== undefined) {
setIsInPurgatory(true)
setPurgatoryData(result)
} else {
setIsInPurgatory(false)
}
setPurgatoryData(result)
} catch (error) {
Logger.error(error)
}
}, [])
const initMetadata = useCallback(async (): Promise<void> => {
// remove until we can properly implement this
// if (!internalDdo) return
// setPrice(internalDdo.price)
// const metadata = internalDdo.findServiceByType('metadata').attributes
// setMetadata(metadata)
// setTitle(metadata.main.name)
// setOwner(internalDdo.publicKey[0].owner)
// setIsInPurgatory(internalDdo.isInPurgatory)
// setPurgatoryData(internalDdo.purgatoryData)
setMetadata(undefined)
setTitle('not_implemented')
setOwner('not_implemented')
if (!asset) return
await setPurgatory(asset as string)
// Stop here and do not start fetching from chain, when not connected properly.
if (status !== 1 || networkId !== (config as ConfigHelperConfig).networkId)
return
// Set price again, but from chain
const priceLive = await getPrice()
setPrice(priceLive)
}, [internalDdo, getPrice])
useEffect(() => {
if (!internalDdo || !ocean || status !== ProviderStatus.CONNECTED) return
initMetadata()
}, [status, internalDdo, initMetadata])
async function refreshPrice(): Promise<void> {
const livePrice = await getPrice()
setPrice(livePrice)
}
return (
<AssetContext.Provider
value={
{
ddo: internalDdo,
did: internalDid,
metadata,
title,
owner,
price,
isInPurgatory,
purgatoryData,
refreshPrice
} as AssetProviderValue
}
>
{children}
</AssetContext.Provider>
)
}
// Helper hook to access the provider values
const useAsset = (): AssetProviderValue => useContext(AssetContext)
export { AssetProvider, useAsset, AssetProviderValue, AssetContext }
export default AssetProvider

View File

@ -0,0 +1 @@
export * from './AssetProvider'

View File

@ -9,11 +9,21 @@ import React, {
} from 'react' } from 'react'
import Web3 from 'web3' import Web3 from 'web3'
import ProviderStatus from './ProviderStatus' import ProviderStatus from './ProviderStatus'
import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib' import {
Ocean,
Logger,
Account,
Config,
PurgatoryData
} from '@oceanprotocol/lib'
import Web3Modal, { ICoreOptions } from 'web3modal' import Web3Modal, { ICoreOptions } from 'web3modal'
import { getDefaultProviders } from './getDefaultProviders' import { getDefaultProviders } from './getDefaultProviders'
import { getAccountId, getBalance } from 'utils' import { getAccountId, getBalance } from 'utils'
import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper' import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper'
import {
AccountPurgatoryData,
getAccountPurgatoryData
} from 'utils/getPurgatoryData'
interface Balance { interface Balance {
eth: string | undefined eth: string | undefined
@ -27,6 +37,8 @@ interface OceanProviderValue {
ocean: Ocean ocean: Ocean
config: Config | ConfigHelperConfig config: Config | ConfigHelperConfig
account: Account account: Account
isInPurgatory: boolean
purgatoryData: AccountPurgatoryData
accountId: string accountId: string
balance: Balance balance: Balance
networkId: number | undefined networkId: number | undefined
@ -54,6 +66,8 @@ function OceanProvider({
const [networkId, setNetworkId] = useState<number | undefined>() const [networkId, setNetworkId] = useState<number | undefined>()
const [account, setAccount] = useState<Account | undefined>() const [account, setAccount] = useState<Account | undefined>()
const [accountId, setAccountId] = useState<string | undefined>() const [accountId, setAccountId] = useState<string | undefined>()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<AccountPurgatoryData>()
const [config, setConfig] = useState<Config | ConfigHelperConfig>( const [config, setConfig] = useState<Config | ConfigHelperConfig>(
initialConfig initialConfig
) )
@ -65,6 +79,23 @@ function OceanProvider({
ProviderStatus.NOT_AVAILABLE ProviderStatus.NOT_AVAILABLE
) )
const setPurgatory = useCallback(async (accountId: string): Promise<void> => {
if (!accountId) return
try {
const result = await getAccountPurgatoryData(accountId)
if (result.address !== undefined) {
setIsInPurgatory(true)
setPurgatoryData(result)
} else {
setIsInPurgatory(false)
}
setPurgatoryData(result)
} catch (error) {
Logger.error(error)
}
}, [])
const init = useCallback(async () => { const init = useCallback(async () => {
Logger.log('Ocean Provider init') Logger.log('Ocean Provider init')
window && window &&
@ -116,6 +147,8 @@ function OceanProvider({
const balance = await getBalance(account) const balance = await getBalance(account)
setBalance(balance) setBalance(balance)
Logger.log('balance', JSON.stringify(balance)) Logger.log('balance', JSON.stringify(balance))
await setPurgatory(accountId)
} catch (error) { } catch (error) {
Logger.error(error) Logger.error(error)
} }
@ -173,6 +206,8 @@ function OceanProvider({
ocean, ocean,
account, account,
accountId, accountId,
isInPurgatory,
purgatoryData,
balance, balance,
networkId, networkId,
status, status,

View File

@ -1 +1,2 @@
export * from './OceanProvider' export * from './OceanProvider'
export * from './AssetProvider'

View File

@ -86,7 +86,6 @@ export async function getFirstExchange(ocean: Ocean, dataTokenAddress: string) {
dataTokenAddress, dataTokenAddress,
'1' '1'
) )
Logger.log('Found exchanges', tokenExchanges)
if (tokenExchanges === undefined || tokenExchanges.length === 0) { if (tokenExchanges === undefined || tokenExchanges.length === 0) {
return { return {
address: '', address: '',

View File

@ -0,0 +1,24 @@
import { PurgatoryData } from '@oceanprotocol/lib'
import axios from 'axios'
const purgatoryUrl = 'https://market-purgatory.oceanprotocol.com/api/'
export interface AccountPurgatoryData {
address: string
reason: string
}
export async function getAssetPurgatoryData(
did: string
): Promise<PurgatoryData> {
const response = await axios(`${purgatoryUrl}asset?did=${did}`)
const responseJson = await response.data[0]
return { did: responseJson.did, reason: responseJson.reason }
}
export async function getAccountPurgatoryData(
address: string
): Promise<AccountPurgatoryData> {
const response = await axios(`${purgatoryUrl}account?address=${address}`)
const responseJson = await response.data[0]
return { address: responseJson.address, reason: responseJson.reason }
}