Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: auto wallet for publish and edit functionality #530

Merged
merged 5 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions src/@context/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@
const newCancelToken = useCancelToken()
const isMounted = useIsMounted()

const [accountIdToCheck, setAccountIdToCheck] = useState<string>(accountId)
useEffect(() => {
if (isAutomationEnabled && autoWallet?.address) {
setAccountIdToCheck(autoWallet.address)
} else {
setAccountIdToCheck(accountId)
}
}, [accountId, autoWallet, isAutomationEnabled])

// -----------------------------------
// Helper: Get and set asset based on passed DID
// -----------------------------------
Expand Down Expand Up @@ -146,7 +155,7 @@

setLoading(false)
},
[did, accountId]

Check warning on line 158 in src/@context/Asset.tsx

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18)

React Hook useCallback has a missing dependency: 'isDDOWhitelisted'. Either include it or remove the dependency array
)

// -----------------------------------
Expand All @@ -155,11 +164,6 @@
const fetchAccessDetails = useCallback(async (): Promise<void> => {
if (!asset?.chainId || !asset?.services?.length) return

const accountIdToCheck =
isAutomationEnabled && autoWallet?.address
? autoWallet.address
: accountId

const accessDetails = await getAccessDetails(
asset.chainId,
asset.services[0].datatokenAddress,
Expand All @@ -171,14 +175,7 @@
accessDetails
}))
LoggerInstance.log(`[asset] Got access details for ${did}`, accessDetails)
}, [
asset?.chainId,
asset?.services,
accountId,
did,
autoWallet?.address,
isAutomationEnabled
])
}, [asset?.chainId, asset?.services, accountIdToCheck, did])

// -----------------------------------
// Helper: Get and set asset Service Credential state
Expand Down Expand Up @@ -246,7 +243,7 @@
if (!isMounted) return

fetchAccessDetails()
}, [accountId, fetchAccessDetails, isMounted])
}, [accountIdToCheck, fetchAccessDetails, isMounted])

// -----------------------------------
// Check user network against asset network
Expand All @@ -262,11 +259,11 @@
// Asset owner check against wallet user
// -----------------------------------
useEffect(() => {
if (!accountId || !owner) return
if (!accountIdToCheck || !owner) return

const isOwner = accountId?.toLowerCase() === owner.toLowerCase()
const isOwner = accountIdToCheck?.toLowerCase() === owner.toLowerCase()
setIsOwner(isOwner)
}, [accountId, owner])
}, [accountIdToCheck, owner])

// -----------------------------------
// Load ocean config based on asset network
Expand Down
26 changes: 21 additions & 5 deletions src/@hooks/useNftFactory.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import { useEffect, useState } from 'react'
import { NftFactory } from '@oceanprotocol/lib'
import { LoggerInstance, NftFactory } from '@oceanprotocol/lib'
import { getOceanConfig } from '@utils/ocean'
import { useEffect, useState } from 'react'
import { useNetwork, useSigner } from 'wagmi'
import { useAutomation } from '../@context/Automation/AutomationProvider'

function useNftFactory(): NftFactory {
const { chain } = useNetwork()
const { data: signer } = useSigner()
const { autoWallet, isAutomationEnabled } = useAutomation()
const [signerToUse, setSignerToUse] = useState(signer)
const [nftFactory, setNftFactory] = useState<NftFactory>()

useEffect(() => {
if (!signer || !chain?.id) return
if (isAutomationEnabled && autoWallet?.address) {
setSignerToUse(autoWallet)
} else {
setSignerToUse(signer)
}
}, [isAutomationEnabled, autoWallet, signer])

useEffect(() => {
if (!signerToUse || !chain?.id) return

const config = getOceanConfig(chain.id)
const factory = new NftFactory(config?.nftFactoryAddress, signer)
const factory = new NftFactory(config?.nftFactoryAddress, signerToUse)
LoggerInstance.log('[NftFactory] instantiated:', {
chain: chain.id,
factory: factory.address,
signer: signerToUse
})
setNftFactory(factory)
}, [signer, chain?.id])
}, [signerToUse, chain?.id])

return nftFactory
}
Expand Down
25 changes: 17 additions & 8 deletions src/components/Asset/Edit/EditComputeDataset.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Formik } from 'formik'
import { ReactElement, useState } from 'react'
import { ReactElement, useEffect, useState } from 'react'
import FormEditComputeDataset from './FormEditComputeDataset'
import {
LoggerInstance,
Expand Down Expand Up @@ -28,6 +28,7 @@ import {
} from '@utils/nft'
import { ComputeEditForm } from './_types'
import { useAccount, useSigner } from 'wagmi'
import { useAutomation } from '../../../@context/Automation/AutomationProvider'

export default function EditComputeDataset({
asset
Expand All @@ -38,6 +39,14 @@ export default function EditComputeDataset({
const { address: accountId } = useAccount()
const { data: signer } = useSigner()
const { fetchAsset, isAssetNetwork } = useAsset()
const { autoWallet, isAutomationEnabled } = useAutomation()
const [signerToUse, setSignerToUse] = useState(signer)
const [accountIdToUse, setAccountIdToUse] = useState<string>(accountId)

useEffect(() => {
setSignerToUse(isAutomationEnabled ? autoWallet : signer)
setAccountIdToUse(isAutomationEnabled ? autoWallet?.address : accountId)
}, [isAutomationEnabled, accountId, autoWallet, signer])

const [success, setSuccess] = useState<string>()
const [error, setError] = useState<string>()
Expand All @@ -52,9 +61,9 @@ export default function EditComputeDataset({
asset?.accessDetails?.isPurchasable
) {
const tx = await setMinterToPublisher(
signer,
signerToUse,
asset?.accessDetails?.datatoken?.address,
accountId,
accountIdToUse,
setError
)
if (!tx) return
Expand Down Expand Up @@ -90,8 +99,8 @@ export default function EditComputeDataset({
// TODO: revert to setMetadata function
const setMetadataTx = await setNFTMetadataAndTokenURI(
updatedAsset,
accountId,
signer,
accountIdToUse,
signerToUse,
decodeTokenURI(asset.nft.tokenURI),
newAbortController()
)
Expand All @@ -112,9 +121,9 @@ export default function EditComputeDataset({
await setMetadataTx.wait()
if (asset.accessDetails.type === 'free') {
const tx = await setMinterToDispenser(
signer,
signerToUse,
asset?.accessDetails?.datatoken?.address,
accountId,
accountIdToUse,
setError
)
if (!tx) return
Expand Down Expand Up @@ -163,7 +172,7 @@ export default function EditComputeDataset({
<FormEditComputeDataset />
<Web3Feedback
networkId={asset?.chainId}
accountId={accountId}
accountId={accountIdToUse}
isAssetNetwork={isAssetNetwork}
/>
{debug === true && (
Expand Down
102 changes: 59 additions & 43 deletions src/components/Asset/Edit/EditMetadata.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
import { ReactElement, useState, useEffect } from 'react'
import { Formik } from 'formik'
import {
LoggerInstance,
FixedRateExchange,
generateCredentials,
transformConsumerParameters
} from '@components/Publish/_utils'
import { useAsset } from '@context/Asset'
import { useUserPreferences } from '@context/UserPreferences'
import { useAbortController } from '@hooks/useAbortController'
import {
Asset,
Datatoken,
Nft,
FixedRateExchange,
LoggerInstance,
Metadata,
Nft,
Service
} from '@oceanprotocol/lib'
import { validationSchema } from './_validation'
import { getInitialValues } from './_constants'
import { MetadataEditForm } from './_types'
import { useUserPreferences } from '@context/UserPreferences'
import Web3Feedback from '@shared/Web3Feedback'
import FormEditMetadata from './FormEditMetadata'
import { assetStateToNumber } from '@utils/assetState'
import { mapTimeoutStringToSeconds, normalizeFile } from '@utils/ddo'
import styles from './index.module.css'
import { setMinterToDispenser, setMinterToPublisher } from '@utils/dispenser'
import { decodeTokenURI, setNFTMetadataAndTokenURI } from '@utils/nft'
import { getOceanConfig, getPaymentCollector } from '@utils/ocean'
import { getEncryptedFiles } from '@utils/provider'
import { sanitizeUrl } from '@utils/url'
import { Formik } from 'formik'
import { ReactElement, useEffect, useState } from 'react'
import { useAccount, useNetwork, useProvider, useSigner } from 'wagmi'
import content from '../../../../content/pages/editMetadata.json'
import { useAbortController } from '@hooks/useAbortController'
import { useAutomation } from '../../../@context/Automation/AutomationProvider'
import DebugEditMetadata from './DebugEditMetadata'
import { getOceanConfig, getPaymentCollector } from '@utils/ocean'
import EditFeedback from './EditFeedback'
import { useAsset } from '@context/Asset'
import {
decodeTokenURI,
setNftMetadata,
setNFTMetadataAndTokenURI
} from '@utils/nft'
import { sanitizeUrl } from '@utils/url'
import { getEncryptedFiles } from '@utils/provider'
import { assetStateToNumber } from '@utils/assetState'
import { setMinterToPublisher, setMinterToDispenser } from '@utils/dispenser'
import { useAccount, useProvider, useNetwork, useSigner } from 'wagmi'
import {
transformConsumerParameters,
generateCredentials
} from '@components/Publish/_utils'
import FormEditMetadata from './FormEditMetadata'
import { getInitialValues } from './_constants'
import { MetadataEditForm } from './_types'
import { validationSchema } from './_validation'
import styles from './index.module.css'

export default function Edit({
asset
Expand All @@ -48,7 +45,7 @@ export default function Edit({
const { address: accountId } = useAccount()
const { chain } = useNetwork()
const provider = useProvider()
const { data: signer } = useSigner()
const { data: signer, refetch: refetchSigner } = useSigner()
const newAbortController = useAbortController()

const [success, setSuccess] = useState<string>()
Expand All @@ -57,6 +54,25 @@ export default function Edit({
const isComputeType = asset?.services[0]?.type === 'compute'
const hasFeedback = error || success

const { autoWallet, isAutomationEnabled } = useAutomation()
const [signerToUse, setSignerToUse] = useState(signer)
const [accountIdToUse, setAccountIdToUse] = useState<string>(accountId)

useEffect(() => {
if (isAutomationEnabled && autoWallet?.address) {
setAccountIdToUse(autoWallet.address)
setSignerToUse(autoWallet)
LoggerInstance.log('[edit] using autoWallet to sign')
} else if (accountId && signer) {
setAccountIdToUse(accountId)
setSignerToUse(signer)
LoggerInstance.log('[edit] using web3 account to sign')
} else {
refetchSigner()
LoggerInstance.log('[edit] refetching signer')
}
}, [isAutomationEnabled, signer, autoWallet, accountId])

useEffect(() => {
if (!asset || !provider) return

Expand All @@ -82,7 +98,7 @@ export default function Edit({

const fixedRateInstance = new FixedRateExchange(
config.fixedRateExchangeAddress,
signer
signerToUse
)

const setPriceResp = await fixedRateInstance.setRate(
Expand Down Expand Up @@ -130,10 +146,10 @@ export default function Edit({
(await updateFixedPrice(values.price))

if (values.paymentCollector !== paymentCollector) {
const datatoken = new Datatoken(signer)
const datatoken = new Datatoken(signerToUse)
await datatoken.setPaymentCollector(
asset?.datatokens[0].address,
accountId,
accountIdToUse,
values.paymentCollector
)
}
Expand Down Expand Up @@ -185,9 +201,9 @@ export default function Edit({
asset?.accessDetails?.isPurchasable
) {
const tx = await setMinterToPublisher(
signer,
signerToUse,
asset?.accessDetails?.datatoken?.address,
accountId,
accountIdToUse,
setError
)
if (!tx) return
Expand All @@ -200,15 +216,15 @@ export default function Edit({
// TODO: revert to setMetadata function
const setMetadataTx = await setNFTMetadataAndTokenURI(
updatedAsset,
accountId,
signer,
accountIdToUse,
signerToUse,
decodeTokenURI(asset.nft.tokenURI),
newAbortController()
)
// const setMetadataTx = await setNftMetadata(
// updatedAsset,
// accountId,
// signer,
// accountIdToUse,
// signerToUse,
// newAbortController()
// )

Expand All @@ -224,11 +240,11 @@ export default function Edit({
assetState
})
if (values.assetState !== assetState) {
const nft = new Nft(signer)
const nft = new Nft(signerToUse)

const setMetadataStateTx = await nft.setMetadataState(
asset?.nftAddress,
accountId,
accountIdToUse,
assetStateToNumber(values.assetState)
)
if (!setMetadataStateTx) {
Expand All @@ -243,9 +259,9 @@ export default function Edit({

if (asset.accessDetails.type === 'free') {
const tx = await setMinterToDispenser(
signer,
signerToUse,
asset?.accessDetails?.datatoken?.address,
accountId,
accountIdToUse,
setError
)
if (!tx) return
Expand Down Expand Up @@ -304,7 +320,7 @@ export default function Edit({

<Web3Feedback
networkId={asset?.chainId}
accountId={accountId}
accountId={accountIdToUse}
isAssetNetwork={isAssetNetwork}
/>

Expand Down
Loading
Loading