Skip to content

Commit f834902

Browse files
committed
feat: add loading state and validation for metadata updates in dot-update-metadata component
1 parent 3d3c1b1 commit f834902

1 file changed

Lines changed: 52 additions & 1 deletion

File tree

packages/extension/src/providers/polkadot/ui/dot-update-metadata.vue

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@
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';
7983
import MetadataStorage from '@/providers/polkadot/libs/metadata-storage';
8084
import { ProviderRequestOptions } from '@/types/provider';
8185
import networks from '../networks';
86+
import { getAllNetworks } from '@/libs/utils/networks';
87+
import { SubstrateNetwork } from '../types/substrate-network';
88+
import { ApiPromise } from '@polkadot/api';
8289
8390
const windowPromise = WindowPromiseHandler(0);
8491
@@ -92,6 +99,7 @@ const Options = ref<ProviderRequestOptions>({
9299
tabId: 0,
93100
});
94101
const metadata = ref<MetadataDef | null>(null);
102+
const isLoading = ref(false);
95103
96104
onBeforeMount(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+
119159
const 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
};
138189
const deny = async () => {

0 commit comments

Comments
 (0)