diff --git a/src/routes/safe/components/Apps/components/AppFrame.tsx b/src/routes/safe/components/Apps/components/AppFrame.tsx index 394fc63f..81fe8d71 100644 --- a/src/routes/safe/components/Apps/components/AppFrame.tsx +++ b/src/routes/safe/components/Apps/components/AppFrame.tsx @@ -95,8 +95,9 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { const { isLoading } = useAppList(false) const iframeRef = useRef(null) - const [confirmTransactionModal, setConfirmTransactionModal] = - useState(INITIAL_CONFIRM_TX_MODAL_STATE) + const [confirmTransactionModal, setConfirmTransactionModal] = useState( + INITIAL_CONFIRM_TX_MODAL_STATE, + ) const [appIsLoading, setAppIsLoading] = useState(true) const [safeApp, setSafeApp] = useState() @@ -129,10 +130,9 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { }), [setConfirmTransactionModal], ) - const closeConfirmationModal = useCallback( - () => setConfirmTransactionModal(INITIAL_CONFIRM_TX_MODAL_STATE), - [setConfirmTransactionModal], - ) + const closeConfirmationModal = useCallback(() => setConfirmTransactionModal(INITIAL_CONFIRM_TX_MODAL_STATE), [ + setConfirmTransactionModal, + ]) const { sendMessageToIframe } = useIframeMessageHandler( safeApp, diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index 6f6a9d90..f286f99b 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -212,89 +212,91 @@ export const getEmptySafeApp = (): SafeApp => { } } -export const getAppInfoFromUrl = memoize(async (appUrl: string): Promise => { - let res = { - ...getEmptySafeApp(), - error: true, - loadingStatus: SAFE_APP_FETCH_STATUS.ERROR, - } - - if (!appUrl?.length) { - return res - } - - res.url = appUrl.trim() - const noTrailingSlashUrl = removeLastTrailingSlash(res.url) - - try { - const appInfo = await axios.get(`${noTrailingSlashUrl}/manifest.json`, { timeout: 5_000 }) - - // verify imported app fulfil safe requirements - if (!appInfo?.data || !isAppManifestValid(appInfo.data)) { - throw Error('The app does not fulfil the structure required.') +export const getAppInfoFromUrl = memoize( + async (appUrl: string): Promise => { + let res = { + ...getEmptySafeApp(), + error: true, + loadingStatus: SAFE_APP_FETCH_STATUS.ERROR, } - // the DB origin field has a limit of 100 characters - const originFieldSize = 100 - const jsonDataLength = 20 - const remainingSpace = originFieldSize - res.url.length - jsonDataLength - - const appInfoData = { - name: appInfo.data.name, - iconPath: appInfo.data.iconPath, - description: appInfo.data.description, - providedBy: appInfo.data.providedBy, + if (!appUrl?.length) { + return res } - res = { - ...res, - ...appInfoData, - id: JSON.stringify({ url: res.url, name: appInfo.data.name.substring(0, remainingSpace) }), - error: false, - loadingStatus: SAFE_APP_FETCH_STATUS.SUCCESS, - } + res.url = appUrl.trim() + const noTrailingSlashUrl = removeLastTrailingSlash(res.url) - if (appInfo.data.iconPath) { - try { - const iconInfo = await axios.get(`${noTrailingSlashUrl}/${appInfo.data.iconPath}`, { timeout: 1000 * 10 }) - if (/image\/\w/gm.test(iconInfo.headers['content-type'])) { - res.iconUrl = `${noTrailingSlashUrl}/${appInfo.data.iconPath}` + try { + const appInfo = await axios.get(`${noTrailingSlashUrl}/manifest.json`, { timeout: 5_000 }) + + // verify imported app fulfil safe requirements + if (!appInfo?.data || !isAppManifestValid(appInfo.data)) { + throw Error('The app does not fulfil the structure required.') + } + + // the DB origin field has a limit of 100 characters + const originFieldSize = 100 + const jsonDataLength = 20 + const remainingSpace = originFieldSize - res.url.length - jsonDataLength + + const appInfoData = { + name: appInfo.data.name, + iconPath: appInfo.data.iconPath, + description: appInfo.data.description, + providedBy: appInfo.data.providedBy, + } + + res = { + ...res, + ...appInfoData, + id: JSON.stringify({ url: res.url, name: appInfo.data.name.substring(0, remainingSpace) }), + error: false, + loadingStatus: SAFE_APP_FETCH_STATUS.SUCCESS, + } + + if (appInfo.data.iconPath) { + try { + const iconInfo = await axios.get(`${noTrailingSlashUrl}/${appInfo.data.iconPath}`, { timeout: 1000 * 10 }) + if (/image\/\w/gm.test(iconInfo.headers['content-type'])) { + res.iconUrl = `${noTrailingSlashUrl}/${appInfo.data.iconPath}` + } + } catch (error) { + console.error(`It was not possible to fetch icon from app ${res.url}`) } - } catch (error) { - console.error(`It was not possible to fetch icon from app ${res.url}`) } + return res + } catch (error) { + logError(Errors._900, `${res.url}: ${error.message}`, undefined, false) + return res } - return res - } catch (error) { - logError(Errors._900, `${res.url}: ${error.message}`, undefined, false) - return res - } -}) + }, +) -export const getIpfsLinkFromEns = memoize(async (name: string): Promise => { - try { - const content = await getContentFromENS(name) - if (content && content.protocolType === 'ipfs') { - return `${process.env.REACT_APP_IPFS_GATEWAY}/${content.decoded}/` - } - } catch (error) { - console.error(error) - return - } -}) - -export const uniqueApp = - (appList: SafeApp[]) => - (url: string): string | undefined => { - const newUrl = new URL(url) - const exists = appList.some((a) => { - try { - const currentUrl = new URL(a.url) - return currentUrl.href === newUrl.href - } catch (error) { - console.error('There was a problem trying to validate the URL existence.', error.message) - return false +export const getIpfsLinkFromEns = memoize( + async (name: string): Promise => { + try { + const content = await getContentFromENS(name) + if (content && content.protocolType === 'ipfs') { + return `${process.env.REACT_APP_IPFS_GATEWAY}/${content.decoded}/` } - }) - return exists ? 'This app is already registered.' : undefined - } + } catch (error) { + console.error(error) + return + } + }, +) + +export const uniqueApp = (appList: SafeApp[]) => (url: string): string | undefined => { + const newUrl = new URL(url) + const exists = appList.some((a) => { + try { + const currentUrl = new URL(a.url) + return currentUrl.href === newUrl.href + } catch (error) { + console.error('There was a problem trying to validate the URL existence.', error.message) + return false + } + }) + return exists ? 'This app is already registered.' : undefined +}