6363 </template >
6464
6565 <template #button-right >
66- <base-button title =" Update" :click =" approve" />
66+ <base-button
67+ :title =" isLoading ? 'Loading...' : 'Update'"
68+ :click =" approve"
69+ :disabled =" isLoading"
70+ />
6771 </template >
6872 </common-popup >
6973</template >
@@ -79,6 +83,9 @@ import { MetadataDef } from '@polkadot/extension-inject/types';
7983import MetadataStorage from ' @/providers/polkadot/libs/metadata-storage' ;
8084import { ProviderRequestOptions } from ' @/types/provider' ;
8185import networks from ' ../networks' ;
86+ import { getAllNetworks } from ' @/libs/utils/networks' ;
87+ import { SubstrateNetwork } from ' ../types/substrate-network' ;
88+ import { ApiPromise } from ' @polkadot/api' ;
8289
8390const windowPromise = WindowPromiseHandler (0 );
8491
@@ -92,6 +99,7 @@ const Options = ref<ProviderRequestOptions>({
9299 tabId: 0 ,
93100});
94101const metadata = ref <MetadataDef | null >(null );
102+ const isLoading = ref (false );
95103
96104onBeforeMount (async () => {
97105 const { options, Request } = await windowPromise ;
@@ -116,6 +124,38 @@ watch(metadata, () => {
116124 }
117125});
118126
127+ const validateMetadataAgainstApi = async (
128+ meta : MetadataDef ,
129+ ): Promise <string | null > => {
130+ const allNetworks = await getAllNetworks ();
131+ const targetNetwork = allNetworks .find (
132+ network => (network as SubstrateNetwork ).genesisHash === meta .genesisHash ,
133+ );
134+ if (! targetNetwork ) {
135+ return null ;
136+ }
137+ try {
138+ const api = (await targetNetwork .api ()).api as ApiPromise ;
139+ const onChainGenesisHash = api .genesisHash .toHex ();
140+ if (onChainGenesisHash !== meta .genesisHash ) {
141+ return ` Genesis hash mismatch: expected ${onChainGenesisHash }, got ${meta .genesisHash } ` ;
142+ }
143+ const onChainSpecVersion = api .runtimeVersion .specVersion .toNumber ();
144+ if (meta .specVersion < onChainSpecVersion ) {
145+ return ` Provided specVersion (${meta .specVersion }) is older than on-chain version (${onChainSpecVersion }) ` ;
146+ }
147+ if (
148+ meta .tokenDecimals !== undefined &&
149+ meta .tokenDecimals !== targetNetwork .decimals
150+ ) {
151+ return ` Token decimals mismatch: expected ${targetNetwork .decimals }, got ${meta .tokenDecimals } ` ;
152+ }
153+ } catch {
154+ return ' Failed to connect to the network API for validation' ;
155+ }
156+ return null ;
157+ };
158+
119159const approve = async () => {
120160 const { Resolve, Request } = await windowPromise ;
121161 if (
@@ -127,12 +167,23 @@ const approve = async () => {
127167 return Resolve .value ({ error: getCustomError (' No params' ) });
128168 }
129169
170+ isLoading .value = true ;
171+
172+ const validationError = await validateMetadataAgainstApi (metadata .value );
173+ if (validationError ) {
174+ isLoading .value = false ;
175+ return Resolve .value ({ error: getCustomError (validationError ) });
176+ }
177+
130178 mstorage
131179 .addMetadata (metadata .value .genesisHash , JSON .stringify (metadata .value ))
132180 .then (() => {
133181 Resolve .value ({
134182 result: JSON .stringify (true ),
135183 });
184+ })
185+ .finally (() => {
186+ isLoading .value = false ;
136187 });
137188};
138189const deny = async () => {
0 commit comments