From c3e72679892e295ce2f9b52a2c425e1122da4b9a Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:39:41 -0300 Subject: [PATCH] feat: enable uploading `rawMetadata` to the extension (#10780) * first commit * test commit * removed old logging * more cleanup * disabled update metadata button until metadata is available * removed logs * dedupe * updated metadata warning * allow rawMetadata to be falsy on _updateMeta --- .../src/Accounts/BannerExtension.tsx | 4 +-- .../page-settings/src/Metadata/Extensions.tsx | 24 +++++++++++---- packages/page-settings/src/Metadata/index.tsx | 7 ++++- packages/page-settings/src/useRawMetadata.ts | 30 +++++++++++++++++++ 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 packages/page-settings/src/useRawMetadata.ts diff --git a/packages/page-accounts/src/Accounts/BannerExtension.tsx b/packages/page-accounts/src/Accounts/BannerExtension.tsx index a983116b46..3914400eed 100644 --- a/packages/page-accounts/src/Accounts/BannerExtension.tsx +++ b/packages/page-accounts/src/Accounts/BannerExtension.tsx @@ -42,8 +42,8 @@ function BannerExtension (): React.ReactElement | null {

{upgradableCount === 1 - ? t('You have 1 extension that needs to be updated with the latest chain properties in order to display the correct information for the chain you are connected to.') - : t('You have {{upgradableCount}} extensions that need to be updated with the latest chain properties in order to display the correct information for the chain you are connected to.', { replace: { upgradableCount } }) + ? t('You have 1 extension that needs to be updated with the latest chain properties in order to display the correct information for the chain you are connected to and to use a Ledger device.') + : t('You have {{upgradableCount}} extensions that need to be updated with the latest chain properties in order to display the correct information for the chain you are connected to and to use a Ledger device.', { replace: { upgradableCount } }) } {t(' This update includes chain metadata and chain properties.')}

diff --git a/packages/page-settings/src/Metadata/Extensions.tsx b/packages/page-settings/src/Metadata/Extensions.tsx index 4303c0f4aa..d96b474bdc 100644 --- a/packages/page-settings/src/Metadata/Extensions.tsx +++ b/packages/page-settings/src/Metadata/Extensions.tsx @@ -1,14 +1,17 @@ // Copyright 2017-2024 @polkadot/app-settings authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { MetadataDef } from '@polkadot/extension-inject/types'; +import type { HexString } from '@polkadot/util/types'; import type { ChainInfo } from '../types.js'; -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { knownExtensions } from '@polkadot/apps-config'; import { externalEmptySVG } from '@polkadot/apps-config/ui/logos/external'; import { Button, Dropdown, Spinner, styled, Table } from '@polkadot/react-components'; import { useToggle } from '@polkadot/react-hooks'; +import { objectSpread } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import useExtensions from '../useExtensions.js'; @@ -17,13 +20,22 @@ import iconOption from './iconOption.js'; interface Props { chainInfo: ChainInfo | null; className?: string; + rawMetadata: HexString | null; } -function Extensions ({ chainInfo, className }: Props): React.ReactElement { +function Extensions ({ chainInfo, className, rawMetadata }: Props): React.ReactElement { + const isMetadataReady = rawMetadata !== null; + const { t } = useTranslation(); const { extensions } = useExtensions(); const [selectedIndex, setSelectedIndex] = useState(0); - const [isBusy, toggleBusy] = useToggle(); + const [isBusy, toggleBusy] = useToggle(true); + + useEffect((): void => { + if (isMetadataReady) { + toggleBusy(); + } + }, [isMetadataReady, toggleBusy]); const options = useMemo( () => (extensions || []).map(({ extension: { name, version } }, value) => @@ -37,14 +49,16 @@ function Extensions ({ chainInfo, className }: Props): React.ReactElement if (chainInfo && extensions?.[selectedIndex]) { toggleBusy(); + const rawDef: MetadataDef = objectSpread({}, { ...chainInfo, rawMetadata }); + extensions[selectedIndex] - .update(chainInfo) + .update(rawDef) .catch(() => false) .then(() => toggleBusy()) .catch(console.error); } }, - [chainInfo, extensions, selectedIndex, toggleBusy] + [chainInfo, extensions, rawMetadata, selectedIndex, toggleBusy] ); const headerRef = useRef<[React.ReactNode?, string?, number?][]>([ diff --git a/packages/page-settings/src/Metadata/index.tsx b/packages/page-settings/src/Metadata/index.tsx index 953d8d96df..db7602dfbe 100644 --- a/packages/page-settings/src/Metadata/index.tsx +++ b/packages/page-settings/src/Metadata/index.tsx @@ -6,17 +6,22 @@ import React from 'react'; import { useApi } from '@polkadot/react-hooks'; import useChainInfo from '../useChainInfo.js'; +import useRawMetadata from '../useRawMetadata.js'; import Extensions from './Extensions.js'; import NetworkSpecs from './NetworkSpecs.js'; export default function Metadata (): React.ReactElement { const { isDevelopment } = useApi(); + const rawMetadata = useRawMetadata(); const chainInfo = useChainInfo(); return ( <> {!isDevelopment && ( - + )} diff --git a/packages/page-settings/src/useRawMetadata.ts b/packages/page-settings/src/useRawMetadata.ts new file mode 100644 index 0000000000..034174316e --- /dev/null +++ b/packages/page-settings/src/useRawMetadata.ts @@ -0,0 +1,30 @@ +// Copyright 2017-2024 @polkadot/app-settings authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +// import type { RawMetadataDef } from '@polkadot/extension-inject/types'; +import type { HexString } from '@polkadot/util/types'; + +import { useEffect, useState } from 'react'; + +import { createNamedHook, useApi } from '@polkadot/react-hooks'; + +function useRawMetadataImpl (): HexString | null { + const { api, isApiReady } = useApi(); + const [state, setState] = useState(null); + + useEffect( + (): void => { + isApiReady && + api.call.metadata.metadataAtVersion(15).then((opaque) => { + const raw = opaque.toHex(); + + setState(raw); + }).catch(console.error); + }, + [api, isApiReady] + ); + + return state; +} + +export default createNamedHook('useRawMetadata', useRawMetadataImpl);