mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Feature/wagmi (#1912)
* wagmi + ethers + web3modal setup
* refactor wallet components
* fallback providers, more config
* kick out useWeb3
* remove all useWeb3 imports
* more web3.js usage removal
* isAddress utils replacement
* restore add token / add network
* less accountId changes
* web3 legacy tinkering, utils/web3 → utils/wallet
* legacy web3 object for ocean.js
* graph sync fix, remove custom network switching code
* package updates, merge fixes
* downgrade to ethers v5
* fix project id
* switch to ConnectKit
* connectkit theming
* add existing chains to wagmi
* rewrite getPaymentCollector()
* kick out getPaymentCollector completely, use wagmi hooks instead
* Revert "kick out getPaymentCollector completely, use wagmi hooks instead"
This reverts commit 54c7d1ef1a
.
* switch getPaymentCollector
* calcBaseInGivenDatatokensOut reorg
* wip integrate ocean lib 3.0.0
* update orbis components to use wagmi instead of web hooks
* more oceanjs integration updates
* more refactors
* fix build
* update ocean lib
* fix publish
* fix order fixed rate
* remove logs
* debug and stop infinite cycle orbis connect
* fix orbis dm connection
* mock use network and fix some more tests
* mock wagmi switch network
* mock wagmi useProvider createClient and connectKit getDefaultClient
* fix jest tests
* try storybook fix
* cleanups and bump ocean lib
* fix order
* bump lib to next.5 and add more modal style
* bump ocean.js lib to 3.0.0
---------
Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
This commit is contained in:
parent
ecef35ef61
commit
165a9b0fb3
@ -1,4 +1,5 @@
|
|||||||
#NEXT_PUBLIC_INFURA_PROJECT_ID="xxx"
|
#NEXT_PUBLIC_INFURA_PROJECT_ID="xxx"
|
||||||
|
#NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="xxx"
|
||||||
#NEXT_PUBLIC_MARKET_FEE_ADDRESS="0xxx"
|
#NEXT_PUBLIC_MARKET_FEE_ADDRESS="0xxx"
|
||||||
#NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE="1"
|
#NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE="1"
|
||||||
#NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE="1"
|
#NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE="1"
|
||||||
|
5
.jest/__fixtures__/wagni.ts
Normal file
5
.jest/__fixtures__/wagni.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const network = {
|
||||||
|
account: '0x123',
|
||||||
|
chainId: 1,
|
||||||
|
networkId: 1
|
||||||
|
}
|
3
.jest/__mocks__/connectkit.js
Normal file
3
.jest/__mocks__/connectkit.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function getDefaultClient() {
|
||||||
|
return jest.fn()
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import marketMetadata from '../__fixtures__/marketMetadata'
|
import marketMetadata from '../__fixtures__/marketMetadata'
|
||||||
import userPreferences from '../__fixtures__/userPreferences'
|
import userPreferences from '../__fixtures__/userPreferences'
|
||||||
import web3 from '../__fixtures__/web3'
|
import { network } from '../__fixtures__/wagni'
|
||||||
import { asset } from '../__fixtures__/datasetWithAccessDetails'
|
import { asset } from '../__fixtures__/datasetWithAccessDetails'
|
||||||
|
|
||||||
jest.mock('../../src/@context/MarketMetadata', () => ({
|
jest.mock('../../src/@context/MarketMetadata', () => ({
|
||||||
@ -11,10 +11,13 @@ jest.mock('../../src/@context/UserPreferences', () => ({
|
|||||||
useUserPreferences: () => userPreferences
|
useUserPreferences: () => userPreferences
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock('../../src/@context/Web3', () => ({
|
|
||||||
useWeb3: () => web3
|
|
||||||
}))
|
|
||||||
|
|
||||||
jest.mock('../../../@context/Asset', () => ({
|
jest.mock('../../../@context/Asset', () => ({
|
||||||
useAsset: () => ({ asset })
|
useAsset: () => ({ asset })
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
jest.mock('wagmi', () => ({
|
||||||
|
useNetwork: () => ({ network }),
|
||||||
|
useSwitchNetwork: () => ({ switchNetwork: () => jest.fn() }),
|
||||||
|
useProvider: () => jest.fn(),
|
||||||
|
createClient: () => jest.fn()
|
||||||
|
}))
|
||||||
|
@ -2,6 +2,7 @@ import '@testing-library/jest-dom/extend-expect'
|
|||||||
import { jest } from '@jest/globals'
|
import { jest } from '@jest/globals'
|
||||||
import './__mocks__/matchMedia'
|
import './__mocks__/matchMedia'
|
||||||
import './__mocks__/hooksMocks'
|
import './__mocks__/hooksMocks'
|
||||||
|
import './__mocks__/connectkit'
|
||||||
|
|
||||||
jest.mock('next/router', () => ({
|
jest.mock('next/router', () => ({
|
||||||
useRouter: jest.fn().mockImplementation(() => ({
|
useRouter: jest.fn().mockImplementation(() => ({
|
||||||
|
@ -43,7 +43,10 @@ module.exports = {
|
|||||||
crypto: false,
|
crypto: false,
|
||||||
os: false,
|
os: false,
|
||||||
stream: false,
|
stream: false,
|
||||||
assert: false
|
assert: false,
|
||||||
|
tls: false,
|
||||||
|
net: false,
|
||||||
|
zlib: false
|
||||||
})
|
})
|
||||||
config.resolve.fallback = fallback
|
config.resolve.fallback = fallback
|
||||||
|
|
||||||
|
14
README.md
14
README.md
@ -238,12 +238,12 @@ function Component() {
|
|||||||
For account purgatory:
|
For account purgatory:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount } from 'wagmi'
|
||||||
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
||||||
|
|
||||||
function Component() {
|
function Component() {
|
||||||
const { accountId } = useWeb3()
|
const { address } = useAccount()
|
||||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
const { isInPurgatory, purgatoryData } = useAccountPurgatory(address)
|
||||||
return isInPurgatory ? <div>{purgatoryData.reason}</div> : null
|
return isInPurgatory ? <div>{purgatoryData.reason}</div> : null
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -252,14 +252,12 @@ function Component() {
|
|||||||
|
|
||||||
All displayed chain & network metadata is retrieved from `https://chainid.network` on build time and integrated into NEXT's GraphQL layer. This data source is a community-maintained GitHub repository under [ethereum-lists/chains](https://github.com/ethereum-lists/chains).
|
All displayed chain & network metadata is retrieved from `https://chainid.network` on build time and integrated into NEXT's GraphQL layer. This data source is a community-maintained GitHub repository under [ethereum-lists/chains](https://github.com/ethereum-lists/chains).
|
||||||
|
|
||||||
Within components this metadata can be queried for under `allNetworksMetadataJson`. The `useWeb3()` hook does this in the background to expose the final `networkDisplayName` for use in components:
|
Within components this metadata can be queried for under `allNetworksMetadataJson`. The `useNetworkMetadata()` hook does this in the background to expose the final `networkDisplayName` for use in components:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
export default function NetworkName(): ReactElement {
|
export default function NetworkName(): ReactElement {
|
||||||
const { networkId, isTestnet } = useWeb3()
|
const { isTestnet } = useNetworkMetadata()
|
||||||
const { networksList } = useNetworkMetadata()
|
const { networkData, networkName } = useNetworkMetadata()
|
||||||
const networkData = getNetworkDataById(networksList, networkId)
|
|
||||||
const networkName = getNetworkDisplayName(networkData)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -16,8 +16,6 @@ module.exports = {
|
|||||||
// List of all supported chainIds. Used to populate the Chains user preferences list.
|
// List of all supported chainIds. Used to populate the Chains user preferences list.
|
||||||
chainIdsSupported: [1, 137, 56, 246, 1285, 5, 80001],
|
chainIdsSupported: [1, 137, 56, 246, 1285, 5, 80001],
|
||||||
|
|
||||||
infuraProjectId: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID || 'xxx',
|
|
||||||
|
|
||||||
defaultDatatokenTemplateIndex: 2,
|
defaultDatatokenTemplateIndex: 2,
|
||||||
// The ETH address the marketplace fee will be sent to.
|
// The ETH address the marketplace fee will be sent to.
|
||||||
marketFeeAddress:
|
marketFeeAddress:
|
||||||
|
@ -36,7 +36,9 @@ module.exports = (phase, { defaultConfig }) => {
|
|||||||
crypto: false,
|
crypto: false,
|
||||||
os: false,
|
os: false,
|
||||||
stream: false,
|
stream: false,
|
||||||
assert: false
|
assert: false,
|
||||||
|
tls: false,
|
||||||
|
net: false
|
||||||
})
|
})
|
||||||
config.resolve.fallback = fallback
|
config.resolve.fallback = fallback
|
||||||
|
|
||||||
|
11848
package-lock.json
generated
11848
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -29,20 +29,20 @@
|
|||||||
"@coingecko/cryptoformat": "^0.5.4",
|
"@coingecko/cryptoformat": "^0.5.4",
|
||||||
"@loadable/component": "^5.15.2",
|
"@loadable/component": "^5.15.2",
|
||||||
"@oceanprotocol/art": "^3.2.0",
|
"@oceanprotocol/art": "^3.2.0",
|
||||||
"@oceanprotocol/lib": "^2.7.0",
|
"@oceanprotocol/lib": "^3.0.0",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
||||||
"@orbisclub/orbis-sdk": "^0.4.40",
|
"@orbisclub/orbis-sdk": "^0.4.40",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
"@uiw/react-codemirror": "^4.19.5",
|
"@uiw/react-codemirror": "^4.19.5",
|
||||||
"@urql/exchange-refocus": "^1.0.0",
|
"@urql/exchange-refocus": "^1.0.0",
|
||||||
"@walletconnect/web3-provider": "^1.8.0",
|
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.0",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
|
"connectkit": "^1.2.3",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
"decimal.js": "^10.4.2",
|
"decimal.js": "^10.4.2",
|
||||||
"dom-confetti": "^0.2.2",
|
"dom-confetti": "^0.2.2",
|
||||||
"dotenv": "^16.0.3",
|
"ethers": "^5.7.2",
|
||||||
"filesize": "^10.0.7",
|
"filesize": "^10.0.7",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
@ -52,6 +52,7 @@
|
|||||||
"match-sorter": "^6.3.1",
|
"match-sorter": "^6.3.1",
|
||||||
"myetherwallet-blockies": "^0.1.1",
|
"myetherwallet-blockies": "^0.1.1",
|
||||||
"next": "13.0.5",
|
"next": "13.0.5",
|
||||||
|
"npm": "^9.6.5",
|
||||||
"posthog-js": "^1.51.4",
|
"posthog-js": "^1.51.4",
|
||||||
"query-string": "^8.1.0",
|
"query-string": "^8.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
@ -73,8 +74,7 @@
|
|||||||
"slugify": "^1.6.5",
|
"slugify": "^1.6.5",
|
||||||
"swr": "^1.3.0",
|
"swr": "^1.3.0",
|
||||||
"urql": "^3.0.3",
|
"urql": "^3.0.3",
|
||||||
"web3": "^1.8.1",
|
"wagmi": "^0.12.12",
|
||||||
"web3modal": "^1.9.12",
|
|
||||||
"yup": "^0.32.11"
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -10,7 +10,6 @@ import React, {
|
|||||||
import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
|
import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
|
||||||
import { CancelToken } from 'axios'
|
import { CancelToken } from 'axios'
|
||||||
import { getAsset } from '@utils/aquarius'
|
import { getAsset } from '@utils/aquarius'
|
||||||
import { useWeb3 } from './Web3'
|
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
|
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
|
||||||
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
||||||
@ -18,6 +17,7 @@ import { useIsMounted } from '@hooks/useIsMounted'
|
|||||||
import { useMarketMetadata } from './MarketMetadata'
|
import { useMarketMetadata } from './MarketMetadata'
|
||||||
import { assetStateToString } from '@utils/assetState'
|
import { assetStateToString } from '@utils/assetState'
|
||||||
import { isValidDid } from '@utils/ddo'
|
import { isValidDid } from '@utils/ddo'
|
||||||
|
import { useAccount, useNetwork } from 'wagmi'
|
||||||
|
|
||||||
export interface AssetProviderValue {
|
export interface AssetProviderValue {
|
||||||
isInPurgatory: boolean
|
isInPurgatory: boolean
|
||||||
@ -44,8 +44,9 @@ function AssetProvider({
|
|||||||
children: ReactNode
|
children: ReactNode
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useMarketMetadata()
|
const { appConfig } = useMarketMetadata()
|
||||||
|
const { address: accountId } = useAccount()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
|
||||||
const { chainId, accountId } = useWeb3()
|
|
||||||
const [isInPurgatory, setIsInPurgatory] = useState(false)
|
const [isInPurgatory, setIsInPurgatory] = useState(false)
|
||||||
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
|
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
|
||||||
const [asset, setAsset] = useState<AssetExtended>()
|
const [asset, setAsset] = useState<AssetExtended>()
|
||||||
@ -158,11 +159,11 @@ function AssetProvider({
|
|||||||
// Check user network against asset network
|
// Check user network against asset network
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!chainId || !asset?.chainId) return
|
if (!chain?.id || !asset?.chainId) return
|
||||||
|
|
||||||
const isAssetNetwork = chainId === asset?.chainId
|
const isAssetNetwork = chain?.id === asset?.chainId
|
||||||
setIsAssetNetwork(isAssetNetwork)
|
setIsAssetNetwork(isAssetNetwork)
|
||||||
}, [chainId, asset?.chainId])
|
}, [chain?.id, asset?.chainId])
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Asset owner check against wallet user
|
// Asset owner check against wallet user
|
||||||
|
@ -9,8 +9,8 @@ import React, {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import { useInterval } from '@hooks/useInterval'
|
import { useInterval } from '@hooks/useInterval'
|
||||||
import { Orbis } from '@orbisclub/orbis-sdk'
|
import { Orbis } from '@orbisclub/orbis-sdk'
|
||||||
import { useWeb3 } from '../Web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { useAccount, useSigner, useProvider } from 'wagmi'
|
||||||
import { didToAddress, sleep } from '@shared/DirectMessages/_utils'
|
import { didToAddress, sleep } from '@shared/DirectMessages/_utils'
|
||||||
import { getEnsName } from '@utils/ens'
|
import { getEnsName } from '@utils/ens'
|
||||||
import usePrevious from '@hooks/usePrevious'
|
import usePrevious from '@hooks/usePrevious'
|
||||||
@ -32,7 +32,9 @@ const CONVERSATION_CONTEXT =
|
|||||||
process.env.NEXT_PUBLIC_ORBIS_CONTEXT || 'ocean_market' // Can be changed to whatever
|
process.env.NEXT_PUBLIC_ORBIS_CONTEXT || 'ocean_market' // Can be changed to whatever
|
||||||
|
|
||||||
function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||||
const { web3Provider, accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
|
const web3Provider = useProvider()
|
||||||
const prevAccountId = usePrevious(accountId)
|
const prevAccountId = usePrevious(accountId)
|
||||||
|
|
||||||
const [ceramicSessions, setCeramicSessions] = useLocalStorage<string[]>(
|
const [ceramicSessions, setCeramicSessions] = useLocalStorage<string[]>(
|
||||||
@ -81,12 +83,12 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
address: string
|
address: string
|
||||||
lit?: boolean
|
lit?: boolean
|
||||||
}) => {
|
}) => {
|
||||||
|
const signerProvide: any = signer?.provider
|
||||||
const res = await orbis.connect_v2({
|
const res = await orbis.connect_v2({
|
||||||
provider: web3Provider,
|
provider: signerProvide.provider,
|
||||||
chain: 'ethereum',
|
chain: 'ethereum',
|
||||||
lit
|
lit
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
const { data } = await orbis.getProfile(res.did)
|
const { data } = await orbis.getProfile(res.did)
|
||||||
setAccount(data)
|
setAccount(data)
|
||||||
@ -98,7 +100,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
} else {
|
} else {
|
||||||
await connectOrbis({ address })
|
// await connectOrbis({ address })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +139,12 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
setAccount(data)
|
setAccount(data)
|
||||||
return data
|
return data
|
||||||
} else if (autoConnect) {
|
} else if (autoConnect) {
|
||||||
const data = await connectOrbis({ address, lit })
|
try {
|
||||||
return data
|
const data = await connectOrbis({ address, lit })
|
||||||
|
return data
|
||||||
|
} catch (err) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
resetStates()
|
resetStates()
|
||||||
removeLitSignature()
|
removeLitSignature()
|
||||||
|
@ -7,7 +7,6 @@ export interface OpcFee {
|
|||||||
|
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
metadataCacheUri: string
|
metadataCacheUri: string
|
||||||
infuraProjectId: string
|
|
||||||
chainIds: number[]
|
chainIds: number[]
|
||||||
chainIdsSupported: number[]
|
chainIdsSupported: number[]
|
||||||
defaultDatatokenTemplateIndex: number
|
defaultDatatokenTemplateIndex: number
|
||||||
@ -49,4 +48,5 @@ export interface MarketMetadataProviderValue {
|
|||||||
siteContent: SiteContent
|
siteContent: SiteContent
|
||||||
appConfig: AppConfig
|
appConfig: AppConfig
|
||||||
getOpcFeeForToken: (tokenAddress: string, chainId: number) => string
|
getOpcFeeForToken: (tokenAddress: string, chainId: number) => string
|
||||||
|
approvedBaseTokens: TokenInfo[]
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,13 @@ import { opcQuery } from './_queries'
|
|||||||
import { MarketMetadataProviderValue, OpcFee } from './_types'
|
import { MarketMetadataProviderValue, OpcFee } from './_types'
|
||||||
import siteContent from '../../../content/site.json'
|
import siteContent from '../../../content/site.json'
|
||||||
import appConfig from '../../../app.config'
|
import appConfig from '../../../app.config'
|
||||||
import { fetchData, getQueryContext } from '@utils/subgraph'
|
import {
|
||||||
|
fetchData,
|
||||||
|
getQueryContext,
|
||||||
|
getOpcsApprovedTokens
|
||||||
|
} from '@utils/subgraph'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
|
import { useNetwork, useConnect } from 'wagmi'
|
||||||
|
|
||||||
const MarketMetadataContext = createContext({} as MarketMetadataProviderValue)
|
const MarketMetadataContext = createContext({} as MarketMetadataProviderValue)
|
||||||
|
|
||||||
@ -23,7 +28,11 @@ function MarketMetadataProvider({
|
|||||||
}: {
|
}: {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
|
const { isLoading } = useConnect()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
|
||||||
const [opcFees, setOpcFees] = useState<OpcFee[]>()
|
const [opcFees, setOpcFees] = useState<OpcFee[]>()
|
||||||
|
const [approvedBaseTokens, setApprovedBaseTokens] = useState<TokenInfo[]>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getOpcData() {
|
async function getOpcData() {
|
||||||
@ -64,6 +73,28 @@ function MarketMetadataProvider({
|
|||||||
},
|
},
|
||||||
[opcFees]
|
[opcFees]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// -----------------------------------
|
||||||
|
// Get and set approved base tokens list
|
||||||
|
// -----------------------------------
|
||||||
|
const getApprovedBaseTokens = useCallback(async (chainId: number) => {
|
||||||
|
try {
|
||||||
|
const approvedTokensList = await getOpcsApprovedTokens(chainId)
|
||||||
|
setApprovedBaseTokens(approvedTokensList)
|
||||||
|
LoggerInstance.log(
|
||||||
|
'[MarketMetadata] Approved baseTokens',
|
||||||
|
approvedTokensList
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error('[MarketMetadata] Error: ', error.message)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isLoading) return
|
||||||
|
getApprovedBaseTokens(chain?.id || 1)
|
||||||
|
}, [chain?.id, getApprovedBaseTokens, isLoading])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MarketMetadataContext.Provider
|
<MarketMetadataContext.Provider
|
||||||
value={
|
value={
|
||||||
@ -71,7 +102,8 @@ function MarketMetadataProvider({
|
|||||||
opcFees,
|
opcFees,
|
||||||
siteContent,
|
siteContent,
|
||||||
appConfig,
|
appConfig,
|
||||||
getOpcFeeForToken
|
getOpcFeeForToken,
|
||||||
|
approvedBaseTokens
|
||||||
} as MarketMetadataProviderValue
|
} as MarketMetadataProviderValue
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -16,9 +16,9 @@ import {
|
|||||||
getUserSales
|
getUserSales
|
||||||
} from '@utils/aquarius'
|
} from '@utils/aquarius'
|
||||||
import axios, { CancelToken } from 'axios'
|
import axios, { CancelToken } from 'axios'
|
||||||
import web3 from 'web3'
|
|
||||||
import { useMarketMetadata } from '../MarketMetadata'
|
import { useMarketMetadata } from '../MarketMetadata'
|
||||||
import { getEnsProfile } from '@utils/ens'
|
import { getEnsProfile } from '@utils/ens'
|
||||||
|
import { isAddress } from 'ethers/lib/utils'
|
||||||
|
|
||||||
interface ProfileProviderValue {
|
interface ProfileProviderValue {
|
||||||
profile: Profile
|
profile: Profile
|
||||||
@ -64,7 +64,7 @@ function ProfileProvider({
|
|||||||
// when accountId is no ETH address
|
// when accountId is no ETH address
|
||||||
//
|
//
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isEthAddress = web3.utils.isAddress(accountId)
|
const isEthAddress = isAddress(accountId)
|
||||||
setIsEthAddress(isEthAddress)
|
setIsEthAddress(isEthAddress)
|
||||||
}, [accountId])
|
}, [accountId])
|
||||||
|
|
||||||
|
@ -1,442 +0,0 @@
|
|||||||
import React, {
|
|
||||||
useContext,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
createContext,
|
|
||||||
ReactElement,
|
|
||||||
ReactNode,
|
|
||||||
useCallback
|
|
||||||
} from 'react'
|
|
||||||
import Web3 from 'web3'
|
|
||||||
import Web3Modal, { getProviderInfo, IProviderInfo } from 'web3modal'
|
|
||||||
import { infuraProjectId as infuraId } from '../../app.config'
|
|
||||||
import WalletConnectProvider from '@walletconnect/web3-provider'
|
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
|
||||||
import { isBrowser } from '@utils/index'
|
|
||||||
import { getEnsProfile } from '@utils/ens'
|
|
||||||
import useNetworkMetadata, {
|
|
||||||
getNetworkDataById,
|
|
||||||
getNetworkDisplayName,
|
|
||||||
getNetworkType,
|
|
||||||
NetworkType
|
|
||||||
} from '../@hooks/useNetworkMetadata'
|
|
||||||
import { useMarketMetadata } from './MarketMetadata'
|
|
||||||
import { getTokenBalance } from '@utils/web3'
|
|
||||||
import { getOpcsApprovedTokens } from '@utils/subgraph'
|
|
||||||
|
|
||||||
interface Web3ProviderValue {
|
|
||||||
web3: Web3
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
web3Provider: any
|
|
||||||
web3Modal: Web3Modal
|
|
||||||
web3ProviderInfo: IProviderInfo
|
|
||||||
accountId: string
|
|
||||||
accountEns: string
|
|
||||||
accountEnsAvatar: string
|
|
||||||
balance: UserBalance
|
|
||||||
networkId: number
|
|
||||||
chainId: number
|
|
||||||
networkDisplayName: string
|
|
||||||
networkData: EthereumListsChain
|
|
||||||
block: number
|
|
||||||
isTestnet: boolean
|
|
||||||
web3Loading: boolean
|
|
||||||
isSupportedOceanNetwork: boolean
|
|
||||||
approvedBaseTokens: TokenInfo[]
|
|
||||||
connect: () => Promise<string>
|
|
||||||
logout: () => Promise<void>
|
|
||||||
}
|
|
||||||
|
|
||||||
const web3ModalTheme = {
|
|
||||||
background: 'var(--background-body)',
|
|
||||||
main: 'var(--font-color-heading)',
|
|
||||||
secondary: 'var(--brand-grey-light)',
|
|
||||||
border: 'var(--border-color)',
|
|
||||||
hover: 'var(--background-highlight)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const providerOptions = isBrowser
|
|
||||||
? {
|
|
||||||
walletconnect: {
|
|
||||||
package: WalletConnectProvider,
|
|
||||||
options: {
|
|
||||||
infuraId,
|
|
||||||
rpc: {
|
|
||||||
137: 'https://polygon-rpc.com',
|
|
||||||
80001: 'https://rpc-mumbai.matic.today'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: {}
|
|
||||||
|
|
||||||
export const web3ModalOpts = {
|
|
||||||
cacheProvider: true,
|
|
||||||
providerOptions,
|
|
||||||
theme: web3ModalTheme
|
|
||||||
}
|
|
||||||
|
|
||||||
const refreshInterval = 20000 // 20 sec.
|
|
||||||
|
|
||||||
const Web3Context = createContext({} as Web3ProviderValue)
|
|
||||||
|
|
||||||
function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
|
||||||
const { networksList } = useNetworkMetadata()
|
|
||||||
const { appConfig } = useMarketMetadata()
|
|
||||||
|
|
||||||
const [web3, setWeb3] = useState<Web3>()
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const [web3Provider, setWeb3Provider] = useState<any>()
|
|
||||||
|
|
||||||
const [web3Modal, setWeb3Modal] = useState<Web3Modal>()
|
|
||||||
const [web3ProviderInfo, setWeb3ProviderInfo] = useState<IProviderInfo>()
|
|
||||||
const [networkId, setNetworkId] = useState<number>()
|
|
||||||
const [chainId, setChainId] = useState<number>()
|
|
||||||
const [networkDisplayName, setNetworkDisplayName] = useState<string>()
|
|
||||||
const [networkData, setNetworkData] = useState<EthereumListsChain>()
|
|
||||||
const [block, setBlock] = useState<number>()
|
|
||||||
const [isTestnet, setIsTestnet] = useState<boolean>()
|
|
||||||
const [accountId, setAccountId] = useState<string>()
|
|
||||||
const [accountEns, setAccountEns] = useState<string>()
|
|
||||||
const [accountEnsAvatar, setAccountEnsAvatar] = useState<string>()
|
|
||||||
const [web3Loading, setWeb3Loading] = useState<boolean>(true)
|
|
||||||
const [balance, setBalance] = useState<UserBalance>({
|
|
||||||
eth: '0'
|
|
||||||
})
|
|
||||||
const [isSupportedOceanNetwork, setIsSupportedOceanNetwork] = useState(true)
|
|
||||||
const [approvedBaseTokens, setApprovedBaseTokens] = useState<TokenInfo[]>()
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Helper: connect to web3
|
|
||||||
// -----------------------------------
|
|
||||||
const connect = useCallback(async () => {
|
|
||||||
if (!web3Modal) {
|
|
||||||
setWeb3Loading(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
setWeb3Loading(true)
|
|
||||||
LoggerInstance.log('[web3] Connecting Web3...')
|
|
||||||
|
|
||||||
const provider = await web3Modal?.connect()
|
|
||||||
setWeb3Provider(provider)
|
|
||||||
|
|
||||||
const web3 = new Web3(provider)
|
|
||||||
setWeb3(web3)
|
|
||||||
LoggerInstance.log('[web3] Web3 created.', web3)
|
|
||||||
|
|
||||||
const networkId = await web3.eth.net.getId()
|
|
||||||
setNetworkId(networkId)
|
|
||||||
LoggerInstance.log('[web3] network id ', networkId)
|
|
||||||
|
|
||||||
const chainId = await web3.eth.getChainId()
|
|
||||||
setChainId(chainId)
|
|
||||||
LoggerInstance.log('[web3] chain id ', chainId)
|
|
||||||
|
|
||||||
const accountId = (await web3.eth.getAccounts())[0]
|
|
||||||
setAccountId(accountId)
|
|
||||||
LoggerInstance.log('[web3] account id', accountId)
|
|
||||||
return accountId
|
|
||||||
} catch (error) {
|
|
||||||
LoggerInstance.error('[web3] Error: ', error.message)
|
|
||||||
return null
|
|
||||||
} finally {
|
|
||||||
setWeb3Loading(false)
|
|
||||||
}
|
|
||||||
}, [web3Modal])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Helper: Get approved base tokens list
|
|
||||||
// -----------------------------------
|
|
||||||
const getApprovedBaseTokens = useCallback(async (chainId: number) => {
|
|
||||||
try {
|
|
||||||
const approvedTokensList = await getOpcsApprovedTokens(chainId)
|
|
||||||
setApprovedBaseTokens(approvedTokensList)
|
|
||||||
LoggerInstance.log('[web3] Approved baseTokens', approvedTokensList)
|
|
||||||
} catch (error) {
|
|
||||||
LoggerInstance.error('[web3] Error: ', error.message)
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Helper: Get user balance
|
|
||||||
// -----------------------------------
|
|
||||||
const getUserBalance = useCallback(async () => {
|
|
||||||
if (!accountId || !networkId || !web3 || !networkData) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const userBalance = web3.utils.fromWei(
|
|
||||||
await web3.eth.getBalance(accountId, 'latest')
|
|
||||||
)
|
|
||||||
const key = networkData.nativeCurrency.symbol.toLowerCase()
|
|
||||||
const balance: UserBalance = { [key]: userBalance }
|
|
||||||
|
|
||||||
if (approvedBaseTokens?.length > 0) {
|
|
||||||
await Promise.all(
|
|
||||||
approvedBaseTokens.map(async (token) => {
|
|
||||||
const { address, decimals, symbol } = token
|
|
||||||
const tokenBalance = await getTokenBalance(
|
|
||||||
accountId,
|
|
||||||
decimals,
|
|
||||||
address,
|
|
||||||
web3
|
|
||||||
)
|
|
||||||
balance[symbol.toLocaleLowerCase()] = tokenBalance
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
setBalance(balance)
|
|
||||||
LoggerInstance.log('[web3] Balance: ', balance)
|
|
||||||
} catch (error) {
|
|
||||||
LoggerInstance.error('[web3] Error: ', error.message)
|
|
||||||
}
|
|
||||||
}, [accountId, approvedBaseTokens, networkId, web3, networkData])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Helper: Get user ENS info
|
|
||||||
// -----------------------------------
|
|
||||||
const getUserEns = useCallback(async () => {
|
|
||||||
if (!accountId) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const profile = await getEnsProfile(accountId)
|
|
||||||
|
|
||||||
if (!profile) {
|
|
||||||
setAccountEns(null)
|
|
||||||
setAccountEnsAvatar(null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setAccountEns(profile.name)
|
|
||||||
LoggerInstance.log(
|
|
||||||
`[web3] ENS name found for ${accountId}:`,
|
|
||||||
profile.name
|
|
||||||
)
|
|
||||||
|
|
||||||
if (profile.avatar) {
|
|
||||||
setAccountEnsAvatar(profile.avatar)
|
|
||||||
LoggerInstance.log(
|
|
||||||
`[web3] ENS avatar found for ${accountId}:`,
|
|
||||||
profile.avatar
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
setAccountEnsAvatar(null)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
LoggerInstance.error('[web3] Error: ', error.message)
|
|
||||||
}
|
|
||||||
}, [accountId])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Create initial Web3Modal instance
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
if (web3Modal) {
|
|
||||||
setWeb3Loading(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
// note: needs artificial await here so the log message is reached and output
|
|
||||||
const web3ModalInstance = await new Web3Modal(web3ModalOpts)
|
|
||||||
setWeb3Modal(web3ModalInstance)
|
|
||||||
LoggerInstance.log(
|
|
||||||
'[web3] Web3Modal instance created.',
|
|
||||||
web3ModalInstance
|
|
||||||
)
|
|
||||||
}
|
|
||||||
init()
|
|
||||||
}, [connect, web3Modal])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Reconnect automatically for returning users
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
if (!web3Modal?.cachedProvider) return
|
|
||||||
|
|
||||||
async function connectCached() {
|
|
||||||
LoggerInstance.log(
|
|
||||||
'[web3] Connecting to cached provider: ',
|
|
||||||
web3Modal.cachedProvider
|
|
||||||
)
|
|
||||||
await connect()
|
|
||||||
}
|
|
||||||
connectCached()
|
|
||||||
}, [connect, web3Modal])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set approved base tokens list
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
if (web3Loading) return
|
|
||||||
getApprovedBaseTokens(chainId || 1)
|
|
||||||
}, [chainId, getApprovedBaseTokens, web3Loading])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set user balance
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
getUserBalance()
|
|
||||||
|
|
||||||
// init periodic refresh of wallet balance
|
|
||||||
const balanceInterval = setInterval(() => getUserBalance(), refreshInterval)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearInterval(balanceInterval)
|
|
||||||
}
|
|
||||||
}, [getUserBalance])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set user ENS info
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
getUserEns()
|
|
||||||
}, [getUserEns])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set network metadata
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
if (!networkId) return
|
|
||||||
const networkData = getNetworkDataById(networksList, networkId)
|
|
||||||
setNetworkData(networkData)
|
|
||||||
LoggerInstance.log(
|
|
||||||
networkData
|
|
||||||
? `[web3] Network metadata found.`
|
|
||||||
: `[web3] No network metadata found.`,
|
|
||||||
networkData
|
|
||||||
)
|
|
||||||
|
|
||||||
// Construct network display name
|
|
||||||
const networkDisplayName = getNetworkDisplayName(networkData)
|
|
||||||
setNetworkDisplayName(networkDisplayName)
|
|
||||||
|
|
||||||
setIsTestnet(getNetworkType(networkData) !== NetworkType.Mainnet)
|
|
||||||
|
|
||||||
LoggerInstance.log(
|
|
||||||
`[web3] Network display name set to: ${networkDisplayName}`
|
|
||||||
)
|
|
||||||
}, [networkId, networksList])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set latest head block
|
|
||||||
// -----------------------------------
|
|
||||||
useEffect(() => {
|
|
||||||
if (!web3) return
|
|
||||||
|
|
||||||
async function getBlock() {
|
|
||||||
const block = await web3.eth.getBlockNumber()
|
|
||||||
setBlock(block)
|
|
||||||
LoggerInstance.log('[web3] Head block: ', block)
|
|
||||||
}
|
|
||||||
getBlock()
|
|
||||||
}, [web3, networkId])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Get and set web3 provider info
|
|
||||||
// -----------------------------------
|
|
||||||
// Workaround cause getInjectedProviderName() always returns `MetaMask`
|
|
||||||
// https://github.com/oceanprotocol/market/issues/332
|
|
||||||
useEffect(() => {
|
|
||||||
if (!web3Provider) return
|
|
||||||
|
|
||||||
const providerInfo = getProviderInfo(web3Provider)
|
|
||||||
setWeb3ProviderInfo(providerInfo)
|
|
||||||
}, [web3Provider])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Logout helper
|
|
||||||
// -----------------------------------
|
|
||||||
async function logout() {
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
if ((web3?.currentProvider as any)?.close) {
|
|
||||||
await (web3.currentProvider as any).close()
|
|
||||||
}
|
|
||||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
||||||
|
|
||||||
await web3Modal.clearCachedProvider()
|
|
||||||
}
|
|
||||||
// -----------------------------------
|
|
||||||
// Get valid Networks and set isSupportedOceanNetwork
|
|
||||||
// -----------------------------------
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (appConfig.chainIdsSupported.includes(networkId)) {
|
|
||||||
setIsSupportedOceanNetwork(true)
|
|
||||||
} else {
|
|
||||||
setIsSupportedOceanNetwork(false)
|
|
||||||
}
|
|
||||||
}, [networkId, appConfig.chainIdsSupported])
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Handle change events
|
|
||||||
// -----------------------------------
|
|
||||||
async function handleChainChanged(chainId: string) {
|
|
||||||
LoggerInstance.log('[web3] Chain changed', chainId)
|
|
||||||
const networkId = await web3.eth.net.getId()
|
|
||||||
setChainId(Number(chainId))
|
|
||||||
setNetworkId(Number(networkId))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleNetworkChanged(networkId: string) {
|
|
||||||
LoggerInstance.log('[web3] Network changed', networkId)
|
|
||||||
const chainId = await web3.eth.getChainId()
|
|
||||||
setNetworkId(Number(networkId))
|
|
||||||
setChainId(Number(chainId))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleAccountsChanged(accounts: string[]) {
|
|
||||||
LoggerInstance.log('[web3] Account changed', accounts[0])
|
|
||||||
setAccountId(accounts[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!web3Provider || !web3) return
|
|
||||||
|
|
||||||
web3Provider.on('chainChanged', handleChainChanged)
|
|
||||||
web3Provider.on('networkChanged', handleNetworkChanged)
|
|
||||||
web3Provider.on('accountsChanged', handleAccountsChanged)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
web3Provider.removeListener('chainChanged', handleChainChanged)
|
|
||||||
web3Provider.removeListener('networkChanged', handleNetworkChanged)
|
|
||||||
web3Provider.removeListener('accountsChanged', handleAccountsChanged)
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [web3Provider, web3])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Web3Context.Provider
|
|
||||||
value={{
|
|
||||||
web3,
|
|
||||||
web3Provider,
|
|
||||||
web3Modal,
|
|
||||||
web3ProviderInfo,
|
|
||||||
accountId,
|
|
||||||
accountEns,
|
|
||||||
accountEnsAvatar,
|
|
||||||
balance,
|
|
||||||
networkId,
|
|
||||||
chainId,
|
|
||||||
networkDisplayName,
|
|
||||||
networkData,
|
|
||||||
block,
|
|
||||||
isTestnet,
|
|
||||||
web3Loading,
|
|
||||||
isSupportedOceanNetwork,
|
|
||||||
approvedBaseTokens,
|
|
||||||
connect,
|
|
||||||
logout
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Web3Context.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper hook to access the provider values
|
|
||||||
const useWeb3 = (): Web3ProviderValue => useContext(Web3Context)
|
|
||||||
|
|
||||||
export { Web3Provider, useWeb3, Web3Context }
|
|
||||||
export default Web3Provider
|
|
73
src/@hooks/useBalance.tsx
Normal file
73
src/@hooks/useBalance.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { useState, useEffect, useCallback } from 'react'
|
||||||
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
|
import { useMarketMetadata } from '../@context/MarketMetadata'
|
||||||
|
import {
|
||||||
|
useNetwork,
|
||||||
|
useAccount,
|
||||||
|
useProvider,
|
||||||
|
useBalance as useBalanceWagmi
|
||||||
|
} from 'wagmi'
|
||||||
|
import { getTokenBalance } from '@utils/wallet'
|
||||||
|
|
||||||
|
interface BalanceProviderValue {
|
||||||
|
balance: UserBalance
|
||||||
|
}
|
||||||
|
|
||||||
|
function useBalance(): BalanceProviderValue {
|
||||||
|
const { address } = useAccount()
|
||||||
|
const { data: balanceNativeToken } = useBalanceWagmi({ address })
|
||||||
|
const web3provider = useProvider()
|
||||||
|
const { approvedBaseTokens } = useMarketMetadata()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
|
||||||
|
const [balance, setBalance] = useState<UserBalance>({
|
||||||
|
eth: '0'
|
||||||
|
})
|
||||||
|
|
||||||
|
// -----------------------------------
|
||||||
|
// Helper: Get user balance
|
||||||
|
// -----------------------------------
|
||||||
|
const getUserBalance = useCallback(async () => {
|
||||||
|
if (
|
||||||
|
!balanceNativeToken?.formatted ||
|
||||||
|
!address ||
|
||||||
|
!chain?.id ||
|
||||||
|
!web3provider
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userBalance = balanceNativeToken?.formatted
|
||||||
|
const key = balanceNativeToken?.symbol.toLowerCase()
|
||||||
|
const newBalance: UserBalance = { [key]: userBalance }
|
||||||
|
|
||||||
|
if (approvedBaseTokens?.length > 0) {
|
||||||
|
await Promise.all(
|
||||||
|
approvedBaseTokens.map(async (token) => {
|
||||||
|
const { address: tokenAddress, decimals, symbol } = token
|
||||||
|
const tokenBalance = await getTokenBalance(
|
||||||
|
address,
|
||||||
|
decimals,
|
||||||
|
tokenAddress,
|
||||||
|
web3provider
|
||||||
|
)
|
||||||
|
newBalance[symbol.toLocaleLowerCase()] = tokenBalance
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
setBalance(newBalance)
|
||||||
|
LoggerInstance.log('[useBalance] Balance: ', newBalance)
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error('[useBalance] Error: ', error.message)
|
||||||
|
}
|
||||||
|
}, [address, approvedBaseTokens, chain?.id, web3provider, balanceNativeToken])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getUserBalance()
|
||||||
|
}, [getUserBalance])
|
||||||
|
|
||||||
|
return { balance }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useBalance
|
@ -1,14 +1,10 @@
|
|||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { Config, LoggerInstance } from '@oceanprotocol/lib'
|
import { Config, LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import Web3 from 'web3'
|
|
||||||
import axios, { AxiosResponse } from 'axios'
|
import axios, { AxiosResponse } from 'axios'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import { useBlockNumber } from 'wagmi'
|
||||||
|
|
||||||
const blockDifferenceThreshold = 30
|
const blockDifferenceThreshold = 30
|
||||||
const ethGraphUrl = `https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks`
|
|
||||||
const ethGraphQueryBody =
|
|
||||||
'{"query":" query Blocks{ blocks(first: 1, skip: 0, orderBy: number, orderDirection: desc, where: {number_gt: 9300000}) { id number timestamp author difficulty gasUsed gasLimit } }","variables":{},"operationName":"Blocks"}'
|
|
||||||
const graphQueryBody =
|
const graphQueryBody =
|
||||||
'{"query": "query Meta { _meta { block { hash number } deployment hasIndexingErrors } }", "variables": {},"operationName":"Meta"}'
|
'{"query": "query Meta { _meta { block { hash number } deployment hasIndexingErrors } }", "variables": {},"operationName":"Meta"}'
|
||||||
|
|
||||||
@ -30,21 +26,6 @@ async function fetchGraph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getBlockHead(config: Config) {
|
|
||||||
if (!config) return
|
|
||||||
// for ETH main, get block from graph fetch
|
|
||||||
if (config.network === 'mainnet') {
|
|
||||||
const response: any = await fetchGraph(ethGraphUrl, ethGraphQueryBody)
|
|
||||||
return Number(response?.data?.blocks[0]?.number)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for everything else, create new web3 instance with infura
|
|
||||||
// TODO: this fails randomly , WHY!?!?!?!?!
|
|
||||||
const web3Instance = new Web3(config.nodeUri)
|
|
||||||
const blockHead = await web3Instance.eth.getBlockNumber()
|
|
||||||
return blockHead
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getBlockSubgraph(subgraphUri: string) {
|
async function getBlockSubgraph(subgraphUri: string) {
|
||||||
const response: any = await fetchGraph(
|
const response: any = await fetchGraph(
|
||||||
`${subgraphUri}/subgraphs/name/oceanprotocol/ocean-subgraph`,
|
`${subgraphUri}/subgraphs/name/oceanprotocol/ocean-subgraph`,
|
||||||
@ -55,11 +36,10 @@ async function getBlockSubgraph(subgraphUri: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
|
export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
|
||||||
const { block, web3Loading } = useWeb3()
|
const { data: blockHead, isLoading } = useBlockNumber()
|
||||||
const [blockGraph, setBlockGraph] = useState<number>()
|
const [blockGraph, setBlockGraph] = useState<number>()
|
||||||
const [blockHead, setBlockHead] = useState<number>()
|
|
||||||
const [isGraphSynced, setIsGraphSynced] = useState(true)
|
const [isGraphSynced, setIsGraphSynced] = useState(true)
|
||||||
const [subgraphLoading, setSubgraphLoading] = useState(false)
|
const [isSubgraphLoading, setIsSubgraphLoading] = useState(false)
|
||||||
const [oceanConfig, setOceanConfig] = useState<Config>()
|
const [oceanConfig, setOceanConfig] = useState<Config>()
|
||||||
|
|
||||||
// Grab ocean config based on passed networkId
|
// Grab ocean config based on passed networkId
|
||||||
@ -70,27 +50,21 @@ export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
|
|||||||
setOceanConfig(oceanConfig)
|
setOceanConfig(oceanConfig)
|
||||||
}, [networkId])
|
}, [networkId])
|
||||||
|
|
||||||
// Get and set head block
|
// Log head block
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!oceanConfig?.nodeUri || web3Loading) return
|
if (!blockHead) return
|
||||||
|
LoggerInstance.log('[GraphStatus] Head block: ', blockHead)
|
||||||
async function initBlockHead() {
|
}, [blockHead])
|
||||||
const blockHead = block || (await getBlockHead(oceanConfig))
|
|
||||||
setBlockHead(blockHead)
|
|
||||||
LoggerInstance.log('[GraphStatus] Head block: ', blockHead)
|
|
||||||
}
|
|
||||||
initBlockHead()
|
|
||||||
}, [web3Loading, block, oceanConfig])
|
|
||||||
|
|
||||||
// Get and set subgraph block
|
// Get and set subgraph block
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!oceanConfig?.subgraphUri) return
|
if (!oceanConfig?.subgraphUri) return
|
||||||
|
|
||||||
async function initBlockSubgraph() {
|
async function initBlockSubgraph() {
|
||||||
setSubgraphLoading(true)
|
setIsSubgraphLoading(true)
|
||||||
const blockGraph = await getBlockSubgraph(oceanConfig.subgraphUri)
|
const blockGraph = await getBlockSubgraph(oceanConfig.subgraphUri)
|
||||||
setBlockGraph(blockGraph)
|
setBlockGraph(blockGraph)
|
||||||
setSubgraphLoading(false)
|
setIsSubgraphLoading(false)
|
||||||
LoggerInstance.log(
|
LoggerInstance.log(
|
||||||
'[GraphStatus] Latest block from subgraph: ',
|
'[GraphStatus] Latest block from subgraph: ',
|
||||||
blockGraph
|
blockGraph
|
||||||
@ -101,7 +75,7 @@ export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
|
|||||||
|
|
||||||
// Set sync status
|
// Set sync status
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ((!blockGraph && !blockHead) || web3Loading || subgraphLoading) return
|
if ((!blockGraph && !blockHead) || isLoading || isSubgraphLoading) return
|
||||||
|
|
||||||
const difference = blockHead - blockGraph
|
const difference = blockHead - blockGraph
|
||||||
|
|
||||||
@ -110,7 +84,7 @@ export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
setIsGraphSynced(true)
|
setIsGraphSynced(true)
|
||||||
}, [blockGraph, blockHead, web3Loading, subgraphLoading])
|
}, [blockGraph, blockHead, isLoading, isSubgraphLoading])
|
||||||
|
|
||||||
return { blockHead, blockGraph, isGraphSynced }
|
return { blockHead, blockGraph, isGraphSynced }
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,57 @@
|
|||||||
import { UseNetworkMetadata } from './types'
|
import { UseNetworkMetadata } from './types'
|
||||||
import networkdata from '../../../content/networks-metadata.json'
|
import networkdata from '../../../content/networks-metadata.json'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import {
|
||||||
|
getNetworkDataById,
|
||||||
|
getNetworkDisplayName,
|
||||||
|
getNetworkType,
|
||||||
|
NetworkType
|
||||||
|
} from './utils'
|
||||||
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
|
import { useNetwork } from 'wagmi'
|
||||||
|
|
||||||
export default function useNetworkMetadata(): UseNetworkMetadata {
|
export default function useNetworkMetadata(): UseNetworkMetadata {
|
||||||
|
const { appConfig } = useMarketMetadata()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
|
||||||
|
const [networkDisplayName, setNetworkDisplayName] = useState<string>()
|
||||||
|
const [networkData, setNetworkData] = useState<EthereumListsChain>()
|
||||||
|
const [isTestnet, setIsTestnet] = useState<boolean>()
|
||||||
|
const [isSupportedOceanNetwork, setIsSupportedOceanNetwork] = useState(true)
|
||||||
|
|
||||||
const networksList: EthereumListsChain[] = networkdata
|
const networksList: EthereumListsChain[] = networkdata
|
||||||
return { networksList }
|
|
||||||
|
// -----------------------------------
|
||||||
|
// Get and set network metadata
|
||||||
|
// -----------------------------------
|
||||||
|
useEffect(() => {
|
||||||
|
if (!chain?.id) return
|
||||||
|
|
||||||
|
const networkData = getNetworkDataById(networksList, chain.id)
|
||||||
|
setNetworkData(networkData)
|
||||||
|
|
||||||
|
// Construct network display name
|
||||||
|
const networkDisplayName = getNetworkDisplayName(networkData)
|
||||||
|
setNetworkDisplayName(networkDisplayName)
|
||||||
|
|
||||||
|
// Check if network is supported by Ocean Protocol
|
||||||
|
if (appConfig.chainIdsSupported.includes(chain.id)) {
|
||||||
|
setIsSupportedOceanNetwork(true)
|
||||||
|
} else {
|
||||||
|
setIsSupportedOceanNetwork(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if network is testnet
|
||||||
|
setIsTestnet(getNetworkType(networkData) !== NetworkType.Mainnet)
|
||||||
|
}, [chain?.id, networksList, appConfig.chainIdsSupported])
|
||||||
|
|
||||||
|
return {
|
||||||
|
networksList,
|
||||||
|
networkDisplayName,
|
||||||
|
networkData,
|
||||||
|
isTestnet,
|
||||||
|
isSupportedOceanNetwork
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
export interface UseNetworkMetadata {
|
export interface UseNetworkMetadata {
|
||||||
|
networkDisplayName: string
|
||||||
|
networkData: EthereumListsChain
|
||||||
|
isTestnet: boolean
|
||||||
|
isSupportedOceanNetwork: boolean
|
||||||
networksList: EthereumListsChain[]
|
networksList: EthereumListsChain[]
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { NftFactory } from '@oceanprotocol/lib'
|
import { NftFactory } from '@oceanprotocol/lib'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import { useNetwork, useSigner } from 'wagmi'
|
||||||
|
|
||||||
function useNftFactory(): NftFactory {
|
function useNftFactory(): NftFactory {
|
||||||
const { web3, chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
const [nftFactory, setNftFactory] = useState<NftFactory>()
|
const [nftFactory, setNftFactory] = useState<NftFactory>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!web3 || !chainId) return
|
if (!signer || !chain?.id) return
|
||||||
const config = getOceanConfig(chainId)
|
|
||||||
const factory = new NftFactory(config?.nftFactoryAddress, web3)
|
const config = getOceanConfig(chain.id)
|
||||||
|
const factory = new NftFactory(config?.nftFactoryAddress, signer)
|
||||||
setNftFactory(factory)
|
setNftFactory(factory)
|
||||||
}, [web3, chainId])
|
}, [signer, chain?.id])
|
||||||
|
|
||||||
return nftFactory
|
return nftFactory
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,13 @@ import {
|
|||||||
ProviderFees,
|
ProviderFees,
|
||||||
ProviderInstance
|
ProviderInstance
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { getFixedBuyPrice } from './fixedRateExchange'
|
import { getFixedBuyPrice } from './ocean/fixedRateExchange'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import {
|
import {
|
||||||
consumeMarketOrderFee,
|
consumeMarketOrderFee,
|
||||||
publisherMarketOrderFee
|
publisherMarketOrderFee
|
||||||
} from '../../app.config'
|
} from '../../app.config'
|
||||||
|
import { Signer } from 'ethers'
|
||||||
|
|
||||||
const tokenPriceQuery = gql`
|
const tokenPriceQuery = gql`
|
||||||
query TokenPriceQuery($datatokenId: ID!, $account: String) {
|
query TokenPriceQuery($datatokenId: ID!, $account: String) {
|
||||||
@ -158,7 +159,8 @@ function getAccessDetailsFromTokenPrice(
|
|||||||
*/
|
*/
|
||||||
export async function getOrderPriceAndFees(
|
export async function getOrderPriceAndFees(
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
accountId?: string,
|
accountId: string,
|
||||||
|
signer: Signer,
|
||||||
providerFees?: ProviderFees
|
providerFees?: ProviderFees
|
||||||
): Promise<OrderPriceAndFees> {
|
): Promise<OrderPriceAndFees> {
|
||||||
const orderPriceAndFee = {
|
const orderPriceAndFee = {
|
||||||
@ -187,7 +189,11 @@ export async function getOrderPriceAndFees(
|
|||||||
|
|
||||||
// fetch price and swap fees
|
// fetch price and swap fees
|
||||||
if (asset?.accessDetails?.type === 'fixed') {
|
if (asset?.accessDetails?.type === 'fixed') {
|
||||||
const fixed = await getFixedBuyPrice(asset?.accessDetails, asset?.chainId)
|
const fixed = await getFixedBuyPrice(
|
||||||
|
asset?.accessDetails,
|
||||||
|
asset?.chainId,
|
||||||
|
signer
|
||||||
|
)
|
||||||
orderPriceAndFee.price = fixed.baseTokenAmount
|
orderPriceAndFee.price = fixed.baseTokenAmount
|
||||||
orderPriceAndFee.opcFee = fixed.oceanFeeAmount
|
orderPriceAndFee.opcFee = fixed.oceanFeeAmount
|
||||||
orderPriceAndFee.publisherMarketFixedSwapFee = fixed.marketFeeAmount
|
orderPriceAndFee.publisherMarketFixedSwapFee = fixed.marketFeeAmount
|
||||||
|
@ -143,12 +143,8 @@ export async function getComputeEnviroment(
|
|||||||
const computeEnvs = await ProviderInstance.getComputeEnvironments(
|
const computeEnvs = await ProviderInstance.getComputeEnvironments(
|
||||||
asset.services[0].serviceEndpoint
|
asset.services[0].serviceEndpoint
|
||||||
)
|
)
|
||||||
const computeEnv = Array.isArray(computeEnvs)
|
if (!computeEnvs[asset.chainId][0]) return null
|
||||||
? computeEnvs[0]
|
return computeEnvs[asset.chainId][0]
|
||||||
: computeEnvs[asset.chainId][0]
|
|
||||||
|
|
||||||
if (!computeEnv) return null
|
|
||||||
return computeEnv
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LoggerInstance.error('[compute] Fetch compute enviroment: ', e.message)
|
LoggerInstance.error('[compute] Fetch compute enviroment: ', e.message)
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { LoggerInstance, Datatoken } from '@oceanprotocol/lib'
|
import { LoggerInstance, Datatoken } from '@oceanprotocol/lib'
|
||||||
import Web3 from 'web3'
|
import { Signer, ethers } from 'ethers'
|
||||||
import { TransactionReceipt } from 'web3-core'
|
|
||||||
|
|
||||||
export async function setMinterToPublisher(
|
export async function setMinterToPublisher(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
datatokenAddress: string,
|
datatokenAddress: string,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
setError: (msg: string) => void
|
setError: (msg: string) => void
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const datatokenInstance = new Datatoken(web3)
|
const datatokenInstance = new Datatoken(signer)
|
||||||
|
|
||||||
const response = await datatokenInstance.removeMinter(
|
const response = await datatokenInstance.removeMinter(
|
||||||
datatokenAddress,
|
datatokenAddress,
|
||||||
@ -24,12 +23,12 @@ export async function setMinterToPublisher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function setMinterToDispenser(
|
export async function setMinterToDispenser(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
datatokenAddress: string,
|
datatokenAddress: string,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
setError: (msg: string) => void
|
setError: (msg: string) => void
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const datatokenInstance = new Datatoken(web3)
|
const datatokenInstance = new Datatoken(signer)
|
||||||
|
|
||||||
const response = await datatokenInstance.addMinter(
|
const response = await datatokenInstance.addMinter(
|
||||||
datatokenAddress,
|
datatokenAddress,
|
||||||
|
@ -9,8 +9,7 @@ import {
|
|||||||
NftCreateData
|
NftCreateData
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { SvgWaves } from './SvgWaves'
|
import { SvgWaves } from './SvgWaves'
|
||||||
import Web3 from 'web3'
|
import { Signer, ethers } from 'ethers'
|
||||||
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 {
|
||||||
@ -67,7 +66,7 @@ export function generateNftCreateData(
|
|||||||
nftMetadata: NftMetadata,
|
nftMetadata: NftMetadata,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
transferable = true
|
transferable = true
|
||||||
): any {
|
): NftCreateData {
|
||||||
const nftCreateData: NftCreateData = {
|
const nftCreateData: NftCreateData = {
|
||||||
name: nftMetadata.name,
|
name: nftMetadata.name,
|
||||||
symbol: nftMetadata.symbol,
|
symbol: nftMetadata.symbol,
|
||||||
@ -99,9 +98,9 @@ export function decodeTokenURI(tokenURI: string): NftMetadata {
|
|||||||
export async function setNftMetadata(
|
export async function setNftMetadata(
|
||||||
asset: Asset | DDO,
|
asset: Asset | DDO,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const encryptedDdo = await ProviderInstance.encrypt(
|
const encryptedDdo = await ProviderInstance.encrypt(
|
||||||
asset,
|
asset,
|
||||||
asset.chainId,
|
asset.chainId,
|
||||||
@ -111,7 +110,7 @@ export async function setNftMetadata(
|
|||||||
LoggerInstance.log('[setNftMetadata] Got encrypted DDO', encryptedDdo)
|
LoggerInstance.log('[setNftMetadata] Got encrypted DDO', encryptedDdo)
|
||||||
|
|
||||||
const metadataHash = getHash(JSON.stringify(asset))
|
const metadataHash = getHash(JSON.stringify(asset))
|
||||||
const nft = new Nft(web3)
|
const nft = new Nft(signer)
|
||||||
|
|
||||||
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
||||||
const flags = '0x2'
|
const flags = '0x2'
|
||||||
@ -133,10 +132,10 @@ export async function setNftMetadata(
|
|||||||
export async function setNFTMetadataAndTokenURI(
|
export async function setNFTMetadataAndTokenURI(
|
||||||
asset: Asset | DDO,
|
asset: Asset | DDO,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
nftMetadata: NftMetadata,
|
nftMetadata: NftMetadata,
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const encryptedDdo = await ProviderInstance.encrypt(
|
const encryptedDdo = await ProviderInstance.encrypt(
|
||||||
asset,
|
asset,
|
||||||
asset.chainId,
|
asset.chainId,
|
||||||
@ -159,7 +158,7 @@ export async function setNFTMetadataAndTokenURI(
|
|||||||
external_url: externalUrl
|
external_url: externalUrl
|
||||||
})
|
})
|
||||||
).toString('base64')
|
).toString('base64')
|
||||||
const nft = new Nft(web3)
|
const nft = new Nft(signer)
|
||||||
|
|
||||||
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
||||||
const flags = '0x02'
|
const flags = '0x02'
|
||||||
|
@ -1,35 +1,30 @@
|
|||||||
import { FixedRateExchange, PriceAndFees } from '@oceanprotocol/lib'
|
import {
|
||||||
import { consumeMarketFixedSwapFee } from '../../app.config'
|
amountToUnits,
|
||||||
import Web3 from 'web3'
|
FixedRateExchange,
|
||||||
import { getOceanConfig } from './ocean'
|
PriceAndFees,
|
||||||
import { getDummyWeb3 } from './web3'
|
unitsToAmount
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
|
import { ethers, Signer } from 'ethers'
|
||||||
|
import abiFre from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
|
||||||
|
import { getOceanConfig } from '.'
|
||||||
|
import { consumeMarketFixedSwapFee } from '../../../app.config'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to calculate the price to buy one datatoken from a fixed rate exchange. You need to pass either a web3 object or a chainId. If you pass a chainId a dummy web3 object will be created
|
* This is used to calculate the price to buy one datatoken from a fixed rate exchange. You need to pass either a web3 object or a chainId. If you pass a chainId a dummy web3 object will be created
|
||||||
* @param {AccessDetails} accessDetails
|
|
||||||
* @param {number} chainId
|
|
||||||
* @param {Web3?} web3
|
|
||||||
* @return {Promise<PriceAndFees>}
|
|
||||||
*/
|
*/
|
||||||
export async function getFixedBuyPrice(
|
export async function getFixedBuyPrice(
|
||||||
accessDetails: AccessDetails,
|
accessDetails: AccessDetails,
|
||||||
chainId?: number,
|
chainId: number,
|
||||||
web3?: Web3
|
provider: Signer
|
||||||
): Promise<PriceAndFees> {
|
): Promise<PriceAndFees> {
|
||||||
if (!web3 && !chainId)
|
|
||||||
throw new Error("web3 and chainId can't be undefined at the same time!")
|
|
||||||
|
|
||||||
if (!web3) {
|
|
||||||
web3 = await getDummyWeb3(chainId)
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = getOceanConfig(chainId)
|
const config = getOceanConfig(chainId)
|
||||||
|
|
||||||
const fixed = new FixedRateExchange(config.fixedRateExchangeAddress, web3)
|
const fixed = new FixedRateExchange(config.fixedRateExchangeAddress, provider)
|
||||||
const estimatedPrice = await fixed.calcBaseInGivenDatatokensOut(
|
const estimatedPrice = await fixed.calcBaseInGivenDatatokensOut(
|
||||||
accessDetails.addressOrId,
|
accessDetails.addressOrId,
|
||||||
'1',
|
'1',
|
||||||
consumeMarketFixedSwapFee
|
consumeMarketFixedSwapFee
|
||||||
)
|
)
|
||||||
|
|
||||||
return estimatedPrice
|
return estimatedPrice
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import { ConfigHelper, Config } from '@oceanprotocol/lib'
|
import { ConfigHelper, Config } from '@oceanprotocol/lib'
|
||||||
// import contractAddresses from '@oceanprotocol/contracts/artifacts/address.json'
|
import { ethers } from 'ethers'
|
||||||
|
|
||||||
|
import abiDatatoken from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'
|
||||||
|
|
||||||
export function getOceanConfig(network: string | number): Config {
|
export function getOceanConfig(network: string | number): Config {
|
||||||
const config = new ConfigHelper().getConfig(
|
const config = new ConfigHelper().getConfig(
|
||||||
@ -28,3 +30,18 @@ export function getDevelopmentConfig(): Config {
|
|||||||
subgraphUri: 'https://v4.subgraph.goerli.oceanprotocol.com'
|
subgraphUri: 'https://v4.subgraph.goerli.oceanprotocol.com'
|
||||||
} as Config
|
} as Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getPaymentCollector - returns the current paymentCollector
|
||||||
|
* @param dtAddress datatoken address
|
||||||
|
* @param provider the ethers.js web3 provider
|
||||||
|
* @return {Promise<string>}
|
||||||
|
*/
|
||||||
|
export async function getPaymentCollector(
|
||||||
|
dtAddress: string,
|
||||||
|
provider: ethers.providers.Provider
|
||||||
|
): Promise<string> {
|
||||||
|
const dtContract = new ethers.Contract(dtAddress, abiDatatoken.abi, provider)
|
||||||
|
const paymentCollector = await dtContract.getPaymentCollector()
|
||||||
|
return paymentCollector
|
||||||
|
}
|
@ -13,9 +13,8 @@ import {
|
|||||||
ProviderInstance,
|
ProviderInstance,
|
||||||
ProviderInitialize
|
ProviderInitialize
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import Web3 from 'web3'
|
import { Signer, ethers } from 'ethers'
|
||||||
import { getOceanConfig } from './ocean'
|
import { getOceanConfig } from './ocean'
|
||||||
import { TransactionReceipt } from 'web3-eth'
|
|
||||||
import {
|
import {
|
||||||
marketFeeAddress,
|
marketFeeAddress,
|
||||||
consumeMarketOrderFee,
|
consumeMarketOrderFee,
|
||||||
@ -44,23 +43,24 @@ async function initializeProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param web3
|
* @param signer
|
||||||
* @param asset
|
* @param asset
|
||||||
* @param orderPriceAndFees
|
* @param orderPriceAndFees
|
||||||
* @param accountId
|
* @param accountId
|
||||||
* @param providerFees
|
* @param providerFees
|
||||||
* @param computeConsumerAddress
|
* @param computeConsumerAddress
|
||||||
* @returns {TransactionReceipt} receipt of the order
|
* @returns {ethers.providers.TransactionResponse | BigNumber} receipt of the order
|
||||||
*/
|
*/
|
||||||
export async function order(
|
export async function order(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
orderPriceAndFees: OrderPriceAndFees,
|
orderPriceAndFees: OrderPriceAndFees,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
|
hasDatatoken: boolean,
|
||||||
providerFees?: ProviderFees,
|
providerFees?: ProviderFees,
|
||||||
computeConsumerAddress?: string
|
computeConsumerAddress?: string
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const datatoken = new Datatoken(web3)
|
const datatoken = new Datatoken(signer)
|
||||||
const config = getOceanConfig(asset.chainId)
|
const config = getOceanConfig(asset.chainId)
|
||||||
|
|
||||||
const initializeData = await initializeProvider(
|
const initializeData = await initializeProvider(
|
||||||
@ -97,36 +97,38 @@ export async function order(
|
|||||||
} as FreOrderParams
|
} as FreOrderParams
|
||||||
|
|
||||||
if (asset.accessDetails.templateId === 1) {
|
if (asset.accessDetails.templateId === 1) {
|
||||||
// buy datatoken
|
if (!hasDatatoken) {
|
||||||
const txApprove = await approve(
|
// buy datatoken
|
||||||
web3,
|
const txApprove = await approve(
|
||||||
config,
|
signer,
|
||||||
accountId,
|
config,
|
||||||
asset.accessDetails.baseToken.address,
|
accountId,
|
||||||
config.fixedRateExchangeAddress,
|
asset.accessDetails.baseToken.address,
|
||||||
await amountToUnits(
|
config.fixedRateExchangeAddress,
|
||||||
web3,
|
await amountToUnits(
|
||||||
asset?.accessDetails?.baseToken?.address,
|
signer,
|
||||||
orderPriceAndFees.price
|
asset?.accessDetails?.baseToken?.address,
|
||||||
),
|
orderPriceAndFees.price
|
||||||
false
|
),
|
||||||
)
|
false
|
||||||
if (!txApprove) {
|
)
|
||||||
return
|
if (!txApprove) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const fre = new FixedRateExchange(
|
||||||
|
config.fixedRateExchangeAddress,
|
||||||
|
signer
|
||||||
|
)
|
||||||
|
const freTx = await fre.buyDatatokens(
|
||||||
|
asset.accessDetails?.addressOrId,
|
||||||
|
'1',
|
||||||
|
orderPriceAndFees.price,
|
||||||
|
marketFeeAddress,
|
||||||
|
consumeMarketFixedSwapFee
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const fre = new FixedRateExchange(config.fixedRateExchangeAddress, web3)
|
|
||||||
const freTx = await fre.buyDatatokens(
|
|
||||||
accountId,
|
|
||||||
asset.accessDetails?.addressOrId,
|
|
||||||
'1',
|
|
||||||
orderPriceAndFees.price,
|
|
||||||
marketFeeAddress,
|
|
||||||
consumeMarketFixedSwapFee
|
|
||||||
)
|
|
||||||
|
|
||||||
return await datatoken.startOrder(
|
return await datatoken.startOrder(
|
||||||
asset.accessDetails.datatoken.address,
|
asset.accessDetails.datatoken.address,
|
||||||
accountId,
|
|
||||||
orderParams.consumer,
|
orderParams.consumer,
|
||||||
orderParams.serviceIndex,
|
orderParams.serviceIndex,
|
||||||
orderParams._providerFee,
|
orderParams._providerFee,
|
||||||
@ -135,13 +137,13 @@ export async function order(
|
|||||||
}
|
}
|
||||||
if (asset.accessDetails.templateId === 2) {
|
if (asset.accessDetails.templateId === 2) {
|
||||||
const txApprove = await approve(
|
const txApprove = await approve(
|
||||||
web3,
|
signer,
|
||||||
config,
|
config,
|
||||||
accountId,
|
accountId,
|
||||||
asset.accessDetails.baseToken.address,
|
asset.accessDetails.baseToken.address,
|
||||||
asset.accessDetails.datatoken.address,
|
asset.accessDetails.datatoken.address,
|
||||||
await amountToUnits(
|
await amountToUnits(
|
||||||
web3,
|
signer,
|
||||||
asset?.accessDetails?.baseToken?.address,
|
asset?.accessDetails?.baseToken?.address,
|
||||||
orderPriceAndFees.price
|
orderPriceAndFees.price
|
||||||
),
|
),
|
||||||
@ -152,7 +154,6 @@ export async function order(
|
|||||||
}
|
}
|
||||||
return await datatoken.buyFromFreAndOrder(
|
return await datatoken.buyFromFreAndOrder(
|
||||||
asset.accessDetails.datatoken.address,
|
asset.accessDetails.datatoken.address,
|
||||||
accountId,
|
|
||||||
orderParams,
|
orderParams,
|
||||||
freParams
|
freParams
|
||||||
)
|
)
|
||||||
@ -161,16 +162,14 @@ export async function order(
|
|||||||
}
|
}
|
||||||
case 'free': {
|
case 'free': {
|
||||||
if (asset.accessDetails.templateId === 1) {
|
if (asset.accessDetails.templateId === 1) {
|
||||||
const dispenser = new Dispenser(config.dispenserAddress, web3)
|
const dispenser = new Dispenser(config.dispenserAddress, signer)
|
||||||
const dispenserTx = await dispenser.dispense(
|
const dispenserTx = await dispenser.dispense(
|
||||||
asset.accessDetails?.datatoken.address,
|
asset.accessDetails?.datatoken.address,
|
||||||
accountId,
|
|
||||||
'1',
|
'1',
|
||||||
accountId
|
accountId
|
||||||
)
|
)
|
||||||
return await datatoken.startOrder(
|
return await datatoken.startOrder(
|
||||||
asset.accessDetails.datatoken.address,
|
asset.accessDetails.datatoken.address,
|
||||||
accountId,
|
|
||||||
orderParams.consumer,
|
orderParams.consumer,
|
||||||
orderParams.serviceIndex,
|
orderParams.serviceIndex,
|
||||||
orderParams._providerFee,
|
orderParams._providerFee,
|
||||||
@ -180,7 +179,6 @@ export async function order(
|
|||||||
if (asset.accessDetails.templateId === 2) {
|
if (asset.accessDetails.templateId === 2) {
|
||||||
return await datatoken.buyFromDispenserAndOrder(
|
return await datatoken.buyFromDispenserAndOrder(
|
||||||
asset.services[0].datatokenAddress,
|
asset.services[0].datatokenAddress,
|
||||||
accountId,
|
|
||||||
orderParams,
|
orderParams,
|
||||||
config.dispenserAddress
|
config.dispenserAddress
|
||||||
)
|
)
|
||||||
@ -191,7 +189,7 @@ export async function order(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* called when having a valid order, but with expired provider access, requires approval of the provider fee
|
* called when having a valid order, but with expired provider access, requires approval of the provider fee
|
||||||
* @param web3
|
* @param signer
|
||||||
* @param asset
|
* @param asset
|
||||||
* @param accountId
|
* @param accountId
|
||||||
* @param validOrderTx
|
* @param validOrderTx
|
||||||
@ -199,13 +197,13 @@ export async function order(
|
|||||||
* @returns {TransactionReceipt} receipt of the order
|
* @returns {TransactionReceipt} receipt of the order
|
||||||
*/
|
*/
|
||||||
export async function reuseOrder(
|
export async function reuseOrder(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
validOrderTx: string,
|
validOrderTx: string,
|
||||||
providerFees?: ProviderFees
|
providerFees?: ProviderFees
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const datatoken = new Datatoken(web3)
|
const datatoken = new Datatoken(signer)
|
||||||
const initializeData = await initializeProvider(
|
const initializeData = await initializeProvider(
|
||||||
asset,
|
asset,
|
||||||
accountId,
|
accountId,
|
||||||
@ -214,7 +212,6 @@ export async function reuseOrder(
|
|||||||
|
|
||||||
const tx = await datatoken.reuseOrder(
|
const tx = await datatoken.reuseOrder(
|
||||||
asset.accessDetails.datatoken.address,
|
asset.accessDetails.datatoken.address,
|
||||||
accountId,
|
|
||||||
validOrderTx,
|
validOrderTx,
|
||||||
providerFees || initializeData.providerFee
|
providerFees || initializeData.providerFee
|
||||||
)
|
)
|
||||||
@ -225,16 +222,16 @@ export async function reuseOrder(
|
|||||||
async function approveProviderFee(
|
async function approveProviderFee(
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
providerFeeAmount: string
|
providerFeeAmount: string
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<ethers.providers.TransactionResponse> {
|
||||||
const config = getOceanConfig(asset.chainId)
|
const config = getOceanConfig(asset.chainId)
|
||||||
const baseToken =
|
const baseToken =
|
||||||
asset?.accessDetails?.type === 'free'
|
asset?.accessDetails?.type === 'free'
|
||||||
? getOceanConfig(asset.chainId).oceanTokenAddress
|
? getOceanConfig(asset.chainId).oceanTokenAddress
|
||||||
: asset?.accessDetails?.baseToken?.address
|
: asset?.accessDetails?.baseToken?.address
|
||||||
const txApproveWei = await approveWei(
|
const txApproveWei = await approveWei(
|
||||||
web3,
|
signer,
|
||||||
config,
|
config,
|
||||||
accountId,
|
accountId,
|
||||||
baseToken,
|
baseToken,
|
||||||
@ -249,7 +246,7 @@ async function approveProviderFee(
|
|||||||
* - have validOrder and no providerFees -> then order is valid, providerFees are valid, it returns the valid order value
|
* - have validOrder and no providerFees -> then order is valid, providerFees are valid, it returns the valid order value
|
||||||
* - have validOrder and providerFees -> then order is valid but providerFees are not valid, we need to call reuseOrder and pay only providerFees
|
* - have validOrder and providerFees -> then order is valid but providerFees are not valid, we need to call reuseOrder and pay only providerFees
|
||||||
* - no validOrder -> we need to call order, to pay 1 DT & providerFees
|
* - no validOrder -> we need to call order, to pay 1 DT & providerFees
|
||||||
* @param web3
|
* @param signer
|
||||||
* @param asset
|
* @param asset
|
||||||
* @param orderPriceAndFees
|
* @param orderPriceAndFees
|
||||||
* @param accountId
|
* @param accountId
|
||||||
@ -259,11 +256,12 @@ async function approveProviderFee(
|
|||||||
* @returns {Promise<string>} tx id
|
* @returns {Promise<string>} tx id
|
||||||
*/
|
*/
|
||||||
export async function handleComputeOrder(
|
export async function handleComputeOrder(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
orderPriceAndFees: OrderPriceAndFees,
|
orderPriceAndFees: OrderPriceAndFees,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
initializeData: ProviderComputeInitialize,
|
initializeData: ProviderComputeInitialize,
|
||||||
|
hasDatatoken,
|
||||||
computeConsumerAddress?: string
|
computeConsumerAddress?: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
LoggerInstance.log(
|
LoggerInstance.log(
|
||||||
@ -288,7 +286,7 @@ export async function handleComputeOrder(
|
|||||||
const txApproveProvider = await approveProviderFee(
|
const txApproveProvider = await approveProviderFee(
|
||||||
asset,
|
asset,
|
||||||
accountId,
|
accountId,
|
||||||
web3,
|
signer,
|
||||||
initializeData.providerFee.providerFeeAmount
|
initializeData.providerFee.providerFeeAmount
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -301,30 +299,33 @@ export async function handleComputeOrder(
|
|||||||
if (initializeData?.validOrder) {
|
if (initializeData?.validOrder) {
|
||||||
LoggerInstance.log('[compute] Calling reuseOrder ...', initializeData)
|
LoggerInstance.log('[compute] Calling reuseOrder ...', initializeData)
|
||||||
const txReuseOrder = await reuseOrder(
|
const txReuseOrder = await reuseOrder(
|
||||||
web3,
|
signer,
|
||||||
asset,
|
asset,
|
||||||
accountId,
|
accountId,
|
||||||
initializeData.validOrder,
|
initializeData.validOrder,
|
||||||
initializeData.providerFee
|
initializeData.providerFee
|
||||||
)
|
)
|
||||||
if (!txReuseOrder) throw new Error('Failed to reuse order!')
|
if (!txReuseOrder) throw new Error('Failed to reuse order!')
|
||||||
LoggerInstance.log('[compute] Reused order:', txReuseOrder)
|
const tx = await txReuseOrder.wait()
|
||||||
return txReuseOrder?.transactionHash
|
LoggerInstance.log('[compute] Reused order:', tx)
|
||||||
|
return tx?.transactionHash
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggerInstance.log('[compute] Calling order ...', initializeData)
|
LoggerInstance.log('[compute] Calling order ...', initializeData)
|
||||||
|
|
||||||
const txStartOrder = await order(
|
const txStartOrder = await order(
|
||||||
web3,
|
signer,
|
||||||
asset,
|
asset,
|
||||||
orderPriceAndFees,
|
orderPriceAndFees,
|
||||||
accountId,
|
accountId,
|
||||||
|
hasDatatoken,
|
||||||
initializeData.providerFee,
|
initializeData.providerFee,
|
||||||
computeConsumerAddress
|
computeConsumerAddress
|
||||||
)
|
)
|
||||||
|
|
||||||
LoggerInstance.log('[compute] Order succeeded', txStartOrder)
|
const tx = await txStartOrder.wait()
|
||||||
return txStartOrder?.transactionHash
|
LoggerInstance.log('[compute] Order succeeded', tx)
|
||||||
|
return tx?.transactionHash
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error.message)
|
toast.error(error.message)
|
||||||
LoggerInstance.error(`[compute] ${error.message}`)
|
LoggerInstance.error(`[compute] ${error.message}`)
|
||||||
|
@ -11,11 +11,11 @@ import {
|
|||||||
LoggerInstance,
|
LoggerInstance,
|
||||||
ProviderComputeInitializeResults,
|
ProviderComputeInitializeResults,
|
||||||
ProviderInstance,
|
ProviderInstance,
|
||||||
UrlFile
|
UrlFile,
|
||||||
|
AbiItem
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { QueryHeader } from '@shared/FormInput/InputElement/Headers'
|
import { QueryHeader } from '@shared/FormInput/InputElement/Headers'
|
||||||
import Web3 from 'web3'
|
import { Signer } from 'ethers'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
|
||||||
import { getValidUntilTime } from './compute'
|
import { getValidUntilTime } from './compute'
|
||||||
|
|
||||||
export async function initializeProviderForCompute(
|
export async function initializeProviderForCompute(
|
||||||
@ -173,19 +173,18 @@ export async function getFileInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadFile(
|
export async function downloadFile(
|
||||||
web3: Web3,
|
signer: Signer,
|
||||||
asset: AssetExtended,
|
asset: AssetExtended,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
validOrderTx?: string
|
validOrderTx?: string
|
||||||
) {
|
) {
|
||||||
const downloadUrl = await ProviderInstance.getDownloadUrl(
|
const downloadUrl = await ProviderInstance.getDownloadUrl(
|
||||||
asset.id,
|
asset.id,
|
||||||
accountId,
|
|
||||||
asset.services[0].id,
|
asset.services[0].id,
|
||||||
0,
|
0,
|
||||||
validOrderTx || asset.accessDetails.validOrderTx,
|
validOrderTx || asset.accessDetails.validOrderTx,
|
||||||
asset.services[0].serviceEndpoint,
|
asset.services[0].serviceEndpoint,
|
||||||
web3
|
signer
|
||||||
)
|
)
|
||||||
await downloadFileBrowser(downloadUrl)
|
await downloadFileBrowser(downloadUrl)
|
||||||
}
|
}
|
||||||
|
84
src/@utils/wallet/chains.ts
Normal file
84
src/@utils/wallet/chains.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { Chain } from 'wagmi'
|
||||||
|
import * as wagmiChains from 'wagmi/chains'
|
||||||
|
|
||||||
|
export const energyWeb = {
|
||||||
|
id: 246,
|
||||||
|
name: 'Energy Web Chain',
|
||||||
|
network: 'energyweb',
|
||||||
|
nativeCurrency: {
|
||||||
|
decimals: 18,
|
||||||
|
name: 'EWT',
|
||||||
|
symbol: 'EWT'
|
||||||
|
},
|
||||||
|
rpcUrls: {
|
||||||
|
public: {
|
||||||
|
http: ['https://rpc.energyweb.org'],
|
||||||
|
webSocket: ['wss://rpc.energyweb.org/ws']
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
http: ['https://rpc.energyweb.org'],
|
||||||
|
webSocket: ['wss://rpc.energyweb.org/ws']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blockExplorers: {
|
||||||
|
default: {
|
||||||
|
name: 'Energy Web Chain',
|
||||||
|
url: 'https://explorer.energyweb.org/'
|
||||||
|
},
|
||||||
|
blockscout: {
|
||||||
|
name: 'Energy Web Chain',
|
||||||
|
url: 'https://explorer.energyweb.org/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
testnet: false
|
||||||
|
} as Chain
|
||||||
|
|
||||||
|
// TODO: remove once moonriver is shipped in wagmi as it is already in codebase
|
||||||
|
// https://github.com/wagmi-dev/references/blob/main/packages/chains/src/moonriver.ts
|
||||||
|
export const moonriver = {
|
||||||
|
id: 1285,
|
||||||
|
name: 'Moonriver',
|
||||||
|
network: 'moonriver',
|
||||||
|
nativeCurrency: {
|
||||||
|
decimals: 18,
|
||||||
|
name: 'MOVR',
|
||||||
|
symbol: 'MOVR'
|
||||||
|
},
|
||||||
|
rpcUrls: {
|
||||||
|
public: {
|
||||||
|
http: ['https://moonriver.public.blastapi.io'],
|
||||||
|
webSocket: ['wss://moonriver.public.blastapi.io']
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
http: ['https://moonriver.public.blastapi.io'],
|
||||||
|
webSocket: ['wss://moonriver.public.blastapi.io']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blockExplorers: {
|
||||||
|
default: {
|
||||||
|
name: 'Moonscan',
|
||||||
|
url: 'https://moonriver.moonscan.io'
|
||||||
|
},
|
||||||
|
etherscan: {
|
||||||
|
name: 'Moonscan',
|
||||||
|
url: 'https://moonriver.moonscan.io'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contracts: {
|
||||||
|
multicall3: {
|
||||||
|
address: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
||||||
|
blockCreated: 1597904
|
||||||
|
}
|
||||||
|
},
|
||||||
|
testnet: false
|
||||||
|
} as Chain
|
||||||
|
|
||||||
|
export const getSupportedChains = (chainIdsSupported: number[]): Chain[] => {
|
||||||
|
const chains = [wagmiChains, energyWeb, moonriver].map((chain) => {
|
||||||
|
return Object.values(chain).filter((chain) =>
|
||||||
|
chainIdsSupported.includes(chain.id)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
console.log(chains.flat())
|
||||||
|
return chains.flat()
|
||||||
|
}
|
@ -1,8 +1,37 @@
|
|||||||
import { getNetworkDisplayName } from '@hooks/useNetworkMetadata'
|
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import Web3 from 'web3'
|
import { createClient, erc20ABI } from 'wagmi'
|
||||||
import { getOceanConfig } from './ocean'
|
import { mainnet, polygon, bsc, goerli, polygonMumbai } from 'wagmi/chains'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
import { ethers, Contract } from 'ethers'
|
||||||
|
import { formatEther } from 'ethers/lib/utils'
|
||||||
|
import { getDefaultClient } from 'connectkit'
|
||||||
|
import { energyWeb, moonriver } from './chains'
|
||||||
|
import { getNetworkDisplayName } from '@hooks/useNetworkMetadata'
|
||||||
|
import { getOceanConfig } from '../ocean'
|
||||||
|
|
||||||
|
// Wagmi client
|
||||||
|
export const wagmiClient = createClient(
|
||||||
|
getDefaultClient({
|
||||||
|
appName: 'Ocean Market',
|
||||||
|
infuraId: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID,
|
||||||
|
// TODO: mapping between appConfig.chainIdsSupported and wagmi chainId
|
||||||
|
chains: [mainnet, polygon, bsc, energyWeb, moonriver, goerli, polygonMumbai]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConnectKit CSS overrides
|
||||||
|
// https://docs.family.co/connectkit/theming#theme-variables
|
||||||
|
export const connectKitTheme = {
|
||||||
|
'--ck-font-family': 'var(--font-family-base)',
|
||||||
|
'--ck-border-radius': 'var(--border-radius)',
|
||||||
|
'--ck-overlay-background': 'var(--background-body-transparent)',
|
||||||
|
'--ck-modal-box-shadow': '0 0 20px 20px var(--box-shadow-color)',
|
||||||
|
'--ck-body-background': 'var(--background-body)',
|
||||||
|
'--ck-body-color': 'var(--font-color-text)',
|
||||||
|
'--ck-primary-button-border-radius': 'var(--border-radius)',
|
||||||
|
'--ck-primary-button-color': 'var(--font-color-heading)',
|
||||||
|
'--ck-primary-button-background': 'var(--background-content)',
|
||||||
|
'--ck-secondary-button-border-radius': 'var(--border-radius)'
|
||||||
|
}
|
||||||
|
|
||||||
export function accountTruncate(account: string): string {
|
export function accountTruncate(account: string): string {
|
||||||
if (!account || account === '') return
|
if (!account || account === '') return
|
||||||
@ -10,14 +39,41 @@ export function accountTruncate(account: string): string {
|
|||||||
const truncated = account.replace(middle, '…')
|
const truncated = account.replace(middle, '…')
|
||||||
return truncated
|
return truncated
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* returns a dummy web3 instance, only usable to get info from the chain
|
export async function addTokenToWallet(
|
||||||
* @param chainId
|
address: string,
|
||||||
* @returns Web3 instance
|
symbol: string,
|
||||||
*/
|
logo?: string
|
||||||
export async function getDummyWeb3(chainId: number): Promise<Web3> {
|
): Promise<void> {
|
||||||
const config = getOceanConfig(chainId)
|
const image =
|
||||||
return new Web3(config.nodeUri)
|
logo ||
|
||||||
|
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
||||||
|
|
||||||
|
const tokenMetadata = {
|
||||||
|
type: 'ERC20',
|
||||||
|
options: { address, symbol, image, decimals: 18 }
|
||||||
|
}
|
||||||
|
|
||||||
|
;(window?.ethereum.request as any)(
|
||||||
|
{
|
||||||
|
method: 'wallet_watchAsset',
|
||||||
|
params: tokenMetadata,
|
||||||
|
id: Math.round(Math.random() * 100000)
|
||||||
|
},
|
||||||
|
(err: { code: number; message: string }, added: any) => {
|
||||||
|
if (err || 'error' in added) {
|
||||||
|
LoggerInstance.error(
|
||||||
|
`Couldn't add ${tokenMetadata.options.symbol} (${
|
||||||
|
tokenMetadata.options.address
|
||||||
|
}) to MetaMask, error: ${err.message || added.error}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
LoggerInstance.log(
|
||||||
|
`Added ${tokenMetadata.options.symbol} (${tokenMetadata.options.address}) to MetaMask`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addCustomNetwork(
|
export async function addCustomNetwork(
|
||||||
@ -75,78 +131,19 @@ export async function addCustomNetwork(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addTokenToWallet(
|
|
||||||
web3Provider: any,
|
|
||||||
address: string,
|
|
||||||
symbol: string,
|
|
||||||
logo?: string
|
|
||||||
): Promise<void> {
|
|
||||||
const image =
|
|
||||||
logo ||
|
|
||||||
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
|
||||||
|
|
||||||
const tokenMetadata = {
|
|
||||||
type: 'ERC20',
|
|
||||||
options: { address, symbol, image, decimals: 18 }
|
|
||||||
}
|
|
||||||
|
|
||||||
web3Provider.sendAsync(
|
|
||||||
{
|
|
||||||
method: 'wallet_watchAsset',
|
|
||||||
params: tokenMetadata,
|
|
||||||
id: Math.round(Math.random() * 100000)
|
|
||||||
},
|
|
||||||
(err: { code: number; message: string }, added: any) => {
|
|
||||||
if (err || 'error' in added) {
|
|
||||||
LoggerInstance.error(
|
|
||||||
`Couldn't add ${tokenMetadata.options.symbol} (${
|
|
||||||
tokenMetadata.options.address
|
|
||||||
}) to MetaMask, error: ${err.message || added.error}`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
LoggerInstance.log(
|
|
||||||
`Added ${tokenMetadata.options.symbol} (${tokenMetadata.options.address}) to MetaMask`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getTokenBalance(
|
export async function getTokenBalance(
|
||||||
accountId: string,
|
accountId: string,
|
||||||
decimals: number,
|
decimals: number,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
web3: Web3
|
web3Provider: ethers.providers.Provider
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const minABI = [
|
if (!web3Provider || !accountId || !tokenAddress) return
|
||||||
{
|
|
||||||
constant: true,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
name: '_owner',
|
|
||||||
type: 'address'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'balanceOf',
|
|
||||||
outputs: [
|
|
||||||
{
|
|
||||||
name: 'balance',
|
|
||||||
type: 'uint256'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
payable: false,
|
|
||||||
stateMutability: 'view',
|
|
||||||
type: 'function'
|
|
||||||
}
|
|
||||||
] as AbiItem[]
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const token = new web3.eth.Contract(minABI, tokenAddress, {
|
const token = new Contract(tokenAddress, erc20ABI, web3Provider)
|
||||||
from: accountId
|
const balance = await token.balanceOf(accountId)
|
||||||
})
|
|
||||||
const balance = await token.methods.balanceOf(accountId).call()
|
|
||||||
const adjustedDecimalsBalance = `${balance}${'0'.repeat(18 - decimals)}`
|
const adjustedDecimalsBalance = `${balance}${'0'.repeat(18 - decimals)}`
|
||||||
return web3.utils.fromWei(adjustedDecimalsBalance)
|
return formatEther(adjustedDecimalsBalance)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LoggerInstance.error(`ERROR: Failed to get the balance: ${e.message}`)
|
LoggerInstance.error(`ERROR: Failed to get the balance: ${e.message}`)
|
||||||
}
|
}
|
||||||
@ -157,6 +154,7 @@ export function getTokenBalanceFromSymbol(
|
|||||||
symbol: string
|
symbol: string
|
||||||
): string {
|
): string {
|
||||||
if (!symbol) return
|
if (!symbol) return
|
||||||
|
|
||||||
const baseTokenBalance = balance?.[symbol.toLocaleLowerCase()]
|
const baseTokenBalance = balance?.[symbol.toLocaleLowerCase()]
|
||||||
return baseTokenBalance || '0'
|
return baseTokenBalance || '0'
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { isCID } from '@utils/ipfs'
|
import { isCID } from '@utils/ipfs'
|
||||||
import isUrl from 'is-url-superb'
|
import isUrl from 'is-url-superb'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import web3 from 'web3'
|
import { ethers } from 'ethers'
|
||||||
import { isGoogleUrl } from './url/index'
|
import { isGoogleUrl } from './url/index'
|
||||||
|
|
||||||
export function testLinks(isEdit?: boolean) {
|
export function testLinks(isEdit?: boolean) {
|
||||||
@ -49,7 +49,7 @@ export function testLinks(isEdit?: boolean) {
|
|||||||
: 'Transaction ID not valid.'
|
: 'Transaction ID not valid.'
|
||||||
break
|
break
|
||||||
case 'smartcontract':
|
case 'smartcontract':
|
||||||
validField = web3.utils.isAddress(value?.toString())
|
validField = ethers.utils.isAddress(value?.toString())
|
||||||
errorMessage = !value?.toString()
|
errorMessage = !value?.toString()
|
||||||
? 'Address required.'
|
? 'Address required.'
|
||||||
: 'Address not valid.'
|
: 'Address not valid.'
|
||||||
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||||||
import testRender from '../../../../.jest/testRender'
|
import testRender from '../../../../.jest/testRender'
|
||||||
import AddToken from './index'
|
import AddToken from './index'
|
||||||
|
|
||||||
jest.mock('../../../@utils/web3', () => ({ addTokenToWallet: jest.fn() }))
|
jest.mock('../../../@utils/wallet', () => ({ addTokenToWallet: jest.fn() }))
|
||||||
|
|
||||||
describe('@shared/AddToken', () => {
|
describe('@shared/AddToken', () => {
|
||||||
const propsBase = {
|
const propsBase = {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames/bind'
|
||||||
import { addTokenToWallet } from '@utils/web3'
|
import { addTokenToWallet } from '@utils/wallet'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import OceanLogo from '@images/logo.svg'
|
import OceanLogo from '@images/logo.svg'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
@ -23,8 +22,6 @@ export default function AddToken({
|
|||||||
className,
|
className,
|
||||||
minimal
|
minimal
|
||||||
}: AddTokenProps): ReactElement {
|
}: AddTokenProps): ReactElement {
|
||||||
const { web3Provider } = useWeb3()
|
|
||||||
|
|
||||||
const styleClasses = cx({
|
const styleClasses = cx({
|
||||||
button: true,
|
button: true,
|
||||||
minimal,
|
minimal,
|
||||||
@ -32,9 +29,9 @@ export default function AddToken({
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function handleAddToken() {
|
async function handleAddToken() {
|
||||||
if (!web3Provider) return
|
if (!window?.ethereum) return
|
||||||
|
|
||||||
await addTokenToWallet(web3Provider, address, symbol)
|
await addTokenToWallet(address, symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import styles from './DmButton.module.css'
|
import styles from './DmButton.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount, useConnect } from 'wagmi'
|
||||||
import { useOrbis } from '@context/DirectMessages'
|
import { useOrbis } from '@context/DirectMessages'
|
||||||
|
|
||||||
export default function DmButton({
|
export default function DmButton({
|
||||||
@ -11,7 +11,7 @@ export default function DmButton({
|
|||||||
accountId: string
|
accountId: string
|
||||||
text?: string
|
text?: string
|
||||||
}) {
|
}) {
|
||||||
const { accountId: ownAccountId, connect } = useWeb3()
|
const { address: ownAccountId } = useAccount()
|
||||||
const {
|
const {
|
||||||
checkOrbisConnection,
|
checkOrbisConnection,
|
||||||
getConversationByDid,
|
getConversationByDid,
|
||||||
@ -24,10 +24,9 @@ export default function DmButton({
|
|||||||
const [isCreatingConversation, setIsCreatingConversation] = useState(false)
|
const [isCreatingConversation, setIsCreatingConversation] = useState(false)
|
||||||
|
|
||||||
const handleActivation = async () => {
|
const handleActivation = async () => {
|
||||||
const resConnect = await connect()
|
if (ownAccountId) {
|
||||||
if (resConnect) {
|
|
||||||
await checkOrbisConnection({
|
await checkOrbisConnection({
|
||||||
address: resConnect,
|
address: ownAccountId,
|
||||||
autoConnect: true,
|
autoConnect: true,
|
||||||
lit: true
|
lit: true
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import styles from './Header.module.css'
|
import styles from './Header.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount } from 'wagmi'
|
||||||
import { useOrbis } from '@context/DirectMessages'
|
import { useOrbis } from '@context/DirectMessages'
|
||||||
import { didToAddress } from './_utils'
|
import { didToAddress } from './_utils'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
@ -10,7 +10,7 @@ import ChevronUp from '@images/chevronup.svg'
|
|||||||
import Copy from '@images/copy.svg'
|
import Copy from '@images/copy.svg'
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const {
|
const {
|
||||||
conversations,
|
conversations,
|
||||||
conversationId,
|
conversationId,
|
||||||
|
@ -2,7 +2,7 @@ import React, { useRef } from 'react'
|
|||||||
import styles from './Postbox.module.css'
|
import styles from './Postbox.module.css'
|
||||||
import { useOrbis } from '@context/DirectMessages'
|
import { useOrbis } from '@context/DirectMessages'
|
||||||
import SendIcon from '@images/send.svg'
|
import SendIcon from '@images/send.svg'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import { didToAddress } from './_utils'
|
import { didToAddress } from './_utils'
|
||||||
import {
|
import {
|
||||||
IOrbisMessage,
|
IOrbisMessage,
|
||||||
|
@ -2,19 +2,18 @@ import React from 'react'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import Conversation from './Conversation'
|
import Conversation from './Conversation'
|
||||||
import { useOrbis } from '@context/DirectMessages'
|
import { useOrbis } from '@context/DirectMessages'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount, useConnect } from 'wagmi'
|
||||||
import Header from './Header'
|
import Header from './Header'
|
||||||
import List from './List'
|
import List from './List'
|
||||||
import walletStyles from '../../Header/Wallet/Account.module.css'
|
import walletStyles from '../../Header/Wallet/Account.module.css'
|
||||||
|
|
||||||
const BodyContent = () => {
|
const BodyContent = () => {
|
||||||
const { account, conversationId, checkOrbisConnection } = useOrbis()
|
const { account, conversationId, checkOrbisConnection } = useOrbis()
|
||||||
const { accountId, connect } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
|
||||||
const handleActivation = async (e: React.MouseEvent) => {
|
const handleActivation = async (e: React.MouseEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const resConnect = await connect()
|
if (accountId) {
|
||||||
if (resConnect) {
|
|
||||||
await checkOrbisConnection({
|
await checkOrbisConnection({
|
||||||
address: accountId,
|
address: accountId,
|
||||||
autoConnect: true,
|
autoConnect: true,
|
||||||
|
@ -7,7 +7,7 @@ import { getFileInfo, checkValidProvider } from '@utils/provider'
|
|||||||
import { LoggerInstance, FileInfo } from '@oceanprotocol/lib'
|
import { LoggerInstance, FileInfo } from '@oceanprotocol/lib'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useNetwork } from 'wagmi'
|
||||||
import InputHeaders from '../Headers'
|
import InputHeaders from '../Headers'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import Loader from '@shared/atoms/Loader'
|
import Loader from '@shared/atoms/Loader'
|
||||||
@ -21,7 +21,8 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [disabledButton, setDisabledButton] = useState(true)
|
const [disabledButton, setDisabledButton] = useState(true)
|
||||||
const { asset } = useAsset()
|
const { asset } = useAsset()
|
||||||
const { chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
|
const chainId = chain?.id
|
||||||
|
|
||||||
const providerUrl = props.form?.values?.services
|
const providerUrl = props.form?.values?.services
|
||||||
? props.form?.values?.services[0].providerUrl.url
|
? props.form?.values?.services[0].providerUrl.url
|
||||||
@ -60,7 +61,7 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
query,
|
query,
|
||||||
headers,
|
headers,
|
||||||
abi,
|
abi,
|
||||||
chainId,
|
chain?.id,
|
||||||
method
|
method
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@ import Button from '@shared/atoms/Button'
|
|||||||
import { LoggerInstance, ProviderInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance, ProviderInstance } from '@oceanprotocol/lib'
|
||||||
import { FormPublishData } from '@components/Publish/_types'
|
import { FormPublishData } from '@components/Publish/_types'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
|
import { useNetwork } from 'wagmi'
|
||||||
|
|
||||||
export default function CustomProvider(props: InputProps): ReactElement {
|
export default function CustomProvider(props: InputProps): ReactElement {
|
||||||
const { chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
const { initialValues, setFieldError } = useFormikContext<FormPublishData>()
|
const { initialValues, setFieldError } = useFormikContext<FormPublishData>()
|
||||||
const [field, meta, helpers] = useField(props.name)
|
const [field, meta, helpers] = useField(props.name)
|
||||||
@ -40,7 +40,7 @@ export default function CustomProvider(props: InputProps): ReactElement {
|
|||||||
const providerResponse = await axios.get(field.value.url, {
|
const providerResponse = await axios.get(field.value.url, {
|
||||||
cancelToken: newCancelToken()
|
cancelToken: newCancelToken()
|
||||||
})
|
})
|
||||||
const userChainId = chainId || 1
|
const userChainId = chain?.id || 1
|
||||||
const providerChain =
|
const providerChain =
|
||||||
providerResponse?.data?.chainId || providerResponse?.data?.chainIds
|
providerResponse?.data?.chainId || providerResponse?.data?.chainIds
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ export default function CustomProvider(props: InputProps): ReactElement {
|
|||||||
function handleDefault(e: React.SyntheticEvent) {
|
function handleDefault(e: React.SyntheticEvent) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
const oceanConfig = getOceanConfig(chainId)
|
const oceanConfig = getOceanConfig(chain?.id)
|
||||||
const providerUrl =
|
const providerUrl =
|
||||||
oceanConfig?.providerUri || initialValues.services[0].providerUrl.url
|
oceanConfig?.providerUri || initialValues.services[0].providerUrl.url
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import InputGroup from '@shared/FormInput/InputGroup'
|
|||||||
import InputElement from '@shared/FormInput/InputElement'
|
import InputElement from '@shared/FormInput/InputElement'
|
||||||
import isUrl from 'is-url-superb'
|
import isUrl from 'is-url-superb'
|
||||||
import { isCID } from '@utils/ipfs'
|
import { isCID } from '@utils/ipfs'
|
||||||
import web3 from 'web3'
|
|
||||||
export interface URLInputProps {
|
export interface URLInputProps {
|
||||||
submitText: string
|
submitText: string
|
||||||
handleButtonClick(e: React.SyntheticEvent, data: string): void
|
handleButtonClick(e: React.SyntheticEvent, data: string): void
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import { getEnsName } from '@utils/ens'
|
import { getEnsName } from '@utils/ens'
|
||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { render, fireEvent, screen } from '@testing-library/react'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import WalletNetworkSwitcher from './'
|
import WalletNetworkSwitcher from './'
|
||||||
|
|
||||||
jest.mock('../../../@utils/web3', () => ({
|
jest.mock('../../../@utils/wallet', () => ({
|
||||||
addCustomNetwork: () => jest.fn()
|
addCustomNetwork: () => jest.fn()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { addCustomNetwork } from '@utils/web3'
|
|
||||||
import useNetworkMetadata, {
|
import useNetworkMetadata, {
|
||||||
getNetworkDataById,
|
getNetworkDataById,
|
||||||
getNetworkDisplayName
|
getNetworkDisplayName
|
||||||
} from '@hooks/useNetworkMetadata'
|
} from '@hooks/useNetworkMetadata'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
|
import { useNetwork, useSwitchNetwork } from 'wagmi'
|
||||||
|
|
||||||
export default function WalletNetworkSwitcher(): ReactElement {
|
export default function WalletNetworkSwitcher(): ReactElement {
|
||||||
const { networkId, web3Provider } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
const { asset } = useAsset()
|
const { asset } = useAsset()
|
||||||
|
const { switchNetwork } = useSwitchNetwork({ chainId: asset?.chainId })
|
||||||
const { networksList } = useNetworkMetadata()
|
const { networksList } = useNetworkMetadata()
|
||||||
|
|
||||||
const ddoNetworkData = getNetworkDataById(networksList, asset.chainId)
|
const ddoNetworkData = getNetworkDataById(networksList, asset.chainId)
|
||||||
const walletNetworkData = getNetworkDataById(networksList, networkId)
|
const walletNetworkData = getNetworkDataById(networksList, chain?.id)
|
||||||
|
|
||||||
const ddoNetworkName = (
|
const ddoNetworkName = (
|
||||||
<strong>{getNetworkDisplayName(ddoNetworkData)}</strong>
|
<strong>{getNetworkDisplayName(ddoNetworkData)}</strong>
|
||||||
@ -24,13 +24,6 @@ export default function WalletNetworkSwitcher(): ReactElement {
|
|||||||
<strong>{getNetworkDisplayName(walletNetworkData)}</strong>
|
<strong>{getNetworkDisplayName(walletNetworkData)}</strong>
|
||||||
)
|
)
|
||||||
|
|
||||||
async function switchWalletNetwork() {
|
|
||||||
const networkNode = await networksList.find(
|
|
||||||
(data) => data.chainId === asset.chainId
|
|
||||||
)
|
|
||||||
addCustomNetwork(web3Provider, networkNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className={styles.text}>
|
<p className={styles.text}>
|
||||||
@ -38,7 +31,7 @@ export default function WalletNetworkSwitcher(): ReactElement {
|
|||||||
to {walletNetworkName}. Connect to {ddoNetworkName} to interact with
|
to {walletNetworkName}. Connect to {ddoNetworkName} to interact with
|
||||||
this asset.
|
this asset.
|
||||||
</p>
|
</p>
|
||||||
<Button size="small" onClick={() => switchWalletNetwork()}>
|
<Button size="small" onClick={() => switchNetwork()}>
|
||||||
Switch to {ddoNetworkName}
|
Switch to {ddoNetworkName}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
@ -33,11 +33,11 @@ export default function Web3Feedback({
|
|||||||
if (!accountId) {
|
if (!accountId) {
|
||||||
setState('error')
|
setState('error')
|
||||||
setTitle('No account connected')
|
setTitle('No account connected')
|
||||||
setMessage('Please connect your Web3 wallet.')
|
setMessage('Please connect your wallet.')
|
||||||
} else if (isAssetNetwork === false) {
|
} else if (isAssetNetwork === false) {
|
||||||
setState('error')
|
setState('error')
|
||||||
setTitle('Not connected to asset network')
|
setTitle('Not connected to asset network')
|
||||||
setMessage('Please connect your Web3 wallet.')
|
setMessage('Please connect your wallet.')
|
||||||
} else if (isGraphSynced === false) {
|
} else if (isGraphSynced === false) {
|
||||||
setState('warning')
|
setState('warning')
|
||||||
setTitle('Data out of sync')
|
setTitle('Data out of sync')
|
||||||
|
@ -2,7 +2,6 @@ import React, { ReactElement } from 'react'
|
|||||||
import Alert from '@shared/atoms/Alert'
|
import Alert from '@shared/atoms/Alert'
|
||||||
import Footer from '../Footer/Footer'
|
import Footer from '../Footer/Footer'
|
||||||
import Header from '../Header'
|
import Header from '../Header'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
||||||
import AnnouncementBanner from '@shared/AnnouncementBanner'
|
import AnnouncementBanner from '@shared/AnnouncementBanner'
|
||||||
import PrivacyPreferenceCenter from '../Privacy/PrivacyPreferenceCenter'
|
import PrivacyPreferenceCenter from '../Privacy/PrivacyPreferenceCenter'
|
||||||
@ -10,6 +9,7 @@ import styles from './index.module.css'
|
|||||||
import { ToastContainer } from 'react-toastify'
|
import { ToastContainer } from 'react-toastify'
|
||||||
import contentPurgatory from '../../../content/purgatory.json'
|
import contentPurgatory from '../../../content/purgatory.json'
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function App({
|
export default function App({
|
||||||
children
|
children
|
||||||
@ -17,8 +17,8 @@ export default function App({
|
|||||||
children: ReactElement
|
children: ReactElement
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { siteContent, appConfig } = useMarketMetadata()
|
const { siteContent, appConfig } = useMarketMetadata()
|
||||||
const { accountId } = useWeb3()
|
const { address } = useAccount()
|
||||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
const { isInPurgatory, purgatoryData } = useAccountPurgatory(address)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import { formatNumber } from '@utils/numbers'
|
import { formatNumber } from '@utils/numbers'
|
||||||
import { getNftOwnAllocation } from '@utils/veAllocation'
|
import { getNftOwnAllocation } from '@utils/veAllocation'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
|
||||||
export default function AssetStats() {
|
export default function AssetStats() {
|
||||||
const { locale } = useUserPreferences()
|
const { locale } = useUserPreferences()
|
||||||
const { asset } = useAsset()
|
const { asset } = useAsset()
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
|
||||||
const [ownAllocation, setOwnAllocation] = useState(0)
|
const [ownAllocation, setOwnAllocation] = useState(0)
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ const downloadProps: ButtonBuyProps = {
|
|||||||
priceType: 'fixed',
|
priceType: 'fixed',
|
||||||
isConsumable: true,
|
isConsumable: true,
|
||||||
isBalanceSufficient: true,
|
isBalanceSufficient: true,
|
||||||
consumableFeedback: 'TEST: consumableFeedback'
|
consumableFeedback: 'TEST: consumableFeedback',
|
||||||
|
isAccountConnected: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const computeProps: ButtonBuyProps = {
|
const computeProps: ButtonBuyProps = {
|
||||||
@ -114,7 +115,7 @@ describe('Asset/AssetActions/ButtonBuy', () => {
|
|||||||
render(<ButtonBuy {...computeProps} />)
|
render(<ButtonBuy {...computeProps} />)
|
||||||
expect(
|
expect(
|
||||||
screen.getByText(
|
screen.getByText(
|
||||||
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Additionally, the selected selectedComputeAssetType is free to use. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
||||||
)
|
)
|
||||||
).toBeInTheDocument()
|
).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
@ -123,7 +124,7 @@ describe('Asset/AssetActions/ButtonBuy', () => {
|
|||||||
render(<ButtonBuy {...computeProps} priceType="free" />)
|
render(<ButtonBuy {...computeProps} priceType="free" />)
|
||||||
expect(
|
expect(
|
||||||
screen.getByText(
|
screen.getByText(
|
||||||
'This algorithm is free to use. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
'This algorithm is free to use. Additionally, the selected selectedComputeAssetType is free to use. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
||||||
)
|
)
|
||||||
).toBeInTheDocument()
|
).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
@ -132,7 +133,7 @@ describe('Asset/AssetActions/ButtonBuy', () => {
|
|||||||
render(<ButtonBuy {...computeProps} algorithmPriceType="fixed" />)
|
render(<ButtonBuy {...computeProps} algorithmPriceType="fixed" />)
|
||||||
expect(
|
expect(
|
||||||
screen.getByText(
|
screen.getByText(
|
||||||
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them.'
|
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Additionally, you will buy 1 dtSymbol for the selectedComputeAssetType and send it back to the publisher. The C2D resources required to start the job are available, no payment is required for them.'
|
||||||
)
|
)
|
||||||
).toBeInTheDocument()
|
).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
@ -2,8 +2,6 @@ import React, { FormEvent, ReactElement } from 'react'
|
|||||||
import Button from '../../../@shared/atoms/Button'
|
import Button from '../../../@shared/atoms/Button'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import Loader from '../../../@shared/atoms/Loader'
|
import Loader from '../../../@shared/atoms/Loader'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Web3 from 'web3'
|
|
||||||
|
|
||||||
export interface ButtonBuyProps {
|
export interface ButtonBuyProps {
|
||||||
action: 'download' | 'compute'
|
action: 'download' | 'compute'
|
||||||
@ -31,6 +29,7 @@ export interface ButtonBuyProps {
|
|||||||
algorithmPriceType?: string
|
algorithmPriceType?: string
|
||||||
isAlgorithmConsumable?: boolean
|
isAlgorithmConsumable?: boolean
|
||||||
isSupportedOceanNetwork?: boolean
|
isSupportedOceanNetwork?: boolean
|
||||||
|
isAccountConnected?: boolean
|
||||||
hasProviderFee?: boolean
|
hasProviderFee?: boolean
|
||||||
retry?: boolean
|
retry?: boolean
|
||||||
}
|
}
|
||||||
@ -46,13 +45,13 @@ function getConsumeHelpText(
|
|||||||
isBalanceSufficient: boolean,
|
isBalanceSufficient: boolean,
|
||||||
consumableFeedback: string,
|
consumableFeedback: string,
|
||||||
isSupportedOceanNetwork: boolean,
|
isSupportedOceanNetwork: boolean,
|
||||||
web3: Web3,
|
isAccountConnected: boolean,
|
||||||
priceType: string
|
priceType: string
|
||||||
) {
|
) {
|
||||||
const text =
|
const text =
|
||||||
isConsumable === false
|
isConsumable === false
|
||||||
? consumableFeedback
|
? consumableFeedback
|
||||||
: hasPreviousOrder && web3 && isSupportedOceanNetwork
|
: hasPreviousOrder && isAccountConnected && isSupportedOceanNetwork
|
||||||
? `You bought this ${assetType} already allowing you to use it without paying again.`
|
? `You bought this ${assetType} already allowing you to use it without paying again.`
|
||||||
: hasDatatoken
|
: hasDatatoken
|
||||||
? `You own ${dtBalance} ${dtSymbol} allowing you to use this dataset by spending 1 ${dtSymbol}, but without paying ${btSymbol} again.`
|
? `You own ${dtBalance} ${dtSymbol} allowing you to use this dataset by spending 1 ${dtSymbol}, but without paying ${btSymbol} again.`
|
||||||
@ -74,7 +73,7 @@ function getAlgoHelpText(
|
|||||||
hasDatatokenSelectedComputeAsset: boolean,
|
hasDatatokenSelectedComputeAsset: boolean,
|
||||||
isBalanceSufficient: boolean,
|
isBalanceSufficient: boolean,
|
||||||
isSupportedOceanNetwork: boolean,
|
isSupportedOceanNetwork: boolean,
|
||||||
web3: Web3,
|
isAccountConnected: boolean,
|
||||||
algorithmPriceType: string
|
algorithmPriceType: string
|
||||||
) {
|
) {
|
||||||
const text =
|
const text =
|
||||||
@ -82,11 +81,13 @@ function getAlgoHelpText(
|
|||||||
isConsumable === false ||
|
isConsumable === false ||
|
||||||
isAlgorithmConsumable === false
|
isAlgorithmConsumable === false
|
||||||
? ''
|
? ''
|
||||||
: hasPreviousOrderSelectedComputeAsset && web3 && isSupportedOceanNetwork
|
: hasPreviousOrderSelectedComputeAsset &&
|
||||||
|
isAccountConnected &&
|
||||||
|
isSupportedOceanNetwork
|
||||||
? `You already bought the selected ${selectedComputeAssetType}, allowing you to use it without paying again.`
|
? `You already bought the selected ${selectedComputeAssetType}, allowing you to use it without paying again.`
|
||||||
: hasDatatokenSelectedComputeAsset
|
: hasDatatokenSelectedComputeAsset
|
||||||
? `You own ${dtBalanceSelectedComputeAsset} ${dtSymbolSelectedComputeAsset} allowing you to use the selected ${selectedComputeAssetType} by spending 1 ${dtSymbolSelectedComputeAsset}, but without paying OCEAN again.`
|
? `You own ${dtBalanceSelectedComputeAsset} ${dtSymbolSelectedComputeAsset} allowing you to use the selected ${selectedComputeAssetType} by spending 1 ${dtSymbolSelectedComputeAsset}, but without paying OCEAN again.`
|
||||||
: web3 && !isSupportedOceanNetwork
|
: isAccountConnected && !isSupportedOceanNetwork
|
||||||
? `Connect to the correct network to interact with this asset.`
|
? `Connect to the correct network to interact with this asset.`
|
||||||
: isBalanceSufficient === false
|
: isBalanceSufficient === false
|
||||||
? ''
|
? ''
|
||||||
@ -115,7 +116,7 @@ function getComputeAssetHelpText(
|
|||||||
selectedComputeAssetType?: string,
|
selectedComputeAssetType?: string,
|
||||||
isAlgorithmConsumable?: boolean,
|
isAlgorithmConsumable?: boolean,
|
||||||
isSupportedOceanNetwork?: boolean,
|
isSupportedOceanNetwork?: boolean,
|
||||||
web3?: Web3,
|
isAccountConnected?: boolean,
|
||||||
hasProviderFee?: boolean
|
hasProviderFee?: boolean
|
||||||
) {
|
) {
|
||||||
const computeAssetHelpText = getConsumeHelpText(
|
const computeAssetHelpText = getConsumeHelpText(
|
||||||
@ -129,7 +130,7 @@ function getComputeAssetHelpText(
|
|||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
consumableFeedback,
|
consumableFeedback,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3,
|
isAccountConnected,
|
||||||
priceType
|
priceType
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ function getComputeAssetHelpText(
|
|||||||
hasDatatokenSelectedComputeAsset,
|
hasDatatokenSelectedComputeAsset,
|
||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3,
|
isAccountConnected,
|
||||||
algorithmPriceType
|
algorithmPriceType
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -183,9 +184,9 @@ export default function ButtonBuy({
|
|||||||
isAlgorithmConsumable,
|
isAlgorithmConsumable,
|
||||||
hasProviderFee,
|
hasProviderFee,
|
||||||
retry,
|
retry,
|
||||||
isSupportedOceanNetwork
|
isSupportedOceanNetwork,
|
||||||
|
isAccountConnected
|
||||||
}: ButtonBuyProps): ReactElement {
|
}: ButtonBuyProps): ReactElement {
|
||||||
const { web3 } = useWeb3()
|
|
||||||
const buttonText = retry
|
const buttonText = retry
|
||||||
? 'Retry'
|
? 'Retry'
|
||||||
: action === 'download'
|
: action === 'download'
|
||||||
@ -216,7 +217,7 @@ export default function ButtonBuy({
|
|||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
consumableFeedback,
|
consumableFeedback,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3,
|
isAccountConnected,
|
||||||
priceType
|
priceType
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -239,7 +240,7 @@ export default function ButtonBuy({
|
|||||||
selectedComputeAssetType,
|
selectedComputeAssetType,
|
||||||
isAlgorithmConsumable,
|
isAlgorithmConsumable,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3,
|
isAccountConnected,
|
||||||
hasProviderFee
|
hasProviderFee
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,17 @@ import { compareAsBN } from '@utils/numbers'
|
|||||||
import ButtonBuy from '../ButtonBuy'
|
import ButtonBuy from '../ButtonBuy'
|
||||||
import PriceOutput from './PriceOutput'
|
import PriceOutput from './PriceOutput'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import content from '../../../../../content/pages/startComputeDataset.json'
|
import content from '../../../../../content/pages/startComputeDataset.json'
|
||||||
import { Asset, ZERO_ADDRESS } from '@oceanprotocol/lib'
|
import { Asset, ZERO_ADDRESS } from '@oceanprotocol/lib'
|
||||||
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
import Alert from '@shared/atoms/Alert'
|
import Alert from '@shared/atoms/Alert'
|
||||||
import { getTokenBalanceFromSymbol } from '@utils/web3'
|
import { getTokenBalanceFromSymbol } from '@utils/wallet'
|
||||||
import { MAX_DECIMALS } from '@utils/constants'
|
import { MAX_DECIMALS } from '@utils/constants'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
import useBalance from '@hooks/useBalance'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
export default function FormStartCompute({
|
export default function FormStartCompute({
|
||||||
algorithms,
|
algorithms,
|
||||||
@ -77,7 +79,9 @@ export default function FormStartCompute({
|
|||||||
retry: boolean
|
retry: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { siteContent } = useMarketMetadata()
|
const { siteContent } = useMarketMetadata()
|
||||||
const { accountId, balance, isSupportedOceanNetwork } = useWeb3()
|
const { address: accountId, isConnected } = useAccount()
|
||||||
|
const { balance } = useBalance()
|
||||||
|
const { isSupportedOceanNetwork } = useNetworkMetadata()
|
||||||
const { isValid, values }: FormikContextType<{ algorithm: string }> =
|
const { isValid, values }: FormikContextType<{ algorithm: string }> =
|
||||||
useFormikContext()
|
useFormikContext()
|
||||||
const { asset, isAssetNetwork } = useAsset()
|
const { asset, isAssetNetwork } = useAsset()
|
||||||
@ -303,6 +307,7 @@ export default function FormStartCompute({
|
|||||||
isSupportedOceanNetwork={isSupportedOceanNetwork}
|
isSupportedOceanNetwork={isSupportedOceanNetwork}
|
||||||
hasProviderFee={providerFeeAmount && providerFeeAmount !== '0'}
|
hasProviderFee={providerFeeAmount && providerFeeAmount !== '0'}
|
||||||
retry={retry}
|
retry={retry}
|
||||||
|
isAccountConnected={isConnected}
|
||||||
/>
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,7 @@ import Tooltip from '@shared/atoms/Tooltip'
|
|||||||
import styles from './PriceOutput.module.css'
|
import styles from './PriceOutput.module.css'
|
||||||
import { MAX_DECIMALS } from '@utils/constants'
|
import { MAX_DECIMALS } from '@utils/constants'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
interface PriceOutputProps {
|
interface PriceOutputProps {
|
||||||
hasPreviousOrder: boolean
|
hasPreviousOrder: boolean
|
||||||
|
@ -20,7 +20,6 @@ import { toast } from 'react-toastify'
|
|||||||
import Price from '@shared/Price'
|
import Price from '@shared/Price'
|
||||||
import FileIcon from '@shared/FileIcon'
|
import FileIcon from '@shared/FileIcon'
|
||||||
import Alert from '@shared/atoms/Alert'
|
import Alert from '@shared/atoms/Alert'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import { getInitialValues, validationSchema } from './_constants'
|
import { getInitialValues, validationSchema } from './_constants'
|
||||||
import FormStartComputeDataset from './FormComputeDataset'
|
import FormStartComputeDataset from './FormComputeDataset'
|
||||||
@ -44,12 +43,12 @@ import { useAbortController } from '@hooks/useAbortController'
|
|||||||
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
||||||
import { handleComputeOrder } from '@utils/order'
|
import { handleComputeOrder } from '@utils/order'
|
||||||
import { getComputeFeedback } from '@utils/feedback'
|
import { getComputeFeedback } from '@utils/feedback'
|
||||||
import { getDummyWeb3 } from '@utils/web3'
|
|
||||||
import { initializeProviderForCompute } from '@utils/provider'
|
import { initializeProviderForCompute } from '@utils/provider'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAccount, useSigner } from 'wagmi'
|
||||||
|
|
||||||
const refreshInterval = 10000 // 10 sec.
|
const refreshInterval = 10000 // 10 sec.
|
||||||
|
|
||||||
export default function Compute({
|
export default function Compute({
|
||||||
asset,
|
asset,
|
||||||
dtBalance,
|
dtBalance,
|
||||||
@ -63,9 +62,9 @@ export default function Compute({
|
|||||||
fileIsLoading?: boolean
|
fileIsLoading?: boolean
|
||||||
consumableFeedback?: string
|
consumableFeedback?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, web3, isSupportedOceanNetwork, networkId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { data: signer } = useSigner()
|
||||||
|
|
||||||
const newAbortController = useAbortController()
|
const newAbortController = useAbortController()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
@ -116,10 +115,9 @@ export default function Compute({
|
|||||||
|
|
||||||
const isUnsupportedPricing = asset?.accessDetails?.type === 'NOT_SUPPORTED'
|
const isUnsupportedPricing = asset?.accessDetails?.type === 'NOT_SUPPORTED'
|
||||||
|
|
||||||
async function checkAssetDTBalance(asset: DDO): Promise<boolean> {
|
async function checkAssetDTBalance(asset: DDO) {
|
||||||
if (!asset?.services[0].datatokenAddress) return
|
if (!asset?.services[0].datatokenAddress) return
|
||||||
const web3 = await getDummyWeb3(asset?.chainId)
|
const datatokenInstance = new Datatoken(signer)
|
||||||
const datatokenInstance = new Datatoken(web3)
|
|
||||||
const dtBalance = await datatokenInstance.balance(
|
const dtBalance = await datatokenInstance.balance(
|
||||||
asset?.services[0].datatokenAddress,
|
asset?.services[0].datatokenAddress,
|
||||||
accountId || ZERO_ADDRESS // if the user is not connected, we use ZERO_ADDRESS as accountId
|
accountId || ZERO_ADDRESS // if the user is not connected, we use ZERO_ADDRESS as accountId
|
||||||
@ -127,7 +125,6 @@ export default function Compute({
|
|||||||
setAlgorithmDTBalance(new Decimal(dtBalance).toString())
|
setAlgorithmDTBalance(new Decimal(dtBalance).toString())
|
||||||
const hasAlgoDt = Number(dtBalance) >= 1
|
const hasAlgoDt = Number(dtBalance) >= 1
|
||||||
setHasAlgoAssetDatatoken(hasAlgoDt)
|
setHasAlgoAssetDatatoken(hasAlgoDt)
|
||||||
return hasAlgoDt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setComputeFees(
|
async function setComputeFees(
|
||||||
@ -145,21 +142,22 @@ export default function Compute({
|
|||||||
const feeValidity = providerData?.datasets?.[0]?.providerFee?.validUntil
|
const feeValidity = providerData?.datasets?.[0]?.providerFee?.validUntil
|
||||||
|
|
||||||
const feeAmount = await unitsToAmount(
|
const feeAmount = await unitsToAmount(
|
||||||
!isSupportedOceanNetwork || !isAssetNetwork
|
// !isSupportedOceanNetwork || !isAssetNetwork
|
||||||
? await getDummyWeb3(asset?.chainId)
|
// ? await getDummyWeb3(asset?.chainId)
|
||||||
: web3,
|
// : web3,
|
||||||
|
signer,
|
||||||
providerFeeToken,
|
providerFeeToken,
|
||||||
providerFeeAmount
|
providerFeeAmount
|
||||||
)
|
)
|
||||||
setProviderFeeAmount(feeAmount)
|
setProviderFeeAmount(feeAmount)
|
||||||
|
|
||||||
const datatoken = new Datatoken(
|
const datatoken = new Datatoken(signer)
|
||||||
await getDummyWeb3(asset?.chainId),
|
// const datatoken = new Datatoken(
|
||||||
null,
|
// await getDummyWeb3(asset?.chainId),
|
||||||
null,
|
// null,
|
||||||
minAbi
|
// null,
|
||||||
)
|
// minAbi
|
||||||
|
// )
|
||||||
setProviderFeesSymbol(await datatoken.getSymbol(providerFeeToken))
|
setProviderFeesSymbol(await datatoken.getSymbol(providerFeeToken))
|
||||||
|
|
||||||
const computeDuration = asset.accessDetails.validProviderFees
|
const computeDuration = asset.accessDetails.validProviderFees
|
||||||
@ -179,6 +177,7 @@ export default function Compute({
|
|||||||
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
|
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
|
||||||
selectedAlgorithmAsset,
|
selectedAlgorithmAsset,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
|
signer,
|
||||||
algoProviderFees
|
algoProviderFees
|
||||||
)
|
)
|
||||||
if (!algorithmOrderPriceAndFees)
|
if (!algorithmOrderPriceAndFees)
|
||||||
@ -197,6 +196,7 @@ export default function Compute({
|
|||||||
const datasetPriceAndFees = await getOrderPriceAndFees(
|
const datasetPriceAndFees = await getOrderPriceAndFees(
|
||||||
asset,
|
asset,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
|
signer,
|
||||||
datasetProviderFees
|
datasetProviderFees
|
||||||
)
|
)
|
||||||
if (!datasetPriceAndFees)
|
if (!datasetPriceAndFees)
|
||||||
@ -373,11 +373,12 @@ export default function Compute({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const algorithmOrderTx = await handleComputeOrder(
|
const algorithmOrderTx = await handleComputeOrder(
|
||||||
web3,
|
signer,
|
||||||
selectedAlgorithmAsset,
|
selectedAlgorithmAsset,
|
||||||
algoOrderPriceAndFees,
|
algoOrderPriceAndFees,
|
||||||
accountId,
|
accountId,
|
||||||
initializedProviderResponse.algorithm,
|
initializedProviderResponse.algorithm,
|
||||||
|
hasAlgoAssetDatatoken,
|
||||||
computeEnv.consumerAddress
|
computeEnv.consumerAddress
|
||||||
)
|
)
|
||||||
if (!algorithmOrderTx) throw new Error('Failed to order algorithm.')
|
if (!algorithmOrderTx) throw new Error('Failed to order algorithm.')
|
||||||
@ -391,11 +392,12 @@ export default function Compute({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const datasetOrderTx = await handleComputeOrder(
|
const datasetOrderTx = await handleComputeOrder(
|
||||||
web3,
|
signer,
|
||||||
asset,
|
asset,
|
||||||
datasetOrderPriceAndFees,
|
datasetOrderPriceAndFees,
|
||||||
accountId,
|
accountId,
|
||||||
initializedProviderResponse.datasets[0],
|
initializedProviderResponse.datasets[0],
|
||||||
|
hasDatatoken,
|
||||||
computeEnv.consumerAddress
|
computeEnv.consumerAddress
|
||||||
)
|
)
|
||||||
if (!datasetOrderTx) throw new Error('Failed to order dataset.')
|
if (!datasetOrderTx) throw new Error('Failed to order dataset.')
|
||||||
@ -414,8 +416,7 @@ export default function Compute({
|
|||||||
setComputeStatusText(getComputeFeedback()[4])
|
setComputeStatusText(getComputeFeedback()[4])
|
||||||
const response = await ProviderInstance.computeStart(
|
const response = await ProviderInstance.computeStart(
|
||||||
asset.services[0].serviceEndpoint,
|
asset.services[0].serviceEndpoint,
|
||||||
web3,
|
signer,
|
||||||
accountId,
|
|
||||||
computeEnv?.id,
|
computeEnv?.id,
|
||||||
computeAsset,
|
computeAsset,
|
||||||
computeAlgorithm,
|
computeAlgorithm,
|
||||||
|
@ -2,7 +2,6 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
|||||||
import FileIcon from '@shared/FileIcon'
|
import FileIcon from '@shared/FileIcon'
|
||||||
import Price from '@shared/Price'
|
import Price from '@shared/Price'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import ButtonBuy from './ButtonBuy'
|
import ButtonBuy from './ButtonBuy'
|
||||||
import { secondsToString } from '@utils/ddo'
|
import { secondsToString } from '@utils/ddo'
|
||||||
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
||||||
@ -17,6 +16,8 @@ import { useIsMounted } from '@hooks/useIsMounted'
|
|||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
import Alert from '@shared/atoms/Alert'
|
import Alert from '@shared/atoms/Alert'
|
||||||
import Loader from '@shared/atoms/Loader'
|
import Loader from '@shared/atoms/Loader'
|
||||||
|
import { useAccount, useSigner } from 'wagmi'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
export default function Download({
|
export default function Download({
|
||||||
asset,
|
asset,
|
||||||
@ -33,7 +34,9 @@ export default function Download({
|
|||||||
fileIsLoading?: boolean
|
fileIsLoading?: boolean
|
||||||
consumableFeedback?: string
|
consumableFeedback?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, web3, isSupportedOceanNetwork } = useWeb3()
|
const { address: accountId, isConnected } = useAccount()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
|
const { isSupportedOceanNetwork } = useNetworkMetadata()
|
||||||
const { getOpcFeeForToken } = useMarketMetadata()
|
const { getOpcFeeForToken } = useMarketMetadata()
|
||||||
const { isInPurgatory, isAssetNetwork } = useAsset()
|
const { isInPurgatory, isAssetNetwork } = useAsset()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
@ -72,16 +75,24 @@ export default function Download({
|
|||||||
async function init() {
|
async function init() {
|
||||||
if (
|
if (
|
||||||
asset.accessDetails.addressOrId === ZERO_ADDRESS ||
|
asset.accessDetails.addressOrId === ZERO_ADDRESS ||
|
||||||
asset.accessDetails.type === 'free' ||
|
asset.accessDetails.type === 'free'
|
||||||
isLoading
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
!orderPriceAndFees && setIsPriceLoading(true)
|
try {
|
||||||
|
!orderPriceAndFees && setIsPriceLoading(true)
|
||||||
|
|
||||||
const _orderPriceAndFees = await getOrderPriceAndFees(asset, ZERO_ADDRESS)
|
const _orderPriceAndFees = await getOrderPriceAndFees(
|
||||||
setOrderPriceAndFees(_orderPriceAndFees)
|
asset,
|
||||||
!orderPriceAndFees && setIsPriceLoading(false)
|
ZERO_ADDRESS,
|
||||||
|
signer
|
||||||
|
)
|
||||||
|
setOrderPriceAndFees(_orderPriceAndFees)
|
||||||
|
!orderPriceAndFees && setIsPriceLoading(false)
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error('getOrderPriceAndFees', error)
|
||||||
|
setIsPriceLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@ -92,7 +103,7 @@ export default function Download({
|
|||||||
* Not adding isLoading and getOpcFeeForToken because we set these here. It is a compromise
|
* Not adding isLoading and getOpcFeeForToken because we set these here. It is a compromise
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [asset, accountId, getOpcFeeForToken, isUnsupportedPricing])
|
}, [asset, getOpcFeeForToken, isUnsupportedPricing])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setHasDatatoken(Number(dtBalance) >= 1)
|
setHasDatatoken(Number(dtBalance) >= 1)
|
||||||
@ -144,7 +155,7 @@ export default function Download({
|
|||||||
)[3]
|
)[3]
|
||||||
)
|
)
|
||||||
|
|
||||||
await downloadFile(web3, asset, accountId, validOrderTx)
|
await downloadFile(signer, asset, accountId, validOrderTx)
|
||||||
} else {
|
} else {
|
||||||
setStatusText(
|
setStatusText(
|
||||||
getOrderFeedback(
|
getOrderFeedback(
|
||||||
@ -152,12 +163,19 @@ export default function Download({
|
|||||||
asset.accessDetails.datatoken?.symbol
|
asset.accessDetails.datatoken?.symbol
|
||||||
)[asset.accessDetails.type === 'fixed' ? 2 : 1]
|
)[asset.accessDetails.type === 'fixed' ? 2 : 1]
|
||||||
)
|
)
|
||||||
const orderTx = await order(web3, asset, orderPriceAndFees, accountId)
|
const orderTx = await order(
|
||||||
if (!orderTx) {
|
signer,
|
||||||
|
asset,
|
||||||
|
orderPriceAndFees,
|
||||||
|
accountId,
|
||||||
|
hasDatatoken
|
||||||
|
)
|
||||||
|
const tx = await orderTx.wait()
|
||||||
|
if (!tx) {
|
||||||
throw new Error()
|
throw new Error()
|
||||||
}
|
}
|
||||||
setIsOwned(true)
|
setIsOwned(true)
|
||||||
setValidOrderTx(orderTx.transactionHash)
|
setValidOrderTx(tx?.transactionHash)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerInstance.error(error)
|
LoggerInstance.error(error)
|
||||||
@ -190,6 +208,7 @@ export default function Download({
|
|||||||
consumableFeedback={consumableFeedback}
|
consumableFeedback={consumableFeedback}
|
||||||
retry={retry}
|
retry={retry}
|
||||||
isSupportedOceanNetwork={isSupportedOceanNetwork}
|
isSupportedOceanNetwork={isSupportedOceanNetwork}
|
||||||
|
isAccountConnected={isConnected}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import Download from './Download'
|
|||||||
import { FileInfo, LoggerInstance, Datatoken } from '@oceanprotocol/lib'
|
import { FileInfo, LoggerInstance, Datatoken } from '@oceanprotocol/lib'
|
||||||
import { compareAsBN } from '@utils/numbers'
|
import { compareAsBN } from '@utils/numbers'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import { getFileDidInfo, getFileInfo } from '@utils/provider'
|
import { getFileDidInfo, getFileInfo } from '@utils/provider'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
@ -13,15 +12,20 @@ import { useIsMounted } from '@hooks/useIsMounted'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { useFormikContext } from 'formik'
|
import { useFormikContext } from 'formik'
|
||||||
import { FormPublishData } from '@components/Publish/_types'
|
import { FormPublishData } from '@components/Publish/_types'
|
||||||
import { getTokenBalanceFromSymbol } from '@utils/web3'
|
import { getTokenBalanceFromSymbol } from '@utils/wallet'
|
||||||
import AssetStats from './AssetStats'
|
import AssetStats from './AssetStats'
|
||||||
|
import { useAccount, useProvider, useNetwork } from 'wagmi'
|
||||||
|
import useBalance from '@hooks/useBalance'
|
||||||
|
|
||||||
export default function AssetActions({
|
export default function AssetActions({
|
||||||
asset
|
asset
|
||||||
}: {
|
}: {
|
||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, balance, web3, chainId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { balance } = useBalance()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
const web3Provider = useProvider()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
@ -72,7 +76,7 @@ export default function AssetActions({
|
|||||||
query,
|
query,
|
||||||
headers,
|
headers,
|
||||||
abi,
|
abi,
|
||||||
chainId,
|
chain?.id,
|
||||||
method
|
method
|
||||||
)
|
)
|
||||||
: await getFileDidInfo(asset?.id, asset?.services[0]?.id, providerUrl)
|
: await getFileDidInfo(asset?.id, asset?.services[0]?.id, providerUrl)
|
||||||
@ -100,11 +104,11 @@ export default function AssetActions({
|
|||||||
|
|
||||||
// Get and set user DT balance
|
// Get and set user DT balance
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!web3 || !accountId || !isAssetNetwork) return
|
if (!web3Provider || !accountId || !isAssetNetwork) return
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
try {
|
try {
|
||||||
const datatokenInstance = new Datatoken(web3)
|
const datatokenInstance = new Datatoken(web3Provider as any)
|
||||||
const dtBalance = await datatokenInstance.balance(
|
const dtBalance = await datatokenInstance.balance(
|
||||||
asset.services[0].datatokenAddress,
|
asset.services[0].datatokenAddress,
|
||||||
accountId
|
accountId
|
||||||
@ -115,7 +119,7 @@ export default function AssetActions({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
}, [web3, accountId, asset, isAssetNetwork])
|
}, [web3Provider, accountId, asset, isAssetNetwork])
|
||||||
|
|
||||||
// Check user balance against price
|
// Check user balance against price
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -3,28 +3,35 @@ import MetaItem from './MetaItem'
|
|||||||
import styles from './MetaFull.module.css'
|
import styles from './MetaFull.module.css'
|
||||||
import Publisher from '@shared/Publisher'
|
import Publisher from '@shared/Publisher'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { getDummyWeb3 } from '@utils/web3'
|
import { Asset, LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import { Asset, Datatoken, LoggerInstance } from '@oceanprotocol/lib'
|
import { getPaymentCollector } from '@utils/ocean'
|
||||||
|
import { useProvider } from 'wagmi'
|
||||||
|
|
||||||
export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement {
|
export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement {
|
||||||
const [paymentCollector, setPaymentCollector] = useState<string>()
|
|
||||||
const { isInPurgatory, assetState } = useAsset()
|
const { isInPurgatory, assetState } = useAsset()
|
||||||
|
const provider = useProvider()
|
||||||
|
|
||||||
|
const [paymentCollector, setPaymentCollector] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!ddo || !provider) return
|
||||||
|
|
||||||
async function getInitialPaymentCollector() {
|
async function getInitialPaymentCollector() {
|
||||||
try {
|
try {
|
||||||
if (!ddo) return
|
const paymentCollector = await getPaymentCollector(
|
||||||
const web3 = await getDummyWeb3(ddo.chainId)
|
ddo.datatokens[0].address,
|
||||||
const datatoken = new Datatoken(web3)
|
provider
|
||||||
setPaymentCollector(
|
|
||||||
await datatoken.getPaymentCollector(ddo.datatokens[0].address)
|
|
||||||
)
|
)
|
||||||
|
setPaymentCollector(paymentCollector)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerInstance.error('[MetaFull: getInitialPaymentCollector]', error)
|
LoggerInstance.error(
|
||||||
|
'[MetaFull: getInitialPaymentCollector]',
|
||||||
|
error.message
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInitialPaymentCollector()
|
getInitialPaymentCollector()
|
||||||
}, [ddo])
|
}, [ddo, provider])
|
||||||
|
|
||||||
function DockerImage() {
|
function DockerImage() {
|
||||||
const containerInfo = ddo?.metadata?.algorithm?.container
|
const containerInfo = ddo?.metadata?.algorithm?.container
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
import AddToken from '@shared/AddToken'
|
import AddToken from '@shared/AddToken'
|
||||||
import ExplorerLink from '@shared/ExplorerLink'
|
import ExplorerLink from '@shared/ExplorerLink'
|
||||||
import Publisher from '@shared/Publisher'
|
import Publisher from '@shared/Publisher'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
import styles from './MetaAsset.module.css'
|
import styles from './MetaAsset.module.css'
|
||||||
|
|
||||||
export default function MetaAsset({
|
export default function MetaAsset({
|
||||||
@ -15,7 +15,7 @@ export default function MetaAsset({
|
|||||||
isBlockscoutExplorer: boolean
|
isBlockscoutExplorer: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const { web3ProviderInfo } = useWeb3()
|
const { connector: activeConnector } = useAccount()
|
||||||
|
|
||||||
const dataTokenSymbol = asset?.datatokens[0]?.symbol
|
const dataTokenSymbol = asset?.datatokens[0]?.symbol
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export default function MetaAsset({
|
|||||||
>
|
>
|
||||||
{`Accessed with ${dataTokenSymbol}`}
|
{`Accessed with ${dataTokenSymbol}`}
|
||||||
</ExplorerLink>
|
</ExplorerLink>
|
||||||
{web3ProviderInfo?.name === 'MetaMask' && isAssetNetwork && (
|
{activeConnector?.name === 'MetaMask' && isAssetNetwork && (
|
||||||
<span className={styles.addWrap}>
|
<span className={styles.addWrap}>
|
||||||
<AddToken
|
<AddToken
|
||||||
address={asset?.services[0].datatokenAddress}
|
address={asset?.services[0].datatokenAddress}
|
||||||
|
@ -5,7 +5,7 @@ import { NftMetadata } from '@utils/nft'
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import styles from './NftTooltip.module.css'
|
import styles from './NftTooltip.module.css'
|
||||||
import explorerLinkStyles from '@shared/ExplorerLink/index.module.css'
|
import explorerLinkStyles from '@shared/ExplorerLink/index.module.css'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
|
|
||||||
// Supported OpenSea networks:
|
// Supported OpenSea networks:
|
||||||
// https://support.opensea.io/hc/en-us/articles/4404027708051-Which-blockchains-does-OpenSea-support-
|
// https://support.opensea.io/hc/en-us/articles/4404027708051-Which-blockchains-does-OpenSea-support-
|
||||||
|
@ -13,12 +13,11 @@ import EditHistory from './EditHistory'
|
|||||||
import styles from './index.module.css'
|
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 Web3 from 'web3'
|
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import RelatedAssets from '../RelatedAssets'
|
import RelatedAssets from '../RelatedAssets'
|
||||||
import DmButton from '@shared/DirectMessages/DmButton'
|
import DmButton from '@shared/DirectMessages/DmButton'
|
||||||
import Web3Feedback from '@components/@shared/Web3Feedback'
|
import Web3Feedback from '@components/@shared/Web3Feedback'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function AssetContent({
|
export default function AssetContent({
|
||||||
asset
|
asset
|
||||||
@ -26,17 +25,17 @@ export default function AssetContent({
|
|||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isInPurgatory, purgatoryData, isOwner, isAssetNetwork } = useAsset()
|
const { isInPurgatory, purgatoryData, isOwner, isAssetNetwork } = useAsset()
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const [receipts, setReceipts] = useState([])
|
const [receipts, setReceipts] = useState([])
|
||||||
const [nftPublisher, setNftPublisher] = useState<string>()
|
const [nftPublisher, setNftPublisher] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNftPublisher(
|
if (!receipts.length) return
|
||||||
Web3.utils.toChecksumAddress(
|
|
||||||
receipts?.find((e) => e.type === 'METADATA_CREATED')?.nft?.owner
|
const publisher = receipts?.find((e) => e.type === 'METADATA_CREATED')?.nft
|
||||||
)
|
?.owner
|
||||||
)
|
setNftPublisher(publisher)
|
||||||
}, [receipts])
|
}, [receipts])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
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 FormEditComputeDataset from './FormEditComputeDataset'
|
import FormEditComputeDataset from './FormEditComputeDataset'
|
||||||
@ -24,6 +23,7 @@ import { useAsset } from '@context/Asset'
|
|||||||
import EditFeedback from './EditFeedback'
|
import EditFeedback from './EditFeedback'
|
||||||
import { setNftMetadata } from '@utils/nft'
|
import { setNftMetadata } from '@utils/nft'
|
||||||
import { ComputeEditForm } from './_types'
|
import { ComputeEditForm } from './_types'
|
||||||
|
import { useAccount, useSigner } from 'wagmi'
|
||||||
|
|
||||||
export default function EditComputeDataset({
|
export default function EditComputeDataset({
|
||||||
asset
|
asset
|
||||||
@ -31,8 +31,10 @@ export default function EditComputeDataset({
|
|||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { accountId, web3 } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
const { fetchAsset, isAssetNetwork } = 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 newAbortController = useAbortController()
|
||||||
@ -46,7 +48,7 @@ export default function EditComputeDataset({
|
|||||||
asset?.accessDetails?.isPurchasable
|
asset?.accessDetails?.isPurchasable
|
||||||
) {
|
) {
|
||||||
const tx = await setMinterToPublisher(
|
const tx = await setMinterToPublisher(
|
||||||
web3,
|
signer,
|
||||||
asset?.accessDetails?.datatoken?.address,
|
asset?.accessDetails?.datatoken?.address,
|
||||||
accountId,
|
accountId,
|
||||||
setError
|
setError
|
||||||
@ -84,7 +86,7 @@ export default function EditComputeDataset({
|
|||||||
const setMetadataTx = await setNftMetadata(
|
const setMetadataTx = await setNftMetadata(
|
||||||
updatedAsset,
|
updatedAsset,
|
||||||
accountId,
|
accountId,
|
||||||
web3,
|
signer,
|
||||||
newAbortController()
|
newAbortController()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ export default function EditComputeDataset({
|
|||||||
} else {
|
} else {
|
||||||
if (asset.accessDetails.type === 'free') {
|
if (asset.accessDetails.type === 'free') {
|
||||||
const tx = await setMinterToDispenser(
|
const tx = await setMinterToDispenser(
|
||||||
web3,
|
signer,
|
||||||
asset?.accessDetails?.datatoken?.address,
|
asset?.accessDetails?.datatoken?.address,
|
||||||
accountId,
|
accountId,
|
||||||
setError
|
setError
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
import { validationSchema } from './_validation'
|
import { validationSchema } from './_validation'
|
||||||
import { getInitialValues } from './_constants'
|
import { getInitialValues } from './_constants'
|
||||||
import { MetadataEditForm } from './_types'
|
import { MetadataEditForm } from './_types'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import FormEditMetadata from './FormEditMetadata'
|
import FormEditMetadata from './FormEditMetadata'
|
||||||
@ -21,13 +20,14 @@ import styles from './index.module.css'
|
|||||||
import content from '../../../../content/pages/editMetadata.json'
|
import content from '../../../../content/pages/editMetadata.json'
|
||||||
import { useAbortController } from '@hooks/useAbortController'
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
import DebugEditMetadata from './DebugEditMetadata'
|
import DebugEditMetadata from './DebugEditMetadata'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig, getPaymentCollector } from '@utils/ocean'
|
||||||
import EditFeedback from './EditFeedback'
|
import EditFeedback from './EditFeedback'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { setNftMetadata } from '@utils/nft'
|
import { setNftMetadata } from '@utils/nft'
|
||||||
import { sanitizeUrl } from '@utils/url'
|
import { sanitizeUrl } from '@utils/url'
|
||||||
import { getEncryptedFiles } from '@utils/provider'
|
import { getEncryptedFiles } from '@utils/provider'
|
||||||
import { assetStateToNumber } from '@utils/assetState'
|
import { assetStateToNumber } from '@utils/assetState'
|
||||||
|
import { useAccount, useProvider, useNetwork, useSigner } from 'wagmi'
|
||||||
|
|
||||||
export default function Edit({
|
export default function Edit({
|
||||||
asset
|
asset
|
||||||
@ -36,8 +36,12 @@ export default function Edit({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { fetchAsset, isAssetNetwork, assetState } = useAsset()
|
const { fetchAsset, isAssetNetwork, assetState } = useAsset()
|
||||||
const { accountId, web3, chainId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
const provider = useProvider()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
const newAbortController = useAbortController()
|
const newAbortController = useAbortController()
|
||||||
|
|
||||||
const [success, setSuccess] = useState<string>()
|
const [success, setSuccess] = useState<string>()
|
||||||
const [paymentCollector, setPaymentCollector] = useState<string>()
|
const [paymentCollector, setPaymentCollector] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
@ -45,12 +49,15 @@ export default function Edit({
|
|||||||
const hasFeedback = error || success
|
const hasFeedback = error || success
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!asset || !provider) return
|
||||||
|
|
||||||
async function getInitialPaymentCollector() {
|
async function getInitialPaymentCollector() {
|
||||||
try {
|
try {
|
||||||
const datatoken = new Datatoken(web3)
|
const paymentCollector = await getPaymentCollector(
|
||||||
setPaymentCollector(
|
asset.datatokens[0].address,
|
||||||
await datatoken.getPaymentCollector(asset?.datatokens[0].address)
|
provider
|
||||||
)
|
)
|
||||||
|
setPaymentCollector(paymentCollector)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerInstance.error(
|
LoggerInstance.error(
|
||||||
'[EditMetadata: getInitialPaymentCollector]',
|
'[EditMetadata: getInitialPaymentCollector]',
|
||||||
@ -59,18 +66,17 @@ export default function Edit({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInitialPaymentCollector()
|
getInitialPaymentCollector()
|
||||||
}, [asset, web3])
|
}, [asset, provider])
|
||||||
|
|
||||||
async function updateFixedPrice(newPrice: string) {
|
async function updateFixedPrice(newPrice: string) {
|
||||||
const config = getOceanConfig(asset.chainId)
|
const config = getOceanConfig(asset.chainId)
|
||||||
|
|
||||||
const fixedRateInstance = new FixedRateExchange(
|
const fixedRateInstance = new FixedRateExchange(
|
||||||
config.fixedRateExchangeAddress,
|
config.fixedRateExchangeAddress,
|
||||||
web3
|
signer
|
||||||
)
|
)
|
||||||
|
|
||||||
const setPriceResp = await fixedRateInstance.setRate(
|
const setPriceResp = await fixedRateInstance.setRate(
|
||||||
accountId,
|
|
||||||
asset.accessDetails.addressOrId,
|
asset.accessDetails.addressOrId,
|
||||||
newPrice.toString()
|
newPrice.toString()
|
||||||
)
|
)
|
||||||
@ -103,7 +109,7 @@ export default function Edit({
|
|||||||
(await updateFixedPrice(values.price))
|
(await updateFixedPrice(values.price))
|
||||||
|
|
||||||
if (values.paymentCollector !== paymentCollector) {
|
if (values.paymentCollector !== paymentCollector) {
|
||||||
const datatoken = new Datatoken(web3)
|
const datatoken = new Datatoken(signer)
|
||||||
await datatoken.setPaymentCollector(
|
await datatoken.setPaymentCollector(
|
||||||
asset?.datatokens[0].address,
|
asset?.datatokens[0].address,
|
||||||
accountId,
|
accountId,
|
||||||
@ -115,7 +121,9 @@ export default function Edit({
|
|||||||
const file = {
|
const file = {
|
||||||
nftAddress: asset.nftAddress,
|
nftAddress: asset.nftAddress,
|
||||||
datatokenAddress: asset.services[0].datatokenAddress,
|
datatokenAddress: asset.services[0].datatokenAddress,
|
||||||
files: [normalizeFile(values.files[0].type, values.files[0], chainId)]
|
files: [
|
||||||
|
normalizeFile(values.files[0].type, values.files[0], chain?.id)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesEncrypted = await getEncryptedFiles(
|
const filesEncrypted = await getEncryptedFiles(
|
||||||
@ -146,12 +154,12 @@ export default function Edit({
|
|||||||
const setMetadataTx = await setNftMetadata(
|
const setMetadataTx = await setNftMetadata(
|
||||||
updatedAsset,
|
updatedAsset,
|
||||||
accountId,
|
accountId,
|
||||||
web3,
|
signer,
|
||||||
newAbortController()
|
newAbortController()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (values.assetState !== assetState) {
|
if (values.assetState !== assetState) {
|
||||||
const nft = new Nft(web3)
|
const nft = new Nft(signer)
|
||||||
|
|
||||||
await nft.setMetadataState(
|
await nft.setMetadataState(
|
||||||
asset?.nftAddress,
|
asset?.nftAddress,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FileInfo } from '@oceanprotocol/lib'
|
import { FileInfo } from '@oceanprotocol/lib'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import web3 from 'web3'
|
import { isAddress } from 'ethers/lib/utils'
|
||||||
import { testLinks } from '../../../@utils/yup'
|
import { testLinks } from '../../../@utils/yup'
|
||||||
|
|
||||||
export const validationSchema = Yup.object().shape({
|
export const validationSchema = Yup.object().shape({
|
||||||
@ -41,7 +41,7 @@ export const validationSchema = Yup.object().shape({
|
|||||||
'ValidAddress',
|
'ValidAddress',
|
||||||
'Must be a valid Ethereum Address.',
|
'Must be a valid Ethereum Address.',
|
||||||
(value) => {
|
(value) => {
|
||||||
return web3.utils.isAddress(value)
|
return isAddress(value)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
retireAsset: Yup.string()
|
retireAsset: Yup.string()
|
||||||
|
@ -1,30 +1,38 @@
|
|||||||
import React, { FormEvent } from 'react'
|
import React, { FormEvent } from 'react'
|
||||||
import Caret from '@images/caret.svg'
|
import Caret from '@images/caret.svg'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import Loader from '@shared/atoms/Loader'
|
// import Loader from '@shared/atoms/Loader'
|
||||||
import styles from './Account.module.css'
|
import styles from './Account.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Avatar from '@shared/atoms/Avatar'
|
import Avatar from '@shared/atoms/Avatar'
|
||||||
|
import { useAccount, useEnsName, useEnsAvatar } from 'wagmi'
|
||||||
|
import { useModal } from 'connectkit'
|
||||||
|
|
||||||
// Forward ref for Tippy.js
|
// Forward ref for Tippy.js
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const Account = React.forwardRef((props, ref: any) => {
|
const Account = React.forwardRef((props, ref: any) => {
|
||||||
const { accountId, accountEns, accountEnsAvatar, web3Modal, connect } =
|
const { address: accountId } = useAccount()
|
||||||
useWeb3()
|
const { data: accountEns } = useEnsName({ address: accountId, chainId: 1 })
|
||||||
|
const { data: accountEnsAvatar } = useEnsAvatar({
|
||||||
|
address: accountId,
|
||||||
|
chainId: 1
|
||||||
|
})
|
||||||
|
const { setOpen } = useModal()
|
||||||
|
|
||||||
async function handleActivation(e: FormEvent<HTMLButtonElement>) {
|
async function handleActivation(e: FormEvent<HTMLButtonElement>) {
|
||||||
// prevent accidentially submitting a form the button might be in
|
// prevent accidentially submitting a form the button might be in
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
await connect()
|
setOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return !accountId && web3Modal?.cachedProvider ? (
|
// return
|
||||||
// Improve user experience for cached provider when connecting takes some time
|
// !accountId && provider ? (
|
||||||
<button className={styles.button} onClick={(e) => e.preventDefault()}>
|
// // Improve user experience for cached provider when connecting takes some time
|
||||||
<Loader />
|
// <button className={styles.button} onClick={(e) => e.preventDefault()}>
|
||||||
</button>
|
// <Loader />
|
||||||
) : accountId ? (
|
// </button>
|
||||||
|
// ) :
|
||||||
|
return accountId ? (
|
||||||
<button
|
<button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
aria-label="Account"
|
aria-label="Account"
|
||||||
|
@ -4,24 +4,24 @@ import { useUserPreferences } from '@context/UserPreferences'
|
|||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import AddToken from '@shared/AddToken'
|
import AddToken from '@shared/AddToken'
|
||||||
import Conversion from '@shared/Price/Conversion'
|
import Conversion from '@shared/Price/Conversion'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useOrbis } from '@context/DirectMessages'
|
import { useOrbis } from '@context/DirectMessages'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import { useNetwork, useDisconnect, useAccount, useConnect } from 'wagmi'
|
||||||
|
import { useModal } from 'connectkit'
|
||||||
import styles from './Details.module.css'
|
import styles from './Details.module.css'
|
||||||
|
import useBalance from '@hooks/useBalance'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
export default function Details(): ReactElement {
|
export default function Details(): ReactElement {
|
||||||
const {
|
const { chain } = useNetwork()
|
||||||
accountId,
|
const { connector: activeConnector, address: accountId } = useAccount()
|
||||||
web3ProviderInfo,
|
const { connect } = useConnect()
|
||||||
web3Modal,
|
const { setOpen } = useModal()
|
||||||
connect,
|
const { disconnect } = useDisconnect()
|
||||||
logout,
|
const { balance } = useBalance()
|
||||||
networkData,
|
const { networkData } = useNetworkMetadata()
|
||||||
networkId,
|
|
||||||
balance
|
|
||||||
} = useWeb3()
|
|
||||||
const { checkOrbisConnection, disconnectOrbis } = useOrbis()
|
|
||||||
const { locale } = useUserPreferences()
|
const { locale } = useUserPreferences()
|
||||||
|
const { checkOrbisConnection, disconnectOrbis } = useOrbis()
|
||||||
|
|
||||||
const [mainCurrency, setMainCurrency] = useState<string>()
|
const [mainCurrency, setMainCurrency] = useState<string>()
|
||||||
const [oceanTokenMetadata, setOceanTokenMetadata] = useState<{
|
const [oceanTokenMetadata, setOceanTokenMetadata] = useState<{
|
||||||
@ -30,19 +30,19 @@ export default function Details(): ReactElement {
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!networkId) return
|
if (!chain?.id) return
|
||||||
|
|
||||||
const symbol = networkData?.nativeCurrency.symbol
|
const symbol = networkData?.nativeCurrency.symbol
|
||||||
setMainCurrency(symbol)
|
setMainCurrency(symbol)
|
||||||
|
|
||||||
const oceanConfig = getOceanConfig(networkId)
|
const oceanConfig = getOceanConfig(chain.id)
|
||||||
|
|
||||||
oceanConfig &&
|
oceanConfig &&
|
||||||
setOceanTokenMetadata({
|
setOceanTokenMetadata({
|
||||||
address: oceanConfig.oceanTokenAddress,
|
address: oceanConfig.oceanTokenAddress,
|
||||||
symbol: oceanConfig.oceanTokenSymbol
|
symbol: oceanConfig.oceanTokenSymbol
|
||||||
})
|
})
|
||||||
}, [networkData, networkId])
|
}, [networkData, chain?.id])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.details}>
|
<div className={styles.details}>
|
||||||
@ -68,10 +68,10 @@ export default function Details(): ReactElement {
|
|||||||
<li className={styles.actions}>
|
<li className={styles.actions}>
|
||||||
<div title="Connected provider" className={styles.walletInfo}>
|
<div title="Connected provider" className={styles.walletInfo}>
|
||||||
<span className={styles.walletLogoWrap}>
|
<span className={styles.walletLogoWrap}>
|
||||||
<img className={styles.walletLogo} src={web3ProviderInfo?.logo} />
|
{/* <img className={styles.walletLogo} src={activeConnector?.logo} /> */}
|
||||||
{web3ProviderInfo?.name}
|
{activeConnector?.name}
|
||||||
</span>
|
</span>
|
||||||
{web3ProviderInfo?.name === 'MetaMask' && (
|
{activeConnector?.name === 'MetaMask' && (
|
||||||
<AddToken
|
<AddToken
|
||||||
address={oceanTokenMetadata?.address}
|
address={oceanTokenMetadata?.address}
|
||||||
symbol={oceanTokenMetadata?.symbol}
|
symbol={oceanTokenMetadata?.symbol}
|
||||||
@ -84,7 +84,6 @@ export default function Details(): ReactElement {
|
|||||||
style="text"
|
style="text"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await web3Modal?.clearCachedProvider()
|
|
||||||
connect()
|
connect()
|
||||||
checkOrbisConnection({ address: accountId })
|
checkOrbisConnection({ address: accountId })
|
||||||
}}
|
}}
|
||||||
@ -95,7 +94,7 @@ export default function Details(): ReactElement {
|
|||||||
style="text"
|
style="text"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
logout()
|
disconnect()
|
||||||
disconnectOrbis(accountId)
|
disconnectOrbis(accountId)
|
||||||
location.reload()
|
location.reload()
|
||||||
}}
|
}}
|
||||||
|
@ -2,21 +2,23 @@ import React, { ReactElement } from 'react'
|
|||||||
import Status from '@shared/atoms/Status'
|
import Status from '@shared/atoms/Status'
|
||||||
import Badge from '@shared/atoms/Badge'
|
import Badge from '@shared/atoms/Badge'
|
||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import NetworkName from '@shared/NetworkName'
|
import NetworkName from '@shared/NetworkName'
|
||||||
import styles from './Network.module.css'
|
import styles from './Network.module.css'
|
||||||
|
import { useNetwork } from 'wagmi'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
export default function Network(): ReactElement {
|
export default function Network(): ReactElement {
|
||||||
const { networkId, isTestnet, isSupportedOceanNetwork } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
|
const { isTestnet, isSupportedOceanNetwork } = useNetworkMetadata()
|
||||||
|
|
||||||
return networkId ? (
|
return chain?.id ? (
|
||||||
<div className={styles.network}>
|
<div className={styles.network}>
|
||||||
{!isSupportedOceanNetwork && (
|
{!isSupportedOceanNetwork && (
|
||||||
<Tooltip content="No Ocean Protocol contracts are deployed to this network.">
|
<Tooltip content="No Ocean Protocol contracts are deployed to this network.">
|
||||||
<Status state="error" className={styles.warning} />
|
<Status state="error" className={styles.warning} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<NetworkName className={styles.name} networkId={networkId} minimal />
|
<NetworkName className={styles.name} networkId={chain.id} minimal />
|
||||||
{isTestnet && <Badge label="Test" className={styles.badge} />}
|
{isTestnet && <Badge label="Test" className={styles.badge} />}
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
|
@ -4,10 +4,10 @@ import Details from './Details'
|
|||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import Network from './Network'
|
import Network from './Network'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function Wallet(): ReactElement {
|
export default function Wallet(): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wallet}>
|
<div className={styles.wallet}>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { AssetWithOwnAllocation, getOwnAllocations } from '@utils/veAllocation'
|
import { AssetWithOwnAllocation, getOwnAllocations } from '@utils/veAllocation'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import {
|
import {
|
||||||
@ -12,9 +11,10 @@ import { useCancelToken } from '@hooks/useCancelToken'
|
|||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import AssetListTable from './AssetListTable'
|
import AssetListTable from './AssetListTable'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function Allocations(): ReactElement {
|
export default function Allocations(): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
|
@ -7,8 +7,8 @@ import Tooltip from '@shared/atoms/Tooltip'
|
|||||||
import AssetTitle from '@shared/AssetListTitle'
|
import AssetTitle from '@shared/AssetListTitle'
|
||||||
import { getAssetsFromDids } from '@utils/aquarius'
|
import { getAssetsFromDids } from '@utils/aquarius'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
const columns: TableOceanColumn<AssetExtended>[] = [
|
const columns: TableOceanColumn<AssetExtended>[] = [
|
||||||
{
|
{
|
||||||
@ -38,7 +38,7 @@ const columns: TableOceanColumn<AssetExtended>[] = [
|
|||||||
|
|
||||||
export default function Bookmarks(): ReactElement {
|
export default function Bookmarks(): ReactElement {
|
||||||
const { appConfig } = useMarketMetadata()
|
const { appConfig } = useMarketMetadata()
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { bookmarks } = useUserPreferences()
|
const { bookmarks } = useUserPreferences()
|
||||||
|
|
||||||
const [pinned, setPinned] = useState<AssetExtended[]>()
|
const [pinned, setPinned] = useState<AssetExtended[]>()
|
||||||
|
@ -2,7 +2,7 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
|||||||
import Dotdotdot from 'react-dotdotdot'
|
import Dotdotdot from 'react-dotdotdot'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import Avatar from '../../../@shared/atoms/Avatar'
|
import Avatar from '../../../@shared/atoms/Avatar'
|
||||||
import { getEnsProfile } from '@utils/ens'
|
import { getEnsProfile } from '@utils/ens'
|
||||||
import { UserSales } from '@utils/aquarius'
|
import { UserSales } from '@utils/aquarius'
|
||||||
|
@ -7,7 +7,7 @@ import Copy from '@shared/atoms/Copy'
|
|||||||
import Avatar from '@shared/atoms/Avatar'
|
import Avatar from '@shared/atoms/Avatar'
|
||||||
import styles from './Account.module.css'
|
import styles from './Account.module.css'
|
||||||
import { useProfile } from '@context/Profile'
|
import { useProfile } from '@context/Profile'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
|
|
||||||
export default function Account({
|
export default function Account({
|
||||||
accountId
|
accountId
|
||||||
|
@ -8,14 +8,14 @@ import { useProfile } from '@context/Profile'
|
|||||||
import { getLocked } from '@utils/veAllocation'
|
import { getLocked } from '@utils/veAllocation'
|
||||||
import PriceUnit from '@shared/Price/PriceUnit'
|
import PriceUnit from '@shared/Price/PriceUnit'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function Stats({
|
export default function Stats({
|
||||||
accountId
|
accountId
|
||||||
}: {
|
}: {
|
||||||
accountId: string
|
accountId: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const web3 = useWeb3()
|
const { address } = useAccount()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const { assets, assetsTotal, sales } = useProfile()
|
const { assets, assetsTotal, sales } = useProfile()
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ export default function Stats({
|
|||||||
<NumberUnit label="Published" value={assetsTotal} />
|
<NumberUnit label="Published" value={assetsTotal} />
|
||||||
<NumberUnit
|
<NumberUnit
|
||||||
label={
|
label={
|
||||||
lockedOcean === 0 && accountId === web3.accountId ? (
|
lockedOcean === 0 && accountId === address ? (
|
||||||
<Button
|
<Button
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
style="text"
|
style="text"
|
||||||
|
@ -10,9 +10,9 @@ import Button from '@shared/atoms/Button'
|
|||||||
import styles from './Results.module.css'
|
import styles from './Results.module.css'
|
||||||
import FormHelp from '@shared/FormInput/Help'
|
import FormHelp from '@shared/FormInput/Help'
|
||||||
import content from '../../../../../content/pages/history.json'
|
import content from '../../../../../content/pages/history.json'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { getAsset } from '@utils/aquarius'
|
import { getAsset } from '@utils/aquarius'
|
||||||
|
import { useAccount, useSigner } from 'wagmi'
|
||||||
|
|
||||||
export default function Results({
|
export default function Results({
|
||||||
job
|
job
|
||||||
@ -20,12 +20,14 @@ export default function Results({
|
|||||||
job: ComputeJobMetaData
|
job: ComputeJobMetaData
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const providerInstance = new Provider()
|
const providerInstance = new Provider()
|
||||||
const { accountId, web3 } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const isFinished = job.dateFinished !== null
|
const { data: signer } = useSigner()
|
||||||
|
|
||||||
const [datasetProvider, setDatasetProvider] = useState<string>()
|
const [datasetProvider, setDatasetProvider] = useState<string>()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
|
|
||||||
|
const isFinished = job.dateFinished !== null
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getAssetMetadata() {
|
async function getAssetMetadata() {
|
||||||
const ddo = await getAsset(job.inputDID[0], newCancelToken())
|
const ddo = await getAsset(job.inputDID[0], newCancelToken())
|
||||||
@ -62,8 +64,7 @@ export default function Results({
|
|||||||
try {
|
try {
|
||||||
const jobResult = await providerInstance.getComputeResultUrl(
|
const jobResult = await providerInstance.getComputeResultUrl(
|
||||||
datasetProvider,
|
datasetProvider,
|
||||||
web3,
|
signer,
|
||||||
accountId,
|
|
||||||
job.jobId,
|
job.jobId,
|
||||||
resultIndex
|
resultIndex
|
||||||
)
|
)
|
||||||
|
@ -2,13 +2,13 @@ import React, { ReactElement, useState } from 'react'
|
|||||||
import Time from '@shared/atoms/Time'
|
import Time from '@shared/atoms/Time'
|
||||||
import Table, { TableOceanColumn } from '@shared/atoms/Table'
|
import Table, { TableOceanColumn } from '@shared/atoms/Table'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Details from './Details'
|
import Details from './Details'
|
||||||
import Refresh from '@images/refresh.svg'
|
import Refresh from '@images/refresh.svg'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import NetworkName from '@shared/NetworkName'
|
import NetworkName from '@shared/NetworkName'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import AssetListTitle from '@shared/AssetListTitle'
|
import AssetListTitle from '@shared/AssetListTitle'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export function Status({ children }: { children: string }): ReactElement {
|
export function Status({ children }: { children: string }): ReactElement {
|
||||||
return <div className={styles.status}>{children}</div>
|
return <div className={styles.status}>{children}</div>
|
||||||
@ -55,7 +55,7 @@ export default function ComputeJobs({
|
|||||||
isLoading?: boolean
|
isLoading?: boolean
|
||||||
refetchJobs?: any
|
refetchJobs?: any
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const [columnsMinimal] = useState([columns[4], columns[5], columns[3]])
|
const [columnsMinimal] = useState([columns[4], columns[5], columns[3]])
|
||||||
|
|
||||||
@ -84,6 +84,6 @@ export default function ComputeJobs({
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div>Please connect your Web3 wallet.</div>
|
<div>Please connect your wallet.</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,6 @@ export default function ComputeDownloads({
|
|||||||
emptyMessage={chainIds.length === 0 ? 'No network selected' : null}
|
emptyMessage={chainIds.length === 0 ? 'No network selected' : null}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div>Please connect your Web3 wallet.</div>
|
<div>Please connect your wallet.</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,6 @@ export default function PublishedList({
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div>Please connect your Web3 wallet.</div>
|
<div>Please connect your wallet.</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ import PublishedList from './PublishedList'
|
|||||||
import Downloads from './Downloads'
|
import Downloads from './Downloads'
|
||||||
import ComputeJobs from './ComputeJobs'
|
import ComputeJobs from './ComputeJobs'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { getComputeJobs } from '@utils/compute'
|
import { getComputeJobs } from '@utils/compute'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
interface HistoryTab {
|
interface HistoryTab {
|
||||||
title: string
|
title: string
|
||||||
@ -56,7 +56,7 @@ export default function HistoryPage({
|
|||||||
}: {
|
}: {
|
||||||
accountIdentifier: string
|
accountIdentifier: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ import { FormikContextType, useFormikContext } from 'formik'
|
|||||||
import { FormPublishData } from '../_types'
|
import { FormPublishData } from '../_types'
|
||||||
import { wizardSteps } from '../_constants'
|
import { wizardSteps } from '../_constants'
|
||||||
import SuccessConfetti from '@shared/SuccessConfetti'
|
import SuccessConfetti from '@shared/SuccessConfetti'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import AvailableNetworks from '@components/Publish/AvailableNetworks'
|
import AvailableNetworks from '@components/Publish/AvailableNetworks'
|
||||||
import Info from '@images/info.svg'
|
import Info from '@images/info.svg'
|
||||||
import Loader from '@shared/atoms/Loader'
|
import Loader from '@shared/atoms/Loader'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
|
||||||
export default function Actions({
|
export default function Actions({
|
||||||
scrollToRef,
|
scrollToRef,
|
||||||
@ -20,21 +20,19 @@ export default function Actions({
|
|||||||
did: string
|
did: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { isSupportedOceanNetwork } = useWeb3()
|
const { isSupportedOceanNetwork } = useNetworkMetadata()
|
||||||
const {
|
const {
|
||||||
values,
|
values,
|
||||||
errors,
|
errors,
|
||||||
isValid,
|
isValid,
|
||||||
isSubmitting
|
isSubmitting
|
||||||
}: FormikContextType<FormPublishData> = useFormikContext()
|
}: FormikContextType<FormPublishData> = useFormikContext()
|
||||||
const { connect, accountId } = useWeb3()
|
// async function handleActivation(e: FormEvent<HTMLButtonElement>) {
|
||||||
|
// // prevent accidentially submitting a form the button might be in
|
||||||
|
// e.preventDefault()
|
||||||
|
|
||||||
async function handleActivation(e: FormEvent<HTMLButtonElement>) {
|
// await connect()
|
||||||
// prevent accidentially submitting a form the button might be in
|
// }
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
await connect()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAction(action: string) {
|
function handleAction(action: string) {
|
||||||
const currentStep: string = router.query.step as string
|
const currentStep: string = router.query.step as string
|
||||||
@ -92,11 +90,12 @@ export default function Actions({
|
|||||||
>
|
>
|
||||||
Continue
|
Continue
|
||||||
</Button>
|
</Button>
|
||||||
) : !accountId ? (
|
) : // !address ? (
|
||||||
<Button type="submit" style="primary" onClick={handleActivation}>
|
// <Button type="submit" style="primary" onClick={handleActivation}>
|
||||||
Connect Wallet
|
// Connect Wallet
|
||||||
</Button>
|
// </Button>
|
||||||
) : !isSupportedOceanNetwork ? (
|
// ) :
|
||||||
|
!isSupportedOceanNetwork ? (
|
||||||
<Tooltip content={<AvailableNetworks />}>
|
<Tooltip content={<AvailableNetworks />}>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -3,8 +3,7 @@ import NetworkName from '@shared/NetworkName'
|
|||||||
import styles from './Network.module.css'
|
import styles from './Network.module.css'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
import { addCustomNetwork } from '@utils/web3'
|
// TODO: import { addCustomNetwork } from '@utils/wallet'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
|
|
||||||
export default function Network({
|
export default function Network({
|
||||||
chainId
|
chainId
|
||||||
@ -12,11 +11,10 @@ export default function Network({
|
|||||||
chainId: number
|
chainId: number
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { networksList } = useNetworkMetadata()
|
const { networksList } = useNetworkMetadata()
|
||||||
const { web3Provider } = useWeb3()
|
|
||||||
|
|
||||||
function changeNetwork(chainId: number) {
|
function changeNetwork(chainId: number) {
|
||||||
const networkNode = networksList.find((data) => data.chainId === chainId)
|
const networkNode = networksList.find((data) => data.chainId === chainId)
|
||||||
addCustomNetwork(web3Provider, networkNode)
|
// addCustomNetwork(networkNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -6,18 +6,18 @@ import { transformPublishFormToDdo } from '../_utils'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { DDO } from '@oceanprotocol/lib'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
import { previewDebugPatch } from '@utils/ddo'
|
import { previewDebugPatch } from '@utils/ddo'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useNetwork } from 'wagmi'
|
||||||
|
|
||||||
export default function Debug(): ReactElement {
|
export default function Debug(): ReactElement {
|
||||||
const { values } = useFormikContext<FormPublishData>()
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
const [valuePreview, setValuePreview] = useState({})
|
const [valuePreview, setValuePreview] = useState({})
|
||||||
const [ddo, setDdo] = useState<DDO>()
|
const [ddo, setDdo] = useState<DDO>()
|
||||||
const { chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function makeDdo() {
|
async function makeDdo() {
|
||||||
const ddo = await transformPublishFormToDdo(values)
|
const ddo = await transformPublishFormToDdo(values)
|
||||||
setValuePreview(previewDebugPatch(values, chainId))
|
setValuePreview(previewDebugPatch(values, chain?.id))
|
||||||
setDdo(ddo)
|
setDdo(ddo)
|
||||||
}
|
}
|
||||||
makeDdo()
|
makeDdo()
|
||||||
|
@ -4,9 +4,9 @@ import styles from './Fees.module.css'
|
|||||||
import Input from '@shared/FormInput'
|
import Input from '@shared/FormInput'
|
||||||
import { getOpcFees } from '@utils/subgraph'
|
import { getOpcFees } from '@utils/subgraph'
|
||||||
import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery'
|
import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
|
import { useNetwork } from 'wagmi'
|
||||||
|
|
||||||
const Default = ({
|
const Default = ({
|
||||||
title,
|
title,
|
||||||
@ -40,18 +40,18 @@ export default function Fees({
|
|||||||
tooltips: { [key: string]: string }
|
tooltips: { [key: string]: string }
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [oceanCommunitySwapFee, setOceanCommunitySwapFee] = useState<string>('')
|
const [oceanCommunitySwapFee, setOceanCommunitySwapFee] = useState<string>('')
|
||||||
const { chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
const { appConfig } = useMarketMetadata()
|
const { appConfig } = useMarketMetadata()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getOpcFees(chainId || 1).then((response: OpcFeesData) => {
|
getOpcFees(chain?.id || 1).then((response: OpcFeesData) => {
|
||||||
setOceanCommunitySwapFee(
|
setOceanCommunitySwapFee(
|
||||||
response?.swapOceanFee
|
response?.swapOceanFee
|
||||||
? new Decimal(response.swapOceanFee).mul(100).toString()
|
? new Decimal(response.swapOceanFee).mul(100).toString()
|
||||||
: '0'
|
: '0'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}, [chainId])
|
}, [chain?.id])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -7,11 +7,13 @@ import Free from './Free'
|
|||||||
import content from '../../../../content/price.json'
|
import content from '../../../../content/price.json'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useNetwork } from 'wagmi'
|
||||||
|
|
||||||
export default function PricingFields(): ReactElement {
|
export default function PricingFields(): ReactElement {
|
||||||
const { appConfig } = useMarketMetadata()
|
const { appConfig } = useMarketMetadata()
|
||||||
const { approvedBaseTokens, chainId } = useWeb3()
|
const { chain } = useNetwork()
|
||||||
|
const { approvedBaseTokens } = useMarketMetadata()
|
||||||
|
|
||||||
// Connect with main publish form
|
// Connect with main publish form
|
||||||
const { values, setFieldValue } = useFormikContext<FormPublishData>()
|
const { values, setFieldValue } = useFormikContext<FormPublishData>()
|
||||||
const { pricing } = values
|
const { pricing } = values
|
||||||
@ -22,6 +24,23 @@ export default function PricingFields(): ReactElement {
|
|||||||
token.name.toLowerCase().includes('ocean')
|
token.name.toLowerCase().includes('ocean')
|
||||||
) || approvedBaseTokens?.[0]
|
) || approvedBaseTokens?.[0]
|
||||||
|
|
||||||
|
const isBaseTokenSet = !!approvedBaseTokens?.find(
|
||||||
|
(token) => token?.address === values?.pricing?.baseToken?.address
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!approvedBaseTokens?.length) return
|
||||||
|
if (isBaseTokenSet) return
|
||||||
|
setFieldValue('pricing.baseToken', defaultBaseToken)
|
||||||
|
}, [
|
||||||
|
approvedBaseTokens,
|
||||||
|
chain?.id,
|
||||||
|
defaultBaseToken,
|
||||||
|
isBaseTokenSet,
|
||||||
|
setFieldValue,
|
||||||
|
values.pricing.baseToken
|
||||||
|
])
|
||||||
|
|
||||||
// Switch type value upon tab change
|
// Switch type value upon tab change
|
||||||
function handleTabChange(tabName: string) {
|
function handleTabChange(tabName: string) {
|
||||||
const type = tabName.toLowerCase()
|
const type = tabName.toLowerCase()
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
import { ReactElement, useEffect } from 'react'
|
import { ReactElement, useEffect } from 'react'
|
||||||
import { useFormikContext } from 'formik'
|
import { useFormikContext } from 'formik'
|
||||||
import { wizardSteps, initialPublishFeedback } from './_constants'
|
import { wizardSteps, initialPublishFeedback } from './_constants'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { FormPublishData, PublishFeedback } from './_types'
|
import { FormPublishData, PublishFeedback } from './_types'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
import { useAccount, useNetwork } from 'wagmi'
|
||||||
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
|
|
||||||
export function Steps({
|
export function Steps({
|
||||||
feedback
|
feedback
|
||||||
}: {
|
}: {
|
||||||
feedback: PublishFeedback
|
feedback: PublishFeedback
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { chainId, accountId, approvedBaseTokens } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
const { approvedBaseTokens } = useMarketMetadata()
|
||||||
const { values, setFieldValue, touched, setTouched } =
|
const { values, setFieldValue, touched, setTouched } =
|
||||||
useFormikContext<FormPublishData>()
|
useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
const isCustomProviderUrl = values?.services?.[0]?.providerUrl.custom
|
const isCustomProviderUrl = values?.services?.[0]?.providerUrl.custom
|
||||||
|
|
||||||
// auto-sync user chainId & account into form data values
|
// auto-sync user chain?.id & account into form data values
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!chainId || !accountId) return
|
if (!chain?.id || !accountId) return
|
||||||
|
|
||||||
setFieldValue('user.chainId', chainId)
|
setFieldValue('user.chainId', chain?.id)
|
||||||
setFieldValue('user.accountId', accountId)
|
setFieldValue('user.accountId', accountId)
|
||||||
}, [chainId, accountId, setFieldValue])
|
}, [chain?.id, accountId, setFieldValue])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!approvedBaseTokens?.length) return
|
if (!approvedBaseTokens?.length) return
|
||||||
@ -37,7 +40,7 @@ export function Steps({
|
|||||||
if (isBaseTokenSet) return
|
if (isBaseTokenSet) return
|
||||||
|
|
||||||
setFieldValue('pricing.baseToken', defaultBaseToken)
|
setFieldValue('pricing.baseToken', defaultBaseToken)
|
||||||
}, [approvedBaseTokens])
|
}, [approvedBaseTokens, values?.pricing?.baseToken?.address])
|
||||||
|
|
||||||
// auto-sync publish feedback into form data values
|
// auto-sync publish feedback into form data values
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -3,16 +3,19 @@ import NetworkName from '@shared/NetworkName'
|
|||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import content from '../../../../content/publish/index.json'
|
import content from '../../../../content/publish/index.json'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import Info from '@images/info.svg'
|
import Info from '@images/info.svg'
|
||||||
import AvailableNetworks from '@components/Publish/AvailableNetworks'
|
import AvailableNetworks from '@components/Publish/AvailableNetworks'
|
||||||
|
import useNetworkMetadata from '@hooks/useNetworkMetadata'
|
||||||
|
import { useAccount } from 'wagmi'
|
||||||
|
|
||||||
export default function Title({
|
export default function Title({
|
||||||
networkId
|
networkId
|
||||||
}: {
|
}: {
|
||||||
networkId: number
|
networkId: number
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isSupportedOceanNetwork, accountId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { isSupportedOceanNetwork } = useNetworkMetadata()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{content.title}{' '}
|
{content.title}{' '}
|
||||||
|
@ -11,13 +11,13 @@ import {
|
|||||||
NftCreateData,
|
NftCreateData,
|
||||||
NftFactory,
|
NftFactory,
|
||||||
Service,
|
Service,
|
||||||
ZERO_ADDRESS
|
ZERO_ADDRESS,
|
||||||
|
getEventFromTx
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { mapTimeoutStringToSeconds, normalizeFile } from '@utils/ddo'
|
import { mapTimeoutStringToSeconds, normalizeFile } from '@utils/ddo'
|
||||||
import { generateNftCreateData } from '@utils/nft'
|
import { generateNftCreateData } from '@utils/nft'
|
||||||
import { getEncryptedFiles } from '@utils/provider'
|
import { getEncryptedFiles } from '@utils/provider'
|
||||||
import slugify from 'slugify'
|
import slugify from 'slugify'
|
||||||
import Web3 from 'web3'
|
|
||||||
import { algorithmContainerPresets } from './_constants'
|
import { algorithmContainerPresets } from './_constants'
|
||||||
import { FormPublishData, MetadataAlgorithmContainer } from './_types'
|
import { FormPublishData, MetadataAlgorithmContainer } from './_types'
|
||||||
import {
|
import {
|
||||||
@ -28,6 +28,7 @@ import {
|
|||||||
} from '../../../app.config'
|
} from '../../../app.config'
|
||||||
import { sanitizeUrl } from '@utils/url'
|
import { sanitizeUrl } from '@utils/url'
|
||||||
import { getContainerChecksum } from '@utils/docker'
|
import { getContainerChecksum } from '@utils/docker'
|
||||||
|
import { parseEther } from 'ethers/lib/utils'
|
||||||
|
|
||||||
function getUrlFileExtension(fileUrl: string): string {
|
function getUrlFileExtension(fileUrl: string): string {
|
||||||
const splittedFileUrl = fileUrl.split('.')
|
const splittedFileUrl = fileUrl.split('.')
|
||||||
@ -193,8 +194,7 @@ export async function createTokensAndPricing(
|
|||||||
values: FormPublishData,
|
values: FormPublishData,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
config: Config,
|
config: Config,
|
||||||
nftFactory: NftFactory,
|
nftFactory: NftFactory
|
||||||
web3: Web3
|
|
||||||
) {
|
) {
|
||||||
const nftCreateData: NftCreateData = generateNftCreateData(
|
const nftCreateData: NftCreateData = generateNftCreateData(
|
||||||
values.metadata.nft,
|
values.metadata.nft,
|
||||||
@ -241,15 +241,18 @@ export async function createTokensAndPricing(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const result = await nftFactory.createNftWithDatatokenWithFixedRate(
|
const result = await nftFactory.createNftWithDatatokenWithFixedRate(
|
||||||
accountId,
|
|
||||||
nftCreateData,
|
nftCreateData,
|
||||||
ercParams,
|
ercParams,
|
||||||
freParams
|
freParams
|
||||||
)
|
)
|
||||||
|
|
||||||
erc721Address = result.events.NFTCreated.returnValues[0]
|
const trxReceipt = await result.wait()
|
||||||
datatokenAddress = result.events.TokenCreated.returnValues[0]
|
const nftCreatedEvent = getEventFromTx(trxReceipt, 'NFTCreated')
|
||||||
txHash = result.transactionHash
|
const tokenCreatedEvent = getEventFromTx(trxReceipt, 'TokenCreated')
|
||||||
|
|
||||||
|
erc721Address = nftCreatedEvent.args.newTokenAddress
|
||||||
|
datatokenAddress = tokenCreatedEvent.args.newTokenAddress
|
||||||
|
txHash = trxReceipt.transactionHash
|
||||||
|
|
||||||
LoggerInstance.log('[publish] createNftErcWithFixedRate tx', txHash)
|
LoggerInstance.log('[publish] createNftErcWithFixedRate tx', txHash)
|
||||||
|
|
||||||
@ -261,8 +264,8 @@ export async function createTokensAndPricing(
|
|||||||
// both will be just 1 for the market
|
// both will be just 1 for the market
|
||||||
const dispenserParams: DispenserCreationParams = {
|
const dispenserParams: DispenserCreationParams = {
|
||||||
dispenserAddress: config.dispenserAddress,
|
dispenserAddress: config.dispenserAddress,
|
||||||
maxTokens: web3.utils.toWei('1'),
|
maxTokens: parseEther('1').toString(),
|
||||||
maxBalance: web3.utils.toWei('1'),
|
maxBalance: parseEther('1').toString(),
|
||||||
withMint: true,
|
withMint: true,
|
||||||
allowedSwapper: ZERO_ADDRESS
|
allowedSwapper: ZERO_ADDRESS
|
||||||
}
|
}
|
||||||
@ -273,14 +276,17 @@ export async function createTokensAndPricing(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const result = await nftFactory.createNftWithDatatokenWithDispenser(
|
const result = await nftFactory.createNftWithDatatokenWithDispenser(
|
||||||
accountId,
|
|
||||||
nftCreateData,
|
nftCreateData,
|
||||||
ercParams,
|
ercParams,
|
||||||
dispenserParams
|
dispenserParams
|
||||||
)
|
)
|
||||||
erc721Address = result.events.NFTCreated.returnValues[0]
|
const trxReceipt = await result.wait()
|
||||||
datatokenAddress = result.events.TokenCreated.returnValues[0]
|
const nftCreatedEvent = getEventFromTx(trxReceipt, 'NFTCreated')
|
||||||
txHash = result.transactionHash
|
const tokenCreatedEvent = getEventFromTx(trxReceipt, 'TokenCreated')
|
||||||
|
|
||||||
|
erc721Address = nftCreatedEvent.args.newTokenAddress
|
||||||
|
datatokenAddress = tokenCreatedEvent.args.newTokenAddress
|
||||||
|
txHash = trxReceipt.transactionHash
|
||||||
|
|
||||||
LoggerInstance.log('[publish] createNftErcWithDispenser tx', txHash)
|
LoggerInstance.log('[publish] createNftErcWithDispenser tx', txHash)
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import React, { ReactElement, useState, useRef } from 'react'
|
|||||||
import { Form, Formik } from 'formik'
|
import { Form, Formik } from 'formik'
|
||||||
import { initialPublishFeedback, initialValues } from './_constants'
|
import { initialPublishFeedback, initialValues } from './_constants'
|
||||||
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import { createTokensAndPricing, transformPublishFormToDdo } from './_utils'
|
import { createTokensAndPricing, transformPublishFormToDdo } from './_utils'
|
||||||
import PageHeader from '@shared/Page/PageHeader'
|
import PageHeader from '@shared/Page/PageHeader'
|
||||||
import Title from './Title'
|
import Title from './Title'
|
||||||
@ -19,6 +18,7 @@ import { getOceanConfig } from '@utils/ocean'
|
|||||||
import { validationSchema } from './_validation'
|
import { validationSchema } from './_validation'
|
||||||
import { useAbortController } from '@hooks/useAbortController'
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
import { setNFTMetadataAndTokenURI } from '@utils/nft'
|
import { setNFTMetadataAndTokenURI } from '@utils/nft'
|
||||||
|
import { useAccount, useNetwork, useSigner } from 'wagmi'
|
||||||
|
|
||||||
export default function PublishPage({
|
export default function PublishPage({
|
||||||
content
|
content
|
||||||
@ -26,7 +26,9 @@ export default function PublishPage({
|
|||||||
content: { title: string; description: string; warning: string }
|
content: { title: string; description: string; warning: string }
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { accountId, web3, chainId } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { data: signer } = useSigner()
|
||||||
|
const { chain } = useNetwork()
|
||||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
||||||
const scrollToRef = useRef()
|
const scrollToRef = useRef()
|
||||||
const nftFactory = useNftFactory()
|
const nftFactory = useNftFactory()
|
||||||
@ -60,17 +62,11 @@ export default function PublishPage({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const config = getOceanConfig(chainId)
|
const config = getOceanConfig(chain?.id)
|
||||||
LoggerInstance.log('[publish] using config: ', config)
|
LoggerInstance.log('[publish] using config: ', config)
|
||||||
|
|
||||||
const { erc721Address, datatokenAddress, txHash } =
|
const { erc721Address, datatokenAddress, txHash } =
|
||||||
await createTokensAndPricing(
|
await createTokensAndPricing(values, accountId, config, nftFactory)
|
||||||
values,
|
|
||||||
accountId,
|
|
||||||
config,
|
|
||||||
nftFactory,
|
|
||||||
web3
|
|
||||||
)
|
|
||||||
|
|
||||||
const isSuccess = Boolean(erc721Address && datatokenAddress && txHash)
|
const isSuccess = Boolean(erc721Address && datatokenAddress && txHash)
|
||||||
if (!isSuccess) throw new Error('No Token created. Please try again.')
|
if (!isSuccess) throw new Error('No Token created. Please try again.')
|
||||||
@ -197,23 +193,24 @@ export default function PublishPage({
|
|||||||
const res = await setNFTMetadataAndTokenURI(
|
const res = await setNFTMetadataAndTokenURI(
|
||||||
ddo,
|
ddo,
|
||||||
accountId,
|
accountId,
|
||||||
web3,
|
signer,
|
||||||
values.metadata.nft,
|
values.metadata.nft,
|
||||||
newAbortController()
|
newAbortController()
|
||||||
)
|
)
|
||||||
if (!res?.transactionHash)
|
const tx = await res.wait()
|
||||||
|
if (!tx?.transactionHash)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Metadata could not be written into the NFT. Please try again.'
|
'Metadata could not be written into the NFT. Please try again.'
|
||||||
)
|
)
|
||||||
|
|
||||||
LoggerInstance.log('[publish] setMetadata result', res)
|
LoggerInstance.log('[publish] setMetadata result', tx)
|
||||||
|
|
||||||
setFeedback((prevState) => ({
|
setFeedback((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
'3': {
|
'3': {
|
||||||
...prevState['3'],
|
...prevState['3'],
|
||||||
status: res ? 'success' : 'error',
|
status: tx ? 'success' : 'error',
|
||||||
txHash: res?.transactionHash
|
txHash: tx?.transactionHash
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
// import App from "next/app";
|
// import App from "next/app";
|
||||||
import React, { ReactElement, useEffect } from 'react'
|
import React, { ReactElement, useEffect } from 'react'
|
||||||
import type { AppProps /*, AppContext */ } from 'next/app'
|
import type { AppProps /*, AppContext */ } from 'next/app'
|
||||||
import Web3Provider from '@context/Web3'
|
|
||||||
import { UserPreferencesProvider } from '@context/UserPreferences'
|
import { UserPreferencesProvider } from '@context/UserPreferences'
|
||||||
import PricesProvider from '@context/Prices'
|
import PricesProvider from '@context/Prices'
|
||||||
import UrqlProvider from '@context/UrqlProvider'
|
import UrqlProvider from '@context/UrqlProvider'
|
||||||
import ConsentProvider from '@context/CookieConsent'
|
import ConsentProvider from '@context/CookieConsent'
|
||||||
|
import App from '../../src/components/App'
|
||||||
import { OrbisProvider } from '@context/DirectMessages'
|
import { OrbisProvider } from '@context/DirectMessages'
|
||||||
import App from 'src/components/App'
|
|
||||||
|
|
||||||
import '@oceanprotocol/typographies/css/ocean-typo.css'
|
import '@oceanprotocol/typographies/css/ocean-typo.css'
|
||||||
import '../stylesGlobal/styles.css'
|
import '../stylesGlobal/styles.css'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import MarketMetadataProvider from '@context/MarketMetadata'
|
import MarketMetadataProvider from '@context/MarketMetadata'
|
||||||
|
import { WagmiConfig } from 'wagmi'
|
||||||
|
import { ConnectKitProvider } from 'connectkit'
|
||||||
|
import { connectKitTheme, wagmiClient } from '@utils/wallet'
|
||||||
import posthog from 'posthog-js'
|
import posthog from 'posthog-js'
|
||||||
import { PostHogProvider } from 'posthog-js/react'
|
import { PostHogProvider } from 'posthog-js/react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
@ -40,25 +41,32 @@ function MyApp({ Component, pageProps }: AppProps): ReactElement {
|
|||||||
}, [router.events])
|
}, [router.events])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MarketMetadataProvider>
|
<>
|
||||||
<Web3Provider>
|
<WagmiConfig client={wagmiClient}>
|
||||||
<UrqlProvider>
|
<ConnectKitProvider
|
||||||
<UserPreferencesProvider>
|
options={{ initialChainId: 0 }}
|
||||||
<PricesProvider>
|
customTheme={connectKitTheme}
|
||||||
<ConsentProvider>
|
>
|
||||||
<OrbisProvider>
|
<MarketMetadataProvider>
|
||||||
<PostHogProvider client={posthog}>
|
<UrqlProvider>
|
||||||
<App>
|
<UserPreferencesProvider>
|
||||||
<Component {...pageProps} />
|
<PricesProvider>
|
||||||
</App>
|
<ConsentProvider>
|
||||||
</PostHogProvider>
|
<OrbisProvider>
|
||||||
</OrbisProvider>
|
<PostHogProvider client={posthog}>
|
||||||
</ConsentProvider>
|
<App>
|
||||||
</PricesProvider>
|
<Component {...pageProps} />
|
||||||
</UserPreferencesProvider>
|
</App>
|
||||||
</UrqlProvider>
|
</PostHogProvider>
|
||||||
</Web3Provider>
|
</OrbisProvider>
|
||||||
</MarketMetadataProvider>
|
</ConsentProvider>
|
||||||
|
</PricesProvider>
|
||||||
|
</UserPreferencesProvider>
|
||||||
|
</UrqlProvider>
|
||||||
|
</MarketMetadataProvider>
|
||||||
|
</ConnectKitProvider>
|
||||||
|
</WagmiConfig>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import Page from '@shared/Page'
|
import Page from '@shared/Page'
|
||||||
import ProfilePage from '../../components/Profile'
|
import ProfilePage from '../../components/Profile'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import { useWeb3 } from '@context/Web3'
|
|
||||||
import ProfileProvider from '@context/Profile'
|
import ProfileProvider from '@context/Profile'
|
||||||
import { getEnsAddress, getEnsName } from '@utils/ens'
|
import { getEnsAddress, getEnsName } from '@utils/ens'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import web3 from 'web3'
|
import { useAccount, useEnsName } from 'wagmi'
|
||||||
|
import { isAddress } from 'ethers/lib/utils'
|
||||||
|
|
||||||
export default function PageProfile(): ReactElement {
|
export default function PageProfile(): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { accountId, accountEns } = useWeb3()
|
const { address: accountId } = useAccount()
|
||||||
|
const { data: accountEns } = useEnsName({ address: accountId })
|
||||||
const [finalAccountId, setFinalAccountId] = useState<string>()
|
const [finalAccountId, setFinalAccountId] = useState<string>()
|
||||||
const [finalAccountEns, setFinalAccountEns] = useState<string>()
|
const [finalAccountEns, setFinalAccountEns] = useState<string>()
|
||||||
const [ownAccount, setOwnAccount] = useState(false)
|
const [ownAccount, setOwnAccount] = useState(false)
|
||||||
|
|
||||||
// Have accountId in path take over, if not present fall back to web3
|
// Have accountId in path take over, if not present fall back to web3
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function init() {
|
async function init() {
|
||||||
@ -30,7 +32,7 @@ export default function PageProfile(): ReactElement {
|
|||||||
const pathAccount = router.query.account as string
|
const pathAccount = router.query.account as string
|
||||||
|
|
||||||
// Path has ETH address
|
// Path has ETH address
|
||||||
if (web3.utils.isAddress(pathAccount)) {
|
if (isAddress(pathAccount)) {
|
||||||
setOwnAccount(pathAccount === accountId)
|
setOwnAccount(pathAccount === accountId)
|
||||||
const finalAccountId = pathAccount || accountId
|
const finalAccountId = pathAccount || accountId
|
||||||
setFinalAccountId(finalAccountId)
|
setFinalAccountId(finalAccountId)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useState } from 'react'
|
||||||
import Search from '../components/Search'
|
import Search from '../components/Search'
|
||||||
import Page from '@shared/Page'
|
import Page from '@shared/Page'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/wallet'
|
||||||
import { MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS } from '@utils/aquarius'
|
import { MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS } from '@utils/aquarius'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import web3 from 'web3'
|
import { isAddress } from 'ethers/lib/utils'
|
||||||
|
|
||||||
export default function PageSearch(): ReactElement {
|
export default function PageSearch(): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -13,7 +13,7 @@ export default function PageSearch(): ReactElement {
|
|||||||
const [totalResults, setTotalResults] = useState<number>()
|
const [totalResults, setTotalResults] = useState<number>()
|
||||||
const [totalPagesNumber, setTotalPagesNumber] = useState<number>()
|
const [totalPagesNumber, setTotalPagesNumber] = useState<number>()
|
||||||
|
|
||||||
const isETHAddress = web3.utils.isAddress(text as string)
|
const isETHAddress = isAddress(text as string)
|
||||||
const searchValue =
|
const searchValue =
|
||||||
(isETHAddress ? accountTruncate(text as string) : text) ||
|
(isETHAddress ? accountTruncate(text as string) : text) ||
|
||||||
tags ||
|
tags ||
|
||||||
|
@ -1,151 +0,0 @@
|
|||||||
div.web3modal-modal-lightbox,
|
|
||||||
div.walletconnect-qrcode__base {
|
|
||||||
background: var(--background-body-transparent);
|
|
||||||
backdrop-filter: blur(3px);
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
animation: fadeIn 0.2s ease-out backwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-modal-card {
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
padding: var(--spacer);
|
|
||||||
margin: var(--spacer) auto;
|
|
||||||
max-width: 100%;
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
box-shadow: 0 6px 15px 0 var(--box-shadow-color);
|
|
||||||
animation: moveUp 0.2s ease-out backwards;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper {
|
|
||||||
border: 0;
|
|
||||||
border-bottom: 1px solid var(--border-color);
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper:last-child {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-container {
|
|
||||||
border-radius: 0;
|
|
||||||
padding: var(--spacer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 40rem) {
|
|
||||||
div.web3modal-modal-card {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
max-width: var(--break-point--small);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper:nth-child(1),
|
|
||||||
div.web3modal-provider-wrapper:nth-child(2) {
|
|
||||||
border-bottom: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper:nth-child(2n + 1) {
|
|
||||||
border-right: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-icon {
|
|
||||||
filter: grayscale(1) contrast(150%);
|
|
||||||
transition: filter 0.2s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-wrapper:hover div.web3modal-provider-icon {
|
|
||||||
filter: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-name {
|
|
||||||
font-size: var(--font-size-large);
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
font-family: var(--font-family-heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.web3modal-provider-description {
|
|
||||||
font-size: var(--font-size-base);
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.walletconnect-modal__base {
|
|
||||||
background: var(--background-body);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
box-shadow: 0 6px 17px 0 var(--box-shadow-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.walletconnect-modal__mobile__toggle {
|
|
||||||
width: 95%;
|
|
||||||
text-transform: uppercase;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--background-body);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.walletconnect-modal__mobile__toggle a {
|
|
||||||
color: var(--color-secondary);
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
padding: calc(var(--spacer) / 12) var(--spacer);
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.walletconnect-modal__mobile__toggle_selector {
|
|
||||||
background: var(--font-color-heading);
|
|
||||||
color: var(--background-body);
|
|
||||||
border-color: var(--font-color-heading);
|
|
||||||
height: calc(100% - calc(var(--spacer) / 12));
|
|
||||||
top: calc(var(--spacer) / 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.walletconnect-modal__header p {
|
|
||||||
color: var(--font-color-heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.walletconnect-qrcode__text {
|
|
||||||
color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
h3.walletconnect-modal__base__row__h3 {
|
|
||||||
font-size: var(--font-size-base);
|
|
||||||
color: var(--font-color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.walletconnect-qrcode__image path:first-child {
|
|
||||||
fill: var(--background-body);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.walletconnect-qrcode__image path:last-child {
|
|
||||||
stroke: var(--font-color-heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
#torusIframe {
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes moveUp {
|
|
||||||
from {
|
|
||||||
transform: translate3d(0, 1rem, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -162,7 +162,6 @@ table th {
|
|||||||
|
|
||||||
@import '_code.css';
|
@import '_code.css';
|
||||||
@import '_toast.css';
|
@import '_toast.css';
|
||||||
@import '_web3modal.css';
|
|
||||||
@import '_emojipicker.css';
|
@import '_emojipicker.css';
|
||||||
|
|
||||||
/* prevent background scrolling */
|
/* prevent background scrolling */
|
||||||
|
Loading…
Reference in New Issue
Block a user