From 1d82b370156f8b684dfe89dc1fdc139d25730e83 Mon Sep 17 00:00:00 2001 From: git Date: Mon, 6 Dec 2021 12:06:54 -0500 Subject: [PATCH 1/4] seperated out the logic from ipfs/metaPtrs and updated the components that use the functions. rebase --- app/src/components/GrantDetailsRow.vue | 2 - app/src/store/data.ts | 2 +- app/src/utils/data/grantRounds.ts | 2 +- app/src/utils/data/grants.ts | 2 +- app/src/utils/data/ipfs.ts | 111 +-------------------- app/src/utils/data/metaPtrs.ts | 86 ++++++++++++++++ app/src/utils/utils.ts | 33 +++++- app/src/views/Contribution.vue | 2 +- app/src/views/GrantRegistryGrantDetail.vue | 18 ++-- app/src/views/GrantRegistryNewGrant.vue | 21 ++-- dcurve/src/internal/calc/linear.ts | 3 +- 11 files changed, 150 insertions(+), 132 deletions(-) create mode 100644 app/src/utils/data/metaPtrs.ts diff --git a/app/src/components/GrantDetailsRow.vue b/app/src/components/GrantDetailsRow.vue index 7eb2e0e8..651a6722 100644 --- a/app/src/components/GrantDetailsRow.vue +++ b/app/src/components/GrantDetailsRow.vue @@ -52,8 +52,6 @@
- Matching: - {{ round.matching || '...' }} {{ round.matchingToken.symbol }} , {{ round.name }}
diff --git a/app/src/store/data.ts b/app/src/store/data.ts index 92ff1b05..86c94696 100644 --- a/app/src/store/data.ts +++ b/app/src/store/data.ts @@ -26,7 +26,7 @@ import { GrantMetadataResolution, GrantRoundMetadataResolution, } from '@dgrants/types'; -import { fetchMetaPtrs } from 'src/utils/data/ipfs'; +import { fetchMetaPtrs } from 'src/utils/data/metaPtrs'; import { TokenInfo } from '@uniswap/token-lists'; import { GRANT_REGISTRY_ADDRESS, diff --git a/app/src/utils/data/grantRounds.ts b/app/src/utils/data/grantRounds.ts index 9ed1b01c..e91beaac 100644 --- a/app/src/utils/data/grantRounds.ts +++ b/app/src/utils/data/grantRounds.ts @@ -18,7 +18,7 @@ import { formatNumber, callMulticallContract, batchFilterCall, metadataId, recur import { syncStorage } from 'src/utils/data/utils'; import { CLR, linear, InitArgs } from '@dgrants/dcurve'; import { filterContributionsByGrantId, filterContributionsByGrantRound } from './contributions'; -import { getMetadata } from './ipfs'; +import { getMetadata } from './metaPtrs'; // --- Constants --- import { START_BLOCK, diff --git a/app/src/utils/data/grants.ts b/app/src/utils/data/grants.ts index c062cc1c..3d98acce 100644 --- a/app/src/utils/data/grants.ts +++ b/app/src/utils/data/grants.ts @@ -13,7 +13,7 @@ import { batchFilterCall, recursiveGraphFetch } from '../utils'; import { DGRANTS_CHAIN_ID } from '../chains'; import { Ref } from 'vue'; import { getAddress } from '../ethers'; -import { getMetadata, fetchMetaPtrs } from './ipfs'; +import { fetchMetaPtrs, getMetadata } from './metaPtrs'; // --- pull in the registry contract const { grantRegistry } = useWalletStore(); diff --git a/app/src/utils/data/ipfs.ts b/app/src/utils/data/ipfs.ts index 17e8adfe..6017345e 100644 --- a/app/src/utils/data/ipfs.ts +++ b/app/src/utils/data/ipfs.ts @@ -1,22 +1,6 @@ import { createIpfs } from '@dgrants/utils/src/ipfs'; -import { GrantMetadata, GrantRoundMetadataResolution, MetaPtr } from '@dgrants/types'; -import { getStorageKey, setStorageKey } from 'src/utils/data/utils'; -import { decodeMetadataId, metadataId } from 'src/utils/utils'; -import { BigNumber } from 'src/utils/ethers'; -import { LocalForageData } from 'src/types'; -import { Ref } from 'vue'; - -const retrievalEndpoint = 'https://scopelift.b-cdn.net/ipfs'; - -function assertIPFSPointer(logoPtr: MetaPtr | undefined) { - if (!logoPtr) throw new Error('assertIPFSPointer: logoPtr is undefined'); - if (typeof logoPtr == 'string') { - logoPtr = decodeMetadataId(logoPtr); - } - const protocol = BigNumber.from(logoPtr.protocol).toString(); - if (!['0', '1'].includes(protocol)) - throw new Error(`assertIPFSPointer: Expected protocol ID of 0 or 1, found ${protocol}`); -} +import { GrantMetadata } from '@dgrants/types'; +import { assertIPFSPointer } from 'src/utils/utils'; export const ipfs = createIpfs(import.meta.env.VITE_FLEEK_STORAGE_API_KEY); @@ -37,94 +21,3 @@ export const uploadGrantMetadata = async ({ name, description, logoPtr, properti const res = await ipfs.add(JSON.stringify({ name, description, logoPtr, properties })); return res.cid; }; - -/** - * Creates a url for a MetaPtr - * @param obj - * @param obj.cid CID of the grant - * @returns string - */ -export const getMetaPtr = ({ cid }: { cid: string | undefined }) => { - return `${retrievalEndpoint}/${cid}`; -}; - -/** - * Given a CID, formats the metadata pointer for compatibility with the contracts - * @param cid CID of the grant - * @returns string - */ -export const formatMetaPtr = (cid: string): MetaPtr => { - return { - protocol: 1, // IPFS has a protocol ID of 1 - pointer: cid, - }; -}; - -/** - * Resolves a metaPtr via fetch - * @param url URL of metaPtr - * @returns Object - */ -export const resolveMetaPtr = (url: string) => { - return fetch(url).then((res) => res.json()); -}; - -/** - * @notice Helper method that fetches metadata for a Grant or GrantRound, and saves the data - * to the state as soon as it's received - * @param metaPtrs Array of IPFS MetaPtrs to resolve - * @param metadata Name of the store's ref to assign resolve metadata to - */ -export const fetchMetaPtrs = async (metaPtrs: MetaPtr[], metadata: Ref) => { - metaPtrs.forEach(assertIPFSPointer); - - // check for any missing entries - const newMetadata = metaPtrs - .filter((_, i) => { - return !metadata.value[metadataId(metaPtrs[i])] || metadata.value[metadataId(metaPtrs[i])].status === 'error'; - }) - .reduce((prev, cur) => { - return { - ...prev, - [metadataId(cur)]: { status: 'pending' }, - }; - }, {}); - // when there is new metadata to load... - if (Object.keys(newMetadata).length) { - // save these pending metadata objects to state - metadata.value = { ...metadata.value, ...newMetadata }; - // resolve metadata via metaPtr and update state (no need to wait for resolution) - Object.keys(newMetadata).forEach((id) => getMetadata(decodeMetadataId(id), metadata)); - } - - return metadata; -}; - -/** - * @notice Helper method that fetches and or returns metadata for a Grant or GrantRound, and saves the data - * to the state as soon as it's received - * @param metaPtr metadata pointer object - * @param metadata Ref store's ref to assign resolved metadata to - */ -export const getMetadata = async (metaPtr: MetaPtr, metadata: Ref) => { - assertIPFSPointer(metaPtr); - const id = metadataId(metaPtr); - const fillMetadata = {} as Record; - try { - // save each individual ipfs result into storage - let data = await getStorageKey('ipfs-' + id); - if (!data) { - const url = getMetaPtr({ cid: metaPtr.pointer }); - data = await resolveMetaPtr(url); - await setStorageKey('ipfs-' + id, data as LocalForageData); - } - fillMetadata[id] = { status: 'resolved', ...data }; - } catch (e) { - fillMetadata[id] = { status: 'error' }; - console.error(e); - } - // place the metadata - metadata.value = { ...metadata.value, ...fillMetadata }; - - return metadata.value[id]; -}; diff --git a/app/src/utils/data/metaPtrs.ts b/app/src/utils/data/metaPtrs.ts new file mode 100644 index 00000000..f9c1f824 --- /dev/null +++ b/app/src/utils/data/metaPtrs.ts @@ -0,0 +1,86 @@ +/** + * 1. Functions in this file should allow uploading and fetching MetaPtr's. + * Inside these utility functions, we should detect the protocol, then curry the pointer off to the appropriate method + * to fetch/upload the data for the protocol in question. Currently, the only supported protocols should be 0 + * (return null on fetch, no-op on upload) or 1 for IPFS, which should pull out the CID and pass it to the aforementioned IPFS utils. + * Any other protocol ID should throw. + * + * Questions: + * 1. What is purpose of the class? + * 2. What is the reason for change? + */ + +import { GrantRoundMetadataResolution, MetaPtr } from '@dgrants/types'; +import { assertIPFSPointer, decodeMetadataId, getMetaPtr, metadataId } from 'src/utils/utils'; +import { getStorageKey, setStorageKey } from 'src/utils/data/utils'; +import { LocalForageData } from 'src/types'; +import { Ref } from 'vue'; + +/** + * Resolves a metaPtr via fetch + * @param url URL of metaPtr + * @returns Object + */ +export const resolveMetaPtr = (url: string) => { + return fetch(url).then((res) => res.json()); +}; + +/** + * @notice Helper method that fetches and or returns metadata for a Grant or GrantRound, and saves the data + * to the state as soon as it's received + * @param metaPtr metadata pointer object + * @param metadata Ref store's ref to assign resolved metadata to + */ +export const getMetadata = async (metaPtr: MetaPtr, metadata: Ref) => { + assertIPFSPointer(metaPtr); + const id = metadataId(metaPtr); + const fillMetadata = {} as Record; + try { + // save each individual ipfs result into storage + let data = await getStorageKey('ipfs-' + id); + if (!data) { + const url = getMetaPtr({ cid: metaPtr.pointer }); + data = await resolveMetaPtr(url); + await setStorageKey('ipfs-' + id, data as LocalForageData); + } + fillMetadata[id] = { status: 'resolved', ...data }; + } catch (e) { + fillMetadata[id] = { status: 'error' }; + console.error(e); + } + // place the metadata + metadata.value = { ...metadata.value, ...fillMetadata }; + + return metadata.value[id]; +}; + +/** + * @notice Helper method that fetches metadata for a Grant or GrantRound, and saves the data + * to the state as soon as it's received + * @param metaPtrs Array of IPFS MetaPtrs to resolve + * @param metadata Name of the store's ref to assign resolve metadata to + */ +export const fetchMetaPtrs = async (metaPtrs: MetaPtr[], metadata: Ref) => { + metaPtrs.forEach(assertIPFSPointer); + + // check for any missing entries + const newMetadata = metaPtrs + .filter((_, i) => { + return !metadata.value[metadataId(metaPtrs[i])] || metadata.value[metadataId(metaPtrs[i])].status === 'error'; + }) + .reduce((prev, cur) => { + return { + ...prev, + [metadataId(cur)]: { status: 'pending' }, + }; + }, {}); + // when there is new metadata to load... + if (Object.keys(newMetadata).length) { + // save these pending metadata objects to state + metadata.value = { ...metadata.value, ...newMetadata }; + // resolve metadata via metaPtr and update state (no need to wait for resolution) + Object.keys(newMetadata).forEach((id) => getMetadata(decodeMetadataId(id), metadata)); + } + + return metadata; +}; diff --git a/app/src/utils/utils.ts b/app/src/utils/utils.ts index ab8dae0f..d35bde5a 100644 --- a/app/src/utils/utils.ts +++ b/app/src/utils/utils.ts @@ -17,9 +17,11 @@ import { SUPPORTED_TOKENS_MAPPING, WETH_ADDRESS, } from 'src/utils/chains'; -import { getMetaPtr } from 'src/utils/data/ipfs'; import { Ref } from 'vue'; +// --- Constants --- +const retrievalEndpoint = 'https://scopelift.b-cdn.net/ipfs'; + // --- Formatters --- // Returns an address with the following format: 0x1234…abcd export function formatAddress(address: string) { @@ -478,3 +480,32 @@ Promise => { return await recursiveGraphFetch(url, key, query, fromBlock, [...before, ...json.data[key]]); } }; + +export function assertIPFSPointer(logoPtr: MetaPtr | undefined) { + if (!logoPtr) throw new Error('assertIPFSPointer: logoPtr is undefined'); + const protocol = BigNumber.from(logoPtr.protocol).toString(); + if (!['0', '1'].includes(protocol)) + throw new Error(`assertIPFSPointer: Expected protocol ID of 0 or 1, found ${protocol}`); +} + +/** + * Creates a url for a MetaPtr + * @param obj + * @param obj.cid CID of the grant + * @returns string + */ +export const getMetaPtr = ({ cid }: { cid: string | undefined }) => { + return `${retrievalEndpoint}/${cid}`; +}; + +/** + * Given a CID, formats the metadata pointer for compatibility with the contracts + * @param cid CID of the grant + * @returns string + */ +export const formatMetaPtr = (cid: string): MetaPtr => { + return { + protocol: 1, // IPFS has a protocol ID of 1 + pointer: cid, + }; +}; diff --git a/app/src/views/Contribution.vue b/app/src/views/Contribution.vue index d6d625b8..5b40bfa3 100644 --- a/app/src/views/Contribution.vue +++ b/app/src/views/Contribution.vue @@ -28,7 +28,7 @@ function setTitle(route: string) { function getFullContributionDetails() { if (!userAddress.value || !grantContributions.value || !grants.value || !grantRounds.value) { - return []; + return null; } const grantMeta = grantMetadata.value ? (grantMetadata.value as Record) : undefined; const grantRoundMeta = grantRoundMetadata.value diff --git a/app/src/views/GrantRegistryGrantDetail.vue b/app/src/views/GrantRegistryGrantDetail.vue index 647bab83..99412ce8 100644 --- a/app/src/views/GrantRegistryGrantDetail.vue +++ b/app/src/views/GrantRegistryGrantDetail.vue @@ -97,7 +97,7 @@
-
+
@@ -119,7 +119,7 @@ -
+
@@ -285,7 +285,9 @@ import { LOREM_IPSOM_TEXT, NO_LOGO_OBJECT } from 'src/utils/constants'; import { ContractTransaction } from 'src/utils/ethers'; import { cleanTwitterUrl, + formatMetaPtr, formatNumber, + getMetaPtr, isDefined, isValidAddress, isValidGithub, @@ -540,7 +542,7 @@ function useGrantDetail() { website !== grantMetadata.value?.properties?.websiteURI || github !== grantMetadata.value?.properties?.githubURI || twitter !== cleanTwitterUrl(grantMetadata.value?.properties?.twitterURI) || - logoURI !== ipfs.getMetaPtr({ cid: (grantMetadata.value?.logoPtr as MetaPtr).pointer }); + logoURI !== getMetaPtr({ cid: (grantMetadata.value?.logoPtr as MetaPtr).pointer }); return areFieldsValid && areFieldsUpdated; }); @@ -550,9 +552,7 @@ function useGrantDetail() { if (isLogoValid.value) isUploadingLogo.value = true; form.value.logo = logo && isLogoValid.value ? logo : undefined; try { - form.value.logoURI = logo - ? await ipfs.uploadFile(logo).then((cid) => ipfs.getMetaPtr({ cid: cid.toString() })) - : ''; + form.value.logoURI = logo ? await ipfs.uploadFile(logo).then((cid) => getMetaPtr({ cid: cid.toString() })) : ''; isUploadingLogo.value = false; } catch (err) { isUploadingLogo.value = false; @@ -593,7 +593,7 @@ function useGrantDetail() { const isMetaPtrUpdated = name !== gMetadata?.name || description !== gMetadata?.description || - logoURI !== ipfs.getMetaPtr({ cid: (gMetadata?.logoPtr as MetaPtr).pointer }) || + logoURI !== getMetaPtr({ cid: (gMetadata?.logoPtr as MetaPtr).pointer }) || website !== gMetadata?.properties?.websiteURI || github !== gMetadata?.properties?.githubURI || twitter !== cleanTwitterUrl(gMetadata?.properties?.twitterURI); @@ -609,7 +609,7 @@ function useGrantDetail() { const logoPtr = cid ? ipfs.formatMetaPtr(cid) : NO_LOGO_OBJECT; metaPtr = await ipfs .uploadGrantMetadata({ name, description, logoPtr, properties }) - .then((cid) => ipfs.formatMetaPtr(cid.toString())); + .then((cid) => formatMetaPtr(cid.toString())); } if (owner !== g.owner && payee === g.payee && !isMetaPtrUpdated) { @@ -649,7 +649,7 @@ function useGrantDetail() { form.value.payee = grant.value?.payee || ''; form.value.name = grantMetadata.value?.name || ''; form.value.description = grantMetadata.value?.description || ''; - form.value.logoURI = cid ? ipfs.getMetaPtr({ cid }) : 'placeholder_grant.svg'; + form.value.logoURI = getMetaPtr({ cid }) : 'placeholder_grant.svg' form.value.website = grantMetadata.value?.properties?.websiteURI || ''; form.value.github = grantMetadata.value?.properties?.githubURI || ''; form.value.twitter = cleanTwitterUrl(grantMetadata.value?.properties?.twitterURI) || ''; diff --git a/app/src/views/GrantRegistryNewGrant.vue b/app/src/views/GrantRegistryNewGrant.vue index 41536cf1..8695fd51 100644 --- a/app/src/views/GrantRegistryNewGrant.vue +++ b/app/src/views/GrantRegistryNewGrant.vue @@ -168,7 +168,18 @@ import TransactionStatus from 'src/components/TransactionStatus.vue'; import useWalletStore from 'src/store/wallet'; // --- Methods and Data --- import { LOREM_IPSOM_TEXT, NO_LOGO_OBJECT } from 'src/utils/constants'; -import { isValidAddress, isValidWebsite, isValidGithub, isValidTwitter, isDefined, pushRoute, urlFromTwitterHandle, isValidLogo, watchTransaction } from 'src/utils/utils'; // prettier-ignore +import { + isValidAddress, + isValidWebsite, + isValidGithub, + isValidTwitter, + isDefined, + pushRoute, + urlFromTwitterHandle, + isValidLogo, + watchTransaction, + getMetaPtr, formatMetaPtr +} from 'src/utils/utils'; // prettier-ignore import * as ipfs from 'src/utils/data/ipfs'; function useNewGrant() { @@ -220,9 +231,7 @@ function useNewGrant() { form.value.logo = logo && isLogoValid.value ? logo : undefined; if (isLogoValid.value) isUploadingLogo.value = true; try { - form.value.logoURI = logo - ? await ipfs.uploadFile(logo).then((cid) => ipfs.getMetaPtr({ cid: cid.toString() })) - : ''; + form.value.logoURI = logo ? await ipfs.uploadFile(logo).then((cid) => getMetaPtr({ cid: cid.toString() })) : ''; isUploadingLogo.value = false; } catch (err) { isUploadingLogo.value = false; @@ -245,10 +254,10 @@ function useNewGrant() { const splitLogoURI = (logoURI as string).split('/'); cid = splitLogoURI[splitLogoURI.length - 1]; } - const logoPtr = cid ? ipfs.formatMetaPtr(cid) : NO_LOGO_OBJECT; + const logoPtr = cid ? formatMetaPtr(cid) : NO_LOGO_OBJECT; const metaPtr = await ipfs .uploadGrantMetadata({ name, description, logoPtr, properties }) - .then((cid) => ipfs.formatMetaPtr(cid.toString())); + .then((cid) => formatMetaPtr(cid.toString())); // watch the transaction to check for any replacements/cancellations and update txHash accordingly const tx = await watchTransaction(() => grantRegistry.value.createGrant(owner, payee, metaPtr), txHash); diff --git a/dcurve/src/internal/calc/linear.ts b/dcurve/src/internal/calc/linear.ts index 2b360205..703c3686 100644 --- a/dcurve/src/internal/calc/linear.ts +++ b/dcurve/src/internal/calc/linear.ts @@ -1,7 +1,8 @@ import { CLRArgs, ContributionsByGrantId, GrantMatch, GrantsDistribution, TrustBonusScore } from '../../types'; import { GrantRoundContributions } from '@dgrants/types'; import { fetchTrustBonusScore, uploadTrustBonusScores } from '@dgrants/utils/src/trustBonus'; -import { getMetaPtr, resolveMetaPtr } from '@dgrants/app/src/utils/data/ipfs'; +import { resolveMetaPtr } from '@dgrants/app/src/utils/data/metaPtrs'; +import { getMetaPtr } from '@dgrants/app/src/utils/utils'; /** * @notice Contains the logic to determine the distribution using linear QF formula. From 5b4409d02902ad4b1804031a3d9719812399c6f0 Mon Sep 17 00:00:00 2001 From: git Date: Mon, 6 Dec 2021 12:19:47 -0500 Subject: [PATCH 2/4] reverted some unexpected changes --- app/src/components/GrantDetailsRow.vue | 2 ++ app/src/views/Contribution.vue | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/components/GrantDetailsRow.vue b/app/src/components/GrantDetailsRow.vue index 651a6722..7eb2e0e8 100644 --- a/app/src/components/GrantDetailsRow.vue +++ b/app/src/components/GrantDetailsRow.vue @@ -52,6 +52,8 @@
+ Matching: + {{ round.matching || '...' }} {{ round.matchingToken.symbol }} , {{ round.name }}
diff --git a/app/src/views/Contribution.vue b/app/src/views/Contribution.vue index 5b40bfa3..d6d625b8 100644 --- a/app/src/views/Contribution.vue +++ b/app/src/views/Contribution.vue @@ -28,7 +28,7 @@ function setTitle(route: string) { function getFullContributionDetails() { if (!userAddress.value || !grantContributions.value || !grants.value || !grantRounds.value) { - return null; + return []; } const grantMeta = grantMetadata.value ? (grantMetadata.value as Record) : undefined; const grantRoundMeta = grantRoundMetadata.value From c834a5b4afea034b1ac3987f0877d80b40f2e069 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 14 Dec 2021 11:47:57 -0500 Subject: [PATCH 3/4] propsed adding a constant for supported protocols and a helper function that returns a boolean if it is found or not and added back ternary --- app/src/utils/constants.ts | 3 +++ app/src/utils/utils.ts | 11 ++++++----- app/src/views/GrantRegistryGrantDetail.vue | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/utils/constants.ts b/app/src/utils/constants.ts index bf77bac4..b827bd5d 100644 --- a/app/src/utils/constants.ts +++ b/app/src/utils/constants.ts @@ -44,6 +44,9 @@ export const DefaultForageConfig: LocalForageConfig = { version: 3, }; +// --- Constants --- +export const retrievalEndpoint = 'https://scopelift.b-cdn.net/ipfs'; + // LocalForage keys export const allGrantsKey = 'AllGrants'; export const allGrantRoundsKey = 'AllGrantRounds'; diff --git a/app/src/utils/utils.ts b/app/src/utils/utils.ts index d35bde5a..fdc2f637 100644 --- a/app/src/utils/utils.ts +++ b/app/src/utils/utils.ts @@ -9,7 +9,7 @@ import { BatchFilterQuery, EtherscanGroup } from 'src/types'; import useWalletStore from 'src/store/wallet'; import { Grant, GrantRound, MetaPtr } from '@dgrants/types'; import { formatUnits } from 'src/utils/ethers'; -import { ETH_ADDRESS } from 'src/utils/constants'; +import { ETH_ADDRESS, retrievalEndpoint } from 'src/utils/constants'; import { DEFAULT_PROVIDER, ETHERSCAN_BASE_URL, @@ -19,9 +19,6 @@ import { } from 'src/utils/chains'; import { Ref } from 'vue'; -// --- Constants --- -const retrievalEndpoint = 'https://scopelift.b-cdn.net/ipfs'; - // --- Formatters --- // Returns an address with the following format: 0x1234…abcd export function formatAddress(address: string) { @@ -481,10 +478,14 @@ Promise => { } }; +const supportedProtocols = ['1']; +const isSupportedProtocol = (protocol: string) => supportedProtocols.includes(protocol); + export function assertIPFSPointer(logoPtr: MetaPtr | undefined) { if (!logoPtr) throw new Error('assertIPFSPointer: logoPtr is undefined'); const protocol = BigNumber.from(logoPtr.protocol).toString(); - if (!['0', '1'].includes(protocol)) + + if (!isSupportedProtocol(protocol)) throw new Error(`assertIPFSPointer: Expected protocol ID of 0 or 1, found ${protocol}`); } diff --git a/app/src/views/GrantRegistryGrantDetail.vue b/app/src/views/GrantRegistryGrantDetail.vue index 99412ce8..85c5332c 100644 --- a/app/src/views/GrantRegistryGrantDetail.vue +++ b/app/src/views/GrantRegistryGrantDetail.vue @@ -649,7 +649,7 @@ function useGrantDetail() { form.value.payee = grant.value?.payee || ''; form.value.name = grantMetadata.value?.name || ''; form.value.description = grantMetadata.value?.description || ''; - form.value.logoURI = getMetaPtr({ cid }) : 'placeholder_grant.svg' + form.value.logoURI = cid ? getMetaPtr({ cid }) : 'placeholder_grant.svg'; form.value.website = grantMetadata.value?.properties?.websiteURI || ''; form.value.github = grantMetadata.value?.properties?.githubURI || ''; form.value.twitter = cleanTwitterUrl(grantMetadata.value?.properties?.twitterURI) || ''; From 0eb006aa1c617713ec414f28d9c3878adff5692e Mon Sep 17 00:00:00 2001 From: git Date: Tue, 14 Dec 2021 16:30:45 -0500 Subject: [PATCH 4/4] removed ipfs prefix --- app/src/views/GrantRegistryGrantDetail.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/views/GrantRegistryGrantDetail.vue b/app/src/views/GrantRegistryGrantDetail.vue index 85c5332c..d6b2186d 100644 --- a/app/src/views/GrantRegistryGrantDetail.vue +++ b/app/src/views/GrantRegistryGrantDetail.vue @@ -606,7 +606,7 @@ function useGrantDetail() { const splitLogoURI = (logoURI as string).split('/'); cid = splitLogoURI[splitLogoURI.length - 1]; } - const logoPtr = cid ? ipfs.formatMetaPtr(cid) : NO_LOGO_OBJECT; + const logoPtr = cid ? formatMetaPtr(cid) : NO_LOGO_OBJECT; metaPtr = await ipfs .uploadGrantMetadata({ name, description, logoPtr, properties }) .then((cid) => formatMetaPtr(cid.toString()));