diff --git a/src/@context/Asset.tsx b/src/@context/Asset.tsx index 1f7b4a71..a353c461 100644 --- a/src/@context/Asset.tsx +++ b/src/@context/Asset.tsx @@ -86,6 +86,15 @@ function AssetProvider({ const newCancelToken = useCancelToken() const isMounted = useIsMounted() + const [accountIdToCheck, setAccountIdToCheck] = useState(accountId) + useEffect(() => { + if (isAutomationEnabled && autoWallet?.address) { + setAccountIdToCheck(autoWallet.address) + } else { + setAccountIdToCheck(accountId) + } + }, [accountId, autoWallet, isAutomationEnabled]) + // ----------------------------------- // Helper: Get and set asset based on passed DID // ----------------------------------- @@ -155,11 +164,6 @@ function AssetProvider({ const fetchAccessDetails = useCallback(async (): Promise => { 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, @@ -171,14 +175,7 @@ function AssetProvider({ 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 @@ -246,7 +243,7 @@ function AssetProvider({ if (!isMounted) return fetchAccessDetails() - }, [accountId, fetchAccessDetails, isMounted]) + }, [accountIdToCheck, fetchAccessDetails, isMounted]) // ----------------------------------- // Check user network against asset network @@ -262,11 +259,11 @@ function AssetProvider({ // 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 diff --git a/src/@hooks/useNftFactory.ts b/src/@hooks/useNftFactory.ts index 560abdef..3e8a754d 100644 --- a/src/@hooks/useNftFactory.ts +++ b/src/@hooks/useNftFactory.ts @@ -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() 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 } diff --git a/src/components/Asset/Edit/EditComputeDataset.tsx b/src/components/Asset/Edit/EditComputeDataset.tsx index 63debfd5..caeaaaba 100644 --- a/src/components/Asset/Edit/EditComputeDataset.tsx +++ b/src/components/Asset/Edit/EditComputeDataset.tsx @@ -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, @@ -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 @@ -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(accountId) + + useEffect(() => { + setSignerToUse(isAutomationEnabled ? autoWallet : signer) + setAccountIdToUse(isAutomationEnabled ? autoWallet?.address : accountId) + }, [isAutomationEnabled, accountId, autoWallet, signer]) const [success, setSuccess] = useState() const [error, setError] = useState() @@ -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 @@ -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() ) @@ -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 @@ -163,7 +172,7 @@ export default function EditComputeDataset({ {debug === true && ( diff --git a/src/components/Asset/Edit/EditMetadata.tsx b/src/components/Asset/Edit/EditMetadata.tsx index c78cb97e..f5c72ad1 100644 --- a/src/components/Asset/Edit/EditMetadata.tsx +++ b/src/components/Asset/Edit/EditMetadata.tsx @@ -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 @@ -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() @@ -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(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 @@ -82,7 +98,7 @@ export default function Edit({ const fixedRateInstance = new FixedRateExchange( config.fixedRateExchangeAddress, - signer + signerToUse ) const setPriceResp = await fixedRateInstance.setRate( @@ -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 ) } @@ -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 @@ -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() // ) @@ -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) { @@ -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 @@ -304,7 +320,7 @@ export default function Edit({ diff --git a/src/components/Publish/index.tsx b/src/components/Publish/index.tsx index b6f48319..c89c2963 100644 --- a/src/components/Publish/index.tsx +++ b/src/components/Publish/index.tsx @@ -1,4 +1,4 @@ -import { ReactElement, useState, useRef } from 'react' +import { ReactElement, useState, useRef, useEffect } from 'react' import { Form, Formik } from 'formik' import { initialPublishFeedback, initialValues } from './_constants' import { useAccountPurgatory } from '@hooks/useAccountPurgatory' @@ -25,6 +25,7 @@ import { useAbortController } from '@hooks/useAbortController' import { setNFTMetadataAndTokenURI } from '@utils/nft' import { customProviderUrl } from '../../../app.config' import { useAccount, useNetwork, useSigner } from 'wagmi' +import { useAutomation } from '../../@context/Automation/AutomationProvider' export default function PublishPage({ content @@ -51,6 +52,20 @@ export default function PublishPage({ const [ddoEncrypted, setDdoEncrypted] = useState() const [did, setDid] = useState() + const { autoWallet, isAutomationEnabled } = useAutomation() + const [accountIdToUse, setAccountIdToUse] = useState(accountId) + const [signerToUse, setSignerToUse] = useState(signer) + + useEffect(() => { + if (isAutomationEnabled && autoWallet?.address) { + setAccountIdToUse(autoWallet.address) + setSignerToUse(autoWallet) + } else { + setAccountIdToUse(accountId) + setSignerToUse(signer) + } + }, [isAutomationEnabled, autoWallet, accountId, signer]) + // -------------------------------------------------- // 1. Create NFT & datatokens & create pricing schema // -------------------------------------------------- @@ -72,7 +87,7 @@ export default function PublishPage({ LoggerInstance.log('[publish] using config: ', config) const { erc721Address, datatokenAddress, txHash } = - await createTokensAndPricing(values, accountId, config, nftFactory) + await createTokensAndPricing(values, accountIdToUse, config, nftFactory) const isSuccess = Boolean(erc721Address && datatokenAddress && txHash) if (!isSuccess) throw new Error('No Token created. Please try again.') @@ -203,8 +218,8 @@ export default function PublishPage({ const res = await setNFTMetadataAndTokenURI( ddo, - accountId, - signer, + accountIdToUse, + signerToUse, values.metadata.nft, newAbortController() )