Repository: polkadot-js/api
Pull request #6130: Metadata v16
Author: login: valentinfernandez1
Created: 2025-04-17T18:20:50Z | Merged: 2025-05-16T12:06:40Z

This PR adds support for Substrate Metadata V16. The main structure and conversion logic are in place, so the core of the feature is done.

There are still a few things to clean up and polish on the edges, so I’m opening this as a Draft to track progress and get early feedback.


Diff:
diff --git a/packages/api/src/base/Decorate.ts b/packages/api/src/base/Decorate.ts
index 121d020146f..0cf91303b5a 100644
--- a/packages/api/src/base/Decorate.ts
+++ b/packages/api/src/base/Decorate.ts
@@ -5,7 +5,7 @@ import type { Observable } from 'rxjs';
 import type { AugmentedCall, DeriveCustom, QueryableCalls } from '@polkadot/api-base/types';
 import type { RpcInterface } from '@polkadot/rpc-core/types';
 import type { Metadata, StorageKey, Text, u64, Vec } from '@polkadot/types';
-import type { Call, Hash, RuntimeApiMethodMetadataV15, RuntimeVersion } from '@polkadot/types/interfaces';
+import type { Call, Hash, RuntimeApiMethodMetadataV16, RuntimeVersion } from '@polkadot/types/interfaces';
 import type { DecoratedMeta } from '@polkadot/types/metadata/decorate/types';
 import type { StorageEntry } from '@polkadot/types/primitive/types';
 import type { AnyFunction, AnyJson, AnyTuple, CallFunction, Codec, DefinitionCall, DefinitionCallNamed, DefinitionRpc, DefinitionRpcSub, DefinitionsCall, DefinitionsCallEntry, DetectCodec, IMethod, IStorageKey, Registry, RegistryError, RegistryTypes } from '@polkadot/types/types';
@@ -494,7 +494,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
   }
 
   // Helper for _getRuntimeDefsViaMetadata
-  protected _getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV15>) {
+  protected _getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV16>) {
     const result: Record<string, DefinitionCall> = {};
 
     methods.forEach((m) => {
diff --git a/packages/api/src/base/Init.ts b/packages/api/src/base/Init.ts
index 2b177a4428f..c0d9a8e2aaa 100644
--- a/packages/api/src/base/Init.ts
+++ b/packages/api/src/base/Init.ts
@@ -14,6 +14,7 @@ import type { VersionedRegistry } from './types.js';
 import { firstValueFrom, map, of, switchMap } from 'rxjs';
 
 import { Metadata, TypeRegistry } from '@polkadot/types';
+import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/extrinsic/constants';
 import { getSpecAlias, getSpecExtensions, getSpecHasher, getSpecRpc, getSpecTypes, getUpgradeVersion } from '@polkadot/types-known';
 import { assertReturn, BN_ZERO, isUndefined, logger, noop, objectSpread, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
 import { blake2AsHex, cryptoWaitReady } from '@polkadot/util-crypto';
@@ -22,7 +23,8 @@ import { Decorate } from './Decorate.js';
 
 const KEEPALIVE_INTERVAL = 10000;
 const WITH_VERSION_SHORTCUT = false;
-const SUPPORTED_METADATA_VERSIONS = [15, 14];
+
+const SUPPORTED_METADATA_VERSIONS = [16, 15, 14];
 
 const l = logger('api/init');
 
@@ -371,7 +373,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
       throw new Error('Invalid initializion order, runtimeVersion is not available');
     }
 
-    this._extrinsicType = metadata.asLatest.extrinsic.version.toNumber();
+    this._extrinsicType = metadata.asLatest.extrinsic.versions.at(-1) || LATEST_EXTRINSIC_VERSION;
     this._rx.extrinsicType = this._extrinsicType;
     this._rx.genesisHash = this._genesisHash;
     this._rx.runtimeVersion = runtimeVersion;
diff --git a/packages/typegen/src/generate/consts.ts b/packages/typegen/src/generate/consts.ts
index 89e7ba3dc07..45fb311f9a9 100644
--- a/packages/typegen/src/generate/consts.ts
+++ b/packages/typegen/src/generate/consts.ts
@@ -4,7 +4,6 @@
 import type { Metadata } from '@polkadot/types/metadata/Metadata';
 import type { Definitions } from '@polkadot/types/types';
 import type { HexString } from '@polkadot/util/types';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
@@ -14,6 +13,7 @@ import { stringCamelCase } from '@polkadot/util';
 
 import { compareName, createImports, formatType, initMeta, readTemplate, setImports, writeFile } from '../util/index.js';
 import { ignoreUnusedLookups } from './lookup.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 const generateForMetaTemplate = Handlebars.compile(readTemplate('consts'));
 
@@ -45,10 +45,20 @@ function generateForMeta (meta: Metadata, dest: string, extraTypes: ExtraTypes,
         }
 
         const items = constants
-          .map(({ docs, name, type }) => {
+          .map(({ deprecationInfo, docs, name, type }) => {
             const typeDef = lookup.getTypeDef(type);
             const returnType = typeDef.lookupName || formatType(registry, allDefs, typeDef, imports);
 
+            if (!deprecationInfo.isNotDeprecated) {
+              const deprecationNotice = getDeprecationNotice(deprecationInfo, stringCamelCase(name), 'Constant');
+
+              const items = docs.length
+                ? ['', deprecationNotice]
+                : [deprecationNotice];
+
+              docs.push(...items.map((text) => registry.createType('Text', text)));
+            }
+
             // Add the type to the list of used types
             if (!(imports.primitiveTypes[returnType])) {
               usedTypes.add(returnType);
diff --git a/packages/typegen/src/generate/errors.ts b/packages/typegen/src/generate/errors.ts
index 2b339cf0fb4..95b23372817 100644
--- a/packages/typegen/src/generate/errors.ts
+++ b/packages/typegen/src/generate/errors.ts
@@ -1,15 +1,16 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
+import type { VariantDeprecationInfoV16 } from '@polkadot/types/interfaces';
 import type { Metadata } from '@polkadot/types/metadata/Metadata';
 import type { HexString } from '@polkadot/util/types';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
 import { stringCamelCase } from '@polkadot/util';
 
 import { compareName, createImports, initMeta, readTemplate, writeFile } from '../util/index.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 const generateForMetaTemplate = Handlebars.compile(readTemplate('errors'));
 
@@ -20,15 +21,34 @@ function generateForMeta (meta: Metadata, dest: string, isStrict: boolean): void
     const { lookup, pallets } = meta.asLatest;
     const modules = pallets
       .filter(({ errors }) => errors.isSome)
-      .map(({ errors, name }) => ({
-        items: lookup.getSiType(errors.unwrap().type).def.asVariant.variants
-          .map(({ docs, name }) => ({
-            docs,
-            name: name.toString()
-          }))
-          .sort(compareName),
-        name: stringCamelCase(name)
-      }))
+      .map((data) => {
+        const name = data.name;
+        const errors = data.errors.unwrap();
+        const deprecationInfo = errors.deprecationInfo.toJSON();
+
+        return {
+          items: lookup.getSiType(errors.type).def.asVariant.variants
+            .map(({ docs, index, name }) => {
+              const rawStatus = deprecationInfo?.[index.toNumber()];
+
+              if (rawStatus) {
+                const deprecationVariantInfo: VariantDeprecationInfoV16 = meta.registry.createTypeUnsafe('VariantDeprecationInfoV16', [rawStatus]);
+
+                const deprecationNotice = getDeprecationNotice(deprecationVariantInfo, name.toString());
+                const notice = docs.length ? ['', deprecationNotice] : [deprecationNotice];
+
+                docs.push(...notice.map((text) => meta.registry.createType('Text', text)));
+              }
+
+              return {
+                docs,
+                name: name.toString()
+              };
+            })
+            .sort(compareName),
+          name: stringCamelCase(name)
+        };
+      })
       .sort(compareName);
 
     return generateForMetaTemplate({
diff --git a/packages/typegen/src/generate/events.ts b/packages/typegen/src/generate/events.ts
index f292c7a8628..e877bd44654 100644
--- a/packages/typegen/src/generate/events.ts
+++ b/packages/typegen/src/generate/events.ts
@@ -1,10 +1,10 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
+import type { VariantDeprecationInfoV16 } from '@polkadot/types/interfaces';
 import type { Metadata } from '@polkadot/types/metadata/Metadata';
 import type { Definitions } from '@polkadot/types/types';
 import type { HexString } from '@polkadot/util/types';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
@@ -14,6 +14,7 @@ import { stringCamelCase } from '@polkadot/util';
 
 import { compareName, createImports, formatType, initMeta, readTemplate, setImports, writeFile } from '../util/index.js';
 import { ignoreUnusedLookups } from './lookup.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 const generateForMetaTemplate = Handlebars.compile(readTemplate('events'));
 
@@ -82,39 +83,55 @@ function generateForMeta (meta: Metadata, dest: string, extraTypes: ExtraTypes,
     const usedTypes = new Set<string>([]);
     const modules = pallets
       .filter(({ events }) => events.isSome)
-      .map(({ events, name }) => ({
-        items: lookup.getSiType(events.unwrap().type).def.asVariant.variants
-          .map(({ docs, fields, name }) => {
-            const args = fields
-              .map(({ type }) => lookup.getTypeDef(type))
-              .map((typeDef) => {
-                const arg = typeDef.lookupName || formatType(registry, allDefs, typeDef, imports);
-
-                // Add the type to the list of used types
-                if (!(imports.primitiveTypes[arg])) {
-                  usedTypes.add(arg);
-                }
-
-                return arg;
-              });
-
-            const names = fields
-              .map(({ name }) => registry.lookup.sanitizeField(name)[0])
-              .filter((n): n is string => !!n);
-
-            setImports(allDefs, imports, args);
-
-            return {
-              docs,
-              name: name.toString(),
-              type: names.length !== 0 && names.length === args.length
-                ? `[${names.map((n, i) => `${ALIAS.includes(n) ? `${n}_` : n}: ${args[i]}`).join(', ')}], { ${names.map((n, i) => `${n}: ${args[i]}`).join(', ')} }`
-                : `[${args.join(', ')}]`
-            };
-          })
-          .sort(compareName),
-        name: stringCamelCase(name)
-      }))
+      .map((data) => {
+        const name = data.name;
+        const events = data.events.unwrap();
+        const deprecationInfo = events.deprecationInfo.toJSON();
+
+        return {
+          items: lookup.getSiType(events.type).def.asVariant.variants
+            .map(({ docs, fields, index, name }) => {
+              const rawStatus = deprecationInfo?.[index.toNumber()];
+
+              if (rawStatus) {
+                const deprecationVariantInfo: VariantDeprecationInfoV16 = meta.registry.createTypeUnsafe('VariantDeprecationInfoV16', [rawStatus]);
+                const deprecationNotice = getDeprecationNotice(deprecationVariantInfo, name.toString());
+                const notice = docs.length ? ['', deprecationNotice] : [deprecationNotice];
+
+                docs.push(...notice.map((text) => meta.registry.createType('Text', text)));
+              }
+
+              const args = fields
+                .map(({ type }) => lookup.getTypeDef(type))
+                .map((typeDef) => {
+                  const arg = typeDef.lookupName || formatType(registry, allDefs, typeDef, imports);
+
+                  // Add the type to the list of used types
+                  if (!(imports.primitiveTypes[arg])) {
+                    usedTypes.add(arg);
+                  }
+
+                  return arg;
+                });
+
+              const names = fields
+                .map(({ name }) => registry.lookup.sanitizeField(name)[0])
+                .filter((n): n is string => !!n);
+
+              setImports(allDefs, imports, args);
+
+              return {
+                docs,
+                name: name.toString(),
+                type: names.length !== 0 && names.length === args.length
+                  ? `[${names.map((n, i) => `${ALIAS.includes(n) ? `${n}_` : n}: ${args[i]}`).join(', ')}], { ${names.map((n, i) => `${n}: ${args[i]}`).join(', ')} }`
+                  : `[${args.join(', ')}]`
+              };
+            })
+            .sort(compareName),
+          name: stringCamelCase(name)
+        };
+      })
       .sort(compareName);
 
     // filter out the unused lookup types from imports
diff --git a/packages/typegen/src/generate/query.ts b/packages/typegen/src/generate/query.ts
index eee498dd776..583530859bc 100644
--- a/packages/typegen/src/generate/query.ts
+++ b/packages/typegen/src/generate/query.ts
@@ -6,7 +6,6 @@ import type { Metadata, PortableRegistry } from '@polkadot/types/metadata';
 import type { Definitions, Registry } from '@polkadot/types/types';
 import type { HexString } from '@polkadot/util/types';
 import type { ModuleTypes, TypeImports } from '../util/imports.js';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
@@ -17,6 +16,7 @@ import { stringCamelCase } from '@polkadot/util';
 
 import { compareName, createImports, formatType, getSimilarTypes, initMeta, readTemplate, setImports, writeFile } from '../util/index.js';
 import { ignoreUnusedLookups } from './lookup.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 const generateForMetaTemplate = Handlebars.compile(readTemplate('query'));
 
@@ -93,8 +93,18 @@ function generateForMeta (registry: Registry, meta: Metadata, dest: string, extr
       .map(({ name, storage }) => {
         const items = storage.unwrap().items
           .map((storageEntry) => {
+            const { deprecationInfo, docs, name } = storageEntry;
             const [isOptional, args, params, _returnType] = entrySignature(lookup, allDefs, registry, name.toString(), storageEntry, imports);
 
+            if (!deprecationInfo.isNotDeprecated) {
+              const deprecationNotice = getDeprecationNotice(deprecationInfo, stringCamelCase(name));
+              const items = docs.length
+                ? ['', deprecationNotice]
+                : [deprecationNotice];
+
+              docs.push(...items.map((text) => registry.createType('Text', text)));
+            }
+
             // Add the type and args to the list of used types
             if (!(imports.primitiveTypes[_returnType])) {
               usedTypes.add(_returnType);
@@ -110,7 +120,7 @@ function generateForMeta (registry: Registry, meta: Metadata, dest: string, extr
 
             return {
               args,
-              docs: storageEntry.docs,
+              docs,
               entryType: 'AugmentedQuery',
               name: stringCamelCase(storageEntry.name),
               params,
diff --git a/packages/typegen/src/generate/runtime.ts b/packages/typegen/src/generate/runtime.ts
index 641a22d9184..e6e89fad38b 100644
--- a/packages/typegen/src/generate/runtime.ts
+++ b/packages/typegen/src/generate/runtime.ts
@@ -1,12 +1,11 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
-import type { RuntimeApiMethodMetadataV15, SiLookupTypeId } from '@polkadot/types/interfaces';
+import type { RuntimeApiMethodMetadataV16, SiLookupTypeId } from '@polkadot/types/interfaces';
 import type { Metadata } from '@polkadot/types/metadata/Metadata';
 import type { DefinitionCall, DefinitionCallNamed, Definitions, DefinitionsCall, Registry } from '@polkadot/types/types';
 import type { Vec } from '@polkadot/types-codec';
 import type { HexString } from '@polkadot/util/types';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
@@ -16,6 +15,7 @@ import { objectSpread, stringCamelCase } from '@polkadot/util';
 import { blake2AsHex } from '@polkadot/util-crypto';
 
 import { createImports, formatType, getSimilarTypes, initMeta, readTemplate, setImports, writeFile } from '../util/index.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 type Apis = [HexString, number][];
 
@@ -52,14 +52,22 @@ const getTypesViaAlias = (registry: Registry, id: SiLookupTypeId) => {
 };
 
 /** @internal */
-function getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV15>) {
+function getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV16>) {
   const result: Record<string, DefinitionCall> = {};
 
   methods.forEach((m) => {
-    const { docs, inputs, name, output } = m;
+    const { deprecationInfo, docs, inputs, name, output } = m;
+    let description = docs.map((d) => d.toString()).join();
+
+    if (!deprecationInfo.isNotDeprecated) {
+      const deprecationNotice = getDeprecationNotice(deprecationInfo, stringCamelCase(name));
+      const notice = description.length ? `\n * ${deprecationNotice}` : ` * ${deprecationNotice}`;
+
+      description += notice;
+    }
 
     result[name.toString()] = {
-      description: docs.map((d) => d.toString()).join(),
+      description,
       params: inputs.map(({ name, type }) => {
         return { name: name.toString(), type: getTypesViaAlias(registry, type) };
       }),
diff --git a/packages/typegen/src/generate/tx.ts b/packages/typegen/src/generate/tx.ts
index 00a123c1412..6f48b9cf24f 100644
--- a/packages/typegen/src/generate/tx.ts
+++ b/packages/typegen/src/generate/tx.ts
@@ -1,11 +1,11 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
+import type { VariantDeprecationInfoV16 } from '@polkadot/types/interfaces';
 import type { Metadata } from '@polkadot/types/metadata/Metadata';
 import type { Text } from '@polkadot/types/primitive';
 import type { Definitions, Registry } from '@polkadot/types/types';
 import type { HexString } from '@polkadot/util/types';
-import type { ExtraTypes } from './types.js';
 
 import Handlebars from 'handlebars';
 
@@ -15,6 +15,7 @@ import { stringCamelCase } from '@polkadot/util';
 
 import { compareName, createImports, formatType, getSimilarTypes, initMeta, readTemplate, setImports, writeFile } from '../util/index.js';
 import { ignoreUnusedLookups } from './lookup.js';
+import { type ExtraTypes, getDeprecationNotice } from './types.js';
 
 const MAPPED_NAMES: Record<string, string> = {
   class: 'clazz',
@@ -51,12 +52,26 @@ function generateForMeta (registry: Registry, meta: Metadata, dest: string, extr
     const modules = pallets
       .sort(compareName)
       .filter(({ calls }) => calls.isSome)
-      .map(({ calls, name }) => {
+      .map((data) => {
+        const name = data.name;
+        const calls = data.calls.unwrap();
+        const deprecationInfo = calls.deprecationInfo.toJSON();
+
         setImports(allDefs, imports, ['SubmittableExtrinsic']);
 
         const sectionName = stringCamelCase(name);
-        const items = lookup.getSiType(calls.unwrap().type).def.asVariant.variants
-          .map(({ docs, fields, name }) => {
+        const items = lookup.getSiType(calls.type).def.asVariant.variants
+          .map(({ docs, fields, index, name }) => {
+            const rawStatus = deprecationInfo?.[index.toNumber()];
+
+            if (rawStatus) {
+              const deprecationVariantInfo: VariantDeprecationInfoV16 = meta.registry.createTypeUnsafe('VariantDeprecationInfoV16', [rawStatus]);
+              const deprecationNotice = getDeprecationNotice(deprecationVariantInfo, name.toString(), 'Call');
+              const notice = docs.length ? ['', deprecationNotice] : [deprecationNotice];
+
+              docs.push(...notice.map((text) => meta.registry.createType('Text', text)));
+            }
+
             const typesInfo = fields.map(({ name, type, typeName }, index): [string, string, string] => {
               const typeDef = registry.lookup.getTypeDef(type);
 
@@ -72,6 +87,7 @@ function generateForMeta (registry: Registry, meta: Metadata, dest: string, extr
                   : typeDef.lookupName || typeDef.type
               ];
             });
+
             const params = typesInfo
               .map(([name,, typeStr]) => {
                 const similarTypes = getSimilarTypes(registry, allDefs, typeStr, imports);
diff --git a/packages/typegen/src/generate/types.ts b/packages/typegen/src/generate/types.ts
index bec6b415aed..30ebe5abafd 100644
--- a/packages/typegen/src/generate/types.ts
+++ b/packages/typegen/src/generate/types.ts
@@ -1,7 +1,26 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
+import type { Option, Text } from '@polkadot/types-codec';
+
 export type ExtraTypes = Record<string, Record<string, {
   runtime?: Record<string, any>;
   types: Record<string, any>;
 }>>;
+
+export function getDeprecationNotice<T extends { isDeprecated: boolean; asDeprecated: { note: Text; since: Option<Text> }}> (deprecationInfo: T, name: string, label?: string): string {
+  let deprecationNotice = '@deprecated';
+
+  if (deprecationInfo.isDeprecated) {
+    const { note, since } = deprecationInfo.asDeprecated;
+    const sinceText = since.isSome ? ` Since ${since.unwrap().toString()}.` : '';
+
+    deprecationNotice += ` ${note.toString()}${sinceText}`;
+  } else {
+    const labelText = label ? `${label} ` : '';
+
+    deprecationNotice += ` ${labelText}${name} has been deprecated`;
+  }
+
+  return deprecationNotice;
+}
diff --git a/packages/typegen/src/interfacesTs.ts b/packages/typegen/src/interfacesTs.ts
index 7e0ce59d445..242a1cd55a5 100644
--- a/packages/typegen/src/interfacesTs.ts
+++ b/packages/typegen/src/interfacesTs.ts
@@ -3,6 +3,7 @@
 
 import type { HexString } from '@polkadot/util/types';
 
+// TODO: replace v15 to v16 once metadata is updated
 import kusama from '@polkadot/types-support/metadata/v15/kusama-hex';
 import polkadot from '@polkadot/types-support/metadata/v15/polkadot-hex';
 import substrate from '@polkadot/types-support/metadata/v15/substrate-hex';
diff --git a/packages/typegen/src/metadataMd.ts b/packages/typegen/src/metadataMd.ts
index bfaf1a9779e..2fdccd247a8 100644
--- a/packages/typegen/src/metadataMd.ts
+++ b/packages/typegen/src/metadataMd.ts
@@ -1,7 +1,7 @@
 // Copyright 2017-2025 @polkadot/typegen authors & contributors
 // SPDX-License-Identifier: Apache-2.0
 
-import type { MetadataLatest, RuntimeApiMethodMetadataV15, SiLookupTypeId } from '@polkadot/types/interfaces';
+import type { MetadataLatest, RuntimeApiMethodMetadataV16, SiLookupTypeId } from '@polkadot/types/interfaces';
 import type { PortableRegistry } from '@polkadot/types/metadata';
 import type { Text } from '@polkadot/types/primitive';
 import type { Codec, DefinitionCall, DefinitionRpcParam, DefinitionsCall, Registry } from '@polkadot/types/types';
@@ -255,7 +255,7 @@ function addRpc (_runtimeDesc: string, rpcMethods?: string[]): string {
 }
 
 /** @internal */
-function getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV15>) {
+function getMethods (registry: Registry, methods: Vec<RuntimeApiMethodMetadataV16>) {
   const result: Record<string, DefinitionCall> = {};
 
   methods.forEach((m) => {
@@ -614,7 +614,7 @@ function extractDeriveExample (tags: Spec[]) {
   let example = '';
   const inCodeBlock = { done: false, found: false };
 
-  // / Obtain code block from example tag.
+  // Obtain code block from example tag.
   exampleTag.source.forEach((line) => {
     if (inCodeBlock.done) {
       return;
diff --git a/packages/types-augment/src/registry/interfaces.ts b/packages/types-augment/src/registry/interfaces.ts
index e6f512ed5a4..b10ac75fc0d 100644
--- a/packages/types-augment/src/registry/interfaces.ts
+++ b/packages/types-augment/src/registry/interfaces.ts
@@ -44,7 +44,7 @@ import type { AuthorityIndex, AuthorityList, AuthoritySet, AuthoritySetChange, A
 import type { IdentityFields, IdentityInfo, IdentityInfoAdditional, IdentityInfoTo198, IdentityJudgement, RegistrarIndex, RegistrarInfo, Registration, RegistrationJudgement, RegistrationTo198 } from '@polkadot/types/interfaces/identity';
 import type { AuthIndex, AuthoritySignature, Heartbeat, HeartbeatTo244, OpaqueMultiaddr, OpaqueNetworkState, OpaquePeerId } from '@polkadot/types/interfaces/imOnline';
 import type { CallIndex, LotteryConfig } from '@polkadot/types/interfaces/lottery';
-import type { CustomMetadata15, CustomValueMetadata15, ErrorMetadataLatest, ErrorMetadataV10, ErrorMetadataV11, ErrorMetadataV12, ErrorMetadataV13, ErrorMetadataV14, ErrorMetadataV9, EventMetadataLatest, EventMetadataV10, EventMetadataV11, EventMetadataV12, EventMetadataV13, EventMetadataV14, EventMetadataV9, ExtrinsicMetadataLatest, ExtrinsicMetadataV11, ExtrinsicMetadataV12, ExtrinsicMetadataV13, ExtrinsicMetadataV14, ExtrinsicMetadataV15, FunctionArgumentMetadataLatest, FunctionArgumentMetadataV10, FunctionArgumentMetadataV11, FunctionArgumentMetadataV12, FunctionArgumentMetadataV13, FunctionArgumentMetadataV14, FunctionArgumentMetadataV9, FunctionMetadataLatest, FunctionMetadataV10, FunctionMetadataV11, FunctionMetadataV12, FunctionMetadataV13, FunctionMetadataV14, FunctionMetadataV9, MetadataAll, MetadataLatest, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15, MetadataV9, ModuleConstantMetadataV10, ModuleConstantMetadataV11, ModuleConstantMetadataV12, ModuleConstantMetadataV13, ModuleConstantMetadataV9, ModuleMetadataV10, ModuleMetadataV11, ModuleMetadataV12, ModuleMetadataV13, ModuleMetadataV9, OpaqueMetadata, OuterEnums15, PalletCallMetadataLatest, PalletCallMetadataV14, PalletConstantMetadataLatest, PalletConstantMetadataV14, PalletErrorMetadataLatest, PalletErrorMetadataV14, PalletEventMetadataLatest, PalletEventMetadataV14, PalletMetadataLatest, PalletMetadataV14, PalletMetadataV15, PalletStorageMetadataLatest, PalletStorageMetadataV14, PortableType, PortableTypeV14, RuntimeApiMetadataLatest, RuntimeApiMetadataV15, RuntimeApiMethodMetadataV15, RuntimeApiMethodParamMetadataV15, SignedExtensionMetadataLatest, SignedExtensionMetadataV14, StorageEntryMetadataLatest, StorageEntryMetadataV10, StorageEntryMetadataV11, StorageEntryMetadataV12, StorageEntryMetadataV13, StorageEntryMetadataV14, StorageEntryMetadataV9, StorageEntryModifierLatest, StorageEntryModifierV10, StorageEntryModifierV11, StorageEntryModifierV12, StorageEntryModifierV13, StorageEntryModifierV14, StorageEntryModifierV9, StorageEntryTypeLatest, StorageEntryTypeV10, StorageEntryTypeV11, StorageEntryTypeV12, StorageEntryTypeV13, StorageEntryTypeV14, StorageEntryTypeV9, StorageHasher, StorageHasherV10, StorageHasherV11, StorageHasherV12, StorageHasherV13, StorageHasherV14, StorageHasherV9, StorageMetadataV10, StorageMetadataV11, StorageMetadataV12, StorageMetadataV13, StorageMetadataV9 } from '@polkadot/types/interfaces/metadata';
+import type { CustomMetadata15, CustomValueMetadata15, EnumDeprecationInfoV16, ErrorMetadataLatest, ErrorMetadataV10, ErrorMetadataV11, ErrorMetadataV12, ErrorMetadataV13, ErrorMetadataV14, ErrorMetadataV9, EventMetadataLatest, EventMetadataV10, EventMetadataV11, EventMetadataV12, EventMetadataV13, EventMetadataV14, EventMetadataV9, ExtrinsicMetadataLatest, ExtrinsicMetadataV11, ExtrinsicMetadataV12, ExtrinsicMetadataV13, ExtrinsicMetadataV14, ExtrinsicMetadataV15, ExtrinsicMetadataV16, FunctionArgumentMetadataLatest, FunctionArgumentMetadataV10, FunctionArgumentMetadataV11, FunctionArgumentMetadataV12, FunctionArgumentMetadataV13, FunctionArgumentMetadataV14, FunctionArgumentMetadataV9, FunctionMetadataLatest, FunctionMetadataV10, FunctionMetadataV11, FunctionMetadataV12, FunctionMetadataV13, FunctionMetadataV14, FunctionMetadataV9, ItemDeprecationInfoV16, MetadataAll, MetadataLatest, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15, MetadataV16, MetadataV9, ModuleConstantMetadataV10, ModuleConstantMetadataV11, ModuleConstantMetadataV12, ModuleConstantMetadataV13, ModuleConstantMetadataV9, ModuleMetadataV10, ModuleMetadataV11, ModuleMetadataV12, ModuleMetadataV13, ModuleMetadataV9, OpaqueMetadata, OuterEnums15, PalletAssociatedTypeMetadataV16, PalletCallMetadataLatest, PalletCallMetadataV14, PalletCallMetadataV16, PalletConstantMetadataLatest, PalletConstantMetadataV14, PalletConstantMetadataV16, PalletErrorMetadataLatest, PalletErrorMetadataV14, PalletErrorMetadataV16, PalletEventMetadataLatest, PalletEventMetadataV14, PalletEventMetadataV16, PalletMetadataLatest, PalletMetadataV14, PalletMetadataV15, PalletMetadataV16, PalletStorageMetadataLatest, PalletStorageMetadataV14, PalletStorageMetadataV16, PalletViewFunctionMetadataV16, PortableType, PortableTypeV14, RuntimeApiMetadataLatest, RuntimeApiMetadataV15, RuntimeApiMetadataV16, RuntimeApiMethodMetadataV15, RuntimeApiMethodMetadataV16, RuntimeApiMethodParamMetadataV15, SignedExtensionMetadataLatest, SignedExtensionMetadataV14, StorageEntryMetadataLatest, StorageEntryMetadataV10, StorageEntryMetadataV11, StorageEntryMetadataV12, StorageEntryMetadataV13, StorageEntryMetadataV14, StorageEntryMetadataV16, StorageEntryMetadataV9, StorageEntryModifierLatest, StorageEntryModifierV10, StorageEntryModifierV11, StorageEntryModifierV12, StorageEntryModifierV13, StorageEntryModifierV14, StorageEntryModifierV9, StorageEntryTypeLatest, StorageEntryTypeV10, StorageEntryTypeV11, StorageEntryTypeV12, StorageEntryTypeV13, StorageEntryTypeV14, StorageEntryTypeV9, StorageHasher, StorageHasherV10, StorageHasherV11, StorageHasherV12, StorageHasherV13, StorageHasherV14, StorageHasherV9, StorageMetadataV10, StorageMetadataV11, StorageMetadataV12, StorageMetadataV13, StorageMetadataV9, TransactionExtensionMetadataLatest, TransactionExtensionMetadataV16, VariantDeprecationInfoV16 } from '@polkadot/types/interfaces/metadata';
 import type { Mixnode, MixnodesErr, SessionPhase, SessionStatus } from '@polkadot/types/interfaces/mixnet';
 import type { MmrBatchProof, MmrEncodableOpaqueLeaf, MmrError, MmrHash, MmrLeafBatchProof, MmrLeafIndex, MmrLeafProof, MmrNodeIndex, MmrProof } from '@polkadot/types/interfaces/mmr';
 import type { NftCollectionId, NftItemId } from '@polkadot/types/interfaces/nfts';
@@ -408,6 +408,7 @@ declare module '@polkadot/types/types/registry' {
     ElectionStatus: ElectionStatus;
     EncodedFinalityProofs: EncodedFinalityProofs;
     EncodedJustification: EncodedJustification;
+    EnumDeprecationInfoV16: EnumDeprecationInfoV16;
     Epoch: Epoch;
     EpochAuthorship: EpochAuthorship;
     Era: Era;
@@ -501,6 +502,7 @@ declare module '@polkadot/types/types/registry' {
     ExtrinsicMetadataV13: ExtrinsicMetadataV13;
     ExtrinsicMetadataV14: ExtrinsicMetadataV14;
     ExtrinsicMetadataV15: ExtrinsicMetadataV15;
+    ExtrinsicMetadataV16: ExtrinsicMetadataV16;
     ExtrinsicOrHash: ExtrinsicOrHash;
     ExtrinsicPayload: ExtrinsicPayload;
     ExtrinsicPayloadUnknown: ExtrinsicPayloadUnknown;
@@ -647,6 +649,7 @@ declare module '@polkadot/types/types/registry' {
     InvalidTransaction: InvalidTransaction;
     isize: isize;
     ISize: ISize;
+    ItemDeprecationInfoV16: ItemDeprecationInfoV16;
     Json: Json;
     Junction: Junction;
     Junctions: Junctions;
@@ -708,6 +711,7 @@ declare module '@polkadot/types/types/registry' {
     MetadataV13: MetadataV13;
     MetadataV14: MetadataV14;
     MetadataV15: MetadataV15;
+    MetadataV16: MetadataV16;
     MetadataV9: MetadataV9;
     MigrationStatusResult: MigrationStatusResult;
     Mixnode: Mixnode;
@@ -827,24 +831,32 @@ declare module '@polkadot/types/types/registry' {
     Owner: Owner;
     PageCounter: PageCounter;
     PageIndexData: PageIndexData;
+    PalletAssociatedTypeMetadataV16: PalletAssociatedTypeMetadataV16;
     PalletCallMetadataLatest: PalletCallMetadataLatest;
     PalletCallMetadataV14: PalletCallMetadataV14;
+    PalletCallMetadataV16: PalletCallMetadataV16;
     PalletConstantMetadataLatest: PalletConstantMetadataLatest;
     PalletConstantMetadataV14: PalletConstantMetadataV14;
+    PalletConstantMetadataV16: PalletConstantMetadataV16;
     PalletErrorMetadataLatest: PalletErrorMetadataLatest;
     PalletErrorMetadataV14: PalletErrorMetadataV14;
+    PalletErrorMetadataV16: PalletErrorMetadataV16;
     PalletEventMetadataLatest: PalletEventMetadataLatest;
     PalletEventMetadataV14: PalletEventMetadataV14;
+    PalletEventMetadataV16: PalletEventMetadataV16;
     PalletId: PalletId;
     PalletInfoV3: PalletInfoV3;
     PalletInfoV4: PalletInfoV4;
     PalletMetadataLatest: PalletMetadataLatest;
     PalletMetadataV14: PalletMetadataV14;
     PalletMetadataV15: PalletMetadataV15;
+    PalletMetadataV16: PalletMetadataV16;
     PalletsOrigin: PalletsOrigin;
     PalletStorageMetadataLatest: PalletStorageMetadataLatest;
     PalletStorageMetadataV14: PalletStorageMetadataV14;
+    PalletStorageMetadataV16: PalletStorageMetadataV16;
     PalletVersion: PalletVersion;
+    PalletViewFunctionMetadataV16: PalletViewFunctionMetadataV16;
     ParachainDispatchOrigin: ParachainDispatchOrigin;
     ParachainInherentData: ParachainInherentData;
     ParachainProposal: ParachainProposal;
@@ -982,7 +994,9 @@ declare module '@polkadot/types/types/registry' {
     RpcMethods: RpcMethods;
     RuntimeApiMetadataLatest: RuntimeApiMetadataLatest;
     RuntimeApiMetadataV15: RuntimeApiMetadataV15;
+    RuntimeApiMetadataV16: RuntimeApiMetadataV16;
     RuntimeApiMethodMetadataV15: RuntimeApiMethodMetadataV15;
+    RuntimeApiMethodMetadataV16: RuntimeApiMethodMetadataV16;
     RuntimeApiMethodParamMetadataV15: RuntimeApiMethodParamMetadataV15;
     RuntimeCall: RuntimeCall;
     RuntimeDbWeight: RuntimeDbWeight;
@@ -1127,6 +1141,7 @@ declare module '@polkadot/types/types/registry' {
     StorageEntryMetadataV12: StorageEntryMetadataV12;
     StorageEntryMetadataV13: StorageEntryMetadataV13;
     StorageEntryMetadataV14: StorageEntryMetadataV14;
+    StorageEntryMetadataV16: StorageEntryMetadataV16;
     StorageEntryMetadataV9: StorageEntryMetadataV9;
     StorageEntryModifierLatest: StorageEntryModifierLatest;
     StorageEntryModifierV10: StorageEntryModifierV10;
@@ -1179,6 +1194,8 @@ declare module '@polkadot/types/types/registry' {
     TraceBlockResponse: TraceBlockResponse;
     TraceError: TraceError;
     TransactionalError: TransactionalError;
+    TransactionExtensionMetadataLatest: TransactionExtensionMetadataLatest;
+    TransactionExtensionMetadataV16: TransactionExtensionMetadataV16;
     TransactionInfo: TransactionInfo;
     TransactionLongevity: TransactionLongevity;
     TransactionPriority: TransactionPriority;
@@ -1242,6 +1259,7 @@ declare module '@polkadot/types/types/registry' {
     ValidDisputeStatementKind: ValidDisputeStatementKind;
     ValidityAttestation: ValidityAttestation;
     ValidTransaction: ValidTransaction;
+    VariantDeprecationInfoV16: VariantDeprecationInfoV16;
     VecInboundHrmpMessage: VecInboundHrmpMessage;
     VersionedMultiAsset: VersionedMultiAsset;
     VersionedMultiAssets: VersionedMultiAssets;
diff --git a/packages/types/src/create/registry.ts b/packages/types/src/create/registry.ts
index 0dd2b8be538..f2d99a98c33 100644
--- a/packages/types/src/create/registry.ts
+++ b/packages/types/src/create/registry.ts
@@ -9,7 +9,7 @@ import type { CallFunction, CodecHasher, Definitions, DetectCodec, RegisteredTyp
 
 import { DoNotConstruct, Json, Raw } from '@polkadot/types-codec';
 import { constructTypeClass, createClassUnsafe, createTypeUnsafe } from '@polkadot/types-create';
-import { assertReturn, BN_ZERO, formatBalance, isBn, isFunction, isNumber, isString, isU8a, lazyMethod, logger, objectSpread, stringCamelCase, stringify } from '@polkadot/util';
+import { assertReturn, formatBalance, isBn, isFunction, isNumber, isString, isU8a, lazyMethod, logger, objectSpread, stringCamelCase, stringify } from '@polkadot/util';
 import { blake2AsU8a } from '@polkadot/util-crypto';
 
 import { expandExtensionTypes, fallbackExtensions, findUnknownExtensions } from '../extrinsic/signedExtensions/index.js';
@@ -608,9 +608,9 @@ export class TypeRegistry implements Registry {
     // setup the available extensions
     this.setSignedExtensions(
       signedExtensions || (
-        this.#metadata.extrinsic.version.gt(BN_ZERO)
+        this.#metadata.extrinsic.versions.length > 0 && this.#metadata.extrinsic.versions.every((value) => value > 0)
           // FIXME Use the extension and their injected types
-          ? this.#metadata.extrinsic.signedExtensions.map(({ identifier }) => identifier.toString())
+          ? this.#metadata.extrinsic.transactionExtensions.map(({ identifier }) => identifier.toString())
           : fallbackExtensions
       ),
       userExtensions,
diff --git a/packages/types/src/extrinsic/Extrinsic.ts b/packages/types/src/extrinsic/Extrinsic.ts
index 432593d86f3..294e28af763 100644
--- a/packages/types/src/extrinsic/Extrinsic.ts
+++ b/packages/types/src/extrinsic/Extrinsic.ts
@@ -329,7 +329,10 @@ export class GenericExtrinsic<A extends AnyTuple = AnyTuple> extends ExtrinsicBa
   static LATEST_EXTRINSIC_VERSION = LATEST_EXTRINSIC_VERSION;
 
   constructor (registry: Registry, value?: GenericExtrinsic | ExtrinsicValue | AnyU8a | Call, { preamble, version }: CreateOptions = {}) {
-    super(registry, decodeExtrinsic(registry, value, version || registry.metadata.extrinsic.version?.toNumber(), preamble), undefined, preamble);
+    const versionsLength = registry.metadata.extrinsic.versions.length;
+    const highestSupportedVersion = versionsLength ? registry.metadata.extrinsic.versions[versionsLength - 1] : undefined;
+
+    super(registry, decodeExtrinsic(registry, value, version || highestSupportedVersion, preamble), undefined, preamble);
   }
 
   /**
diff --git a/packages/types/src/interfaces/metadata/definitions.ts b/packages/types/src/interfaces/metadata/definitions.ts
index 7fd8d861abc..6ef8f8c0c8a 100644
--- a/packages/types/src/interfaces/metadata/definitions.ts
+++ b/packages/types/src/interfaces/metadata/definitions.ts
@@ -15,6 +15,7 @@ import { v12 } from './v12.js';
 import { v13 } from './v13.js';
 import { v14 } from './v14.js';
 import { v15 } from './v15.js';
+import { v16 } from './v16.js';
 
 export { AllHashers };
 
@@ -30,26 +31,28 @@ export default {
     ...v13,
     ...v14,
     ...v15,
+    ...v16,
 
     // latest mappings
     // NOTE: For v15, we only added the runtime defintions,
     // hence latest for most pointing to the previous V14
     ErrorMetadataLatest: 'ErrorMetadataV14',
     EventMetadataLatest: 'EventMetadataV14',
-    ExtrinsicMetadataLatest: 'ExtrinsicMetadataV15',
+    ExtrinsicMetadataLatest: 'ExtrinsicMetadataV16',
     FunctionArgumentMetadataLatest: 'FunctionArgumentMetadataV14',
     FunctionMetadataLatest: 'FunctionMetadataV14',
-    MetadataLatest: 'MetadataV15',
-    PalletCallMetadataLatest: 'PalletCallMetadataV14',
-    PalletConstantMetadataLatest: 'PalletConstantMetadataV14',
-    PalletErrorMetadataLatest: 'PalletErrorMetadataV14',
-    PalletEventMetadataLatest: 'PalletEventMetadataV14',
-    PalletMetadataLatest: 'PalletMetadataV15',
-    PalletStorageMetadataLatest: 'PalletStorageMetadataV14',
+    MetadataLatest: 'MetadataV16',
+    PalletCallMetadataLatest: 'PalletCallMetadataV16',
+    PalletConstantMetadataLatest: 'PalletConstantMetadataV16',
+    PalletErrorMetadataLatest: 'PalletErrorMetadataV16',
+    PalletEventMetadataLatest: 'PalletEventMetadataV16',
+    PalletMetadataLatest: 'PalletMetadataV16',
+    PalletStorageMetadataLatest: 'PalletStorageMetadataV16',
     PortableType: 'PortableTypeV14',
-    RuntimeApiMetadataLatest: 'RuntimeApiMetadataV15',
+    RuntimeApiMetadataLatest: 'RuntimeApiMetadataV16',
     SignedExtensionMetadataLatest: 'SignedExtensionMetadataV14',
-    StorageEntryMetadataLatest: 'StorageEntryMetadataV14',
+    TransactionExtensionMetadataLatest: 'TransactionExtensionMetadataV16',
+    StorageEntryMetadataLatest: 'StorageEntryMetadataV16',
     StorageEntryModifierLatest: 'StorageEntryModifierV14',
     StorageEntryTypeLatest: 'StorageEntryTypeV14',
     StorageHasher: 'StorageHasherV14',
@@ -76,7 +79,8 @@ export default {
         V12: 'MetadataV12',
         V13: 'MetadataV13',
         V14: 'MetadataV14',
-        V15: 'MetadataV15'
+        V15: 'MetadataV15',
+        V16: 'MetadataV16'
       }
     }
   }
diff --git a/packages/types/src/interfaces/metadata/types.ts b/packages/types/src/interfaces/metadata/types.ts
index b60cd7bc889..85debb77474 100644
--- a/packages/types/src/interfaces/metadata/types.ts
+++ b/packages/types/src/interfaces/metadata/types.ts
@@ -2,7 +2,7 @@
 /* eslint-disable */
 
 import type { PortableRegistry } from '@polkadot/types';
-import type { BTreeMap, Bytes, Enum, Option, Struct, Text, Type, Vec, WrapperOpaque, bool, u8 } from '@polkadot/types-codec';
+import type { BTreeMap, Bytes, Compact, Enum, Option, Struct, Text, Type, U8aFixed, Vec, WrapperOpaque, bool, u32, u8 } from '@polkadot/types-codec';
 import type { Si1Field, Si1LookupTypeId, Si1Type, SiLookupTypeId } from '@polkadot/types/interfaces/scaleInfo';
 
 /** @name CustomMetadata15 */
@@ -16,6 +16,9 @@ export interface CustomValueMetadata15 extends Struct {
   readonly value: Bytes;
 }
 
+/** @name EnumDeprecationInfoV16 */
+export interface EnumDeprecationInfoV16 extends BTreeMap<u8, VariantDeprecationInfoV16> {}
+
 /** @name ErrorMetadataLatest */
 export interface ErrorMetadataLatest extends ErrorMetadataV14 {}
 
@@ -78,7 +81,7 @@ export interface EventMetadataV9 extends Struct {
 }
 
 /** @name ExtrinsicMetadataLatest */
-export interface ExtrinsicMetadataLatest extends ExtrinsicMetadataV15 {}
+export interface ExtrinsicMetadataLatest extends ExtrinsicMetadataV16 {}
 
 /** @name ExtrinsicMetadataV11 */
 export interface ExtrinsicMetadataV11 extends Struct {
@@ -109,6 +112,16 @@ export interface ExtrinsicMetadataV15 extends Struct {
   readonly signedExtensions: Vec<SignedExtensionMetadataV14>;
 }
 
+/** @name ExtrinsicMetadataV16 */
+export interface ExtrinsicMetadataV16 extends Struct {
+  readonly versions: Bytes;
+  readonly addressType: SiLookupTypeId;
+  readonly callType: SiLookupTypeId;
+  readonly signatureType: SiLookupTypeId;
+  readonly transactionExtensionsByVersion: BTreeMap<u8, Vec<Compact<u32>>>;
+  readonly transactionExtensions: Vec<TransactionExtensionMetadataV16>;
+}
+
 /** @name FunctionArgumentMetadataLatest */
 export interface FunctionArgumentMetadataLatest extends FunctionArgumentMetadataV14 {}
 
@@ -168,6 +181,18 @@ export interface FunctionMetadataV9 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name ItemDeprecationInfoV16 */
+export interface ItemDeprecationInfoV16 extends Enum {
+  readonly isNotDeprecated: boolean;
+  readonly isDeprecatedWithoutNote: boolean;
+  readonly isDeprecated: boolean;
+  readonly asDeprecated: {
+    readonly note: Text;
+    readonly since: Option<Text>;
+  } & Struct;
+  readonly type: 'NotDeprecated' | 'DeprecatedWithoutNote' | 'Deprecated';
+}
+
 /** @name MetadataAll */
 export interface MetadataAll extends Enum {
   readonly isV9: boolean;
@@ -184,11 +209,13 @@ export interface MetadataAll extends Enum {
   readonly asV14: MetadataV14;
   readonly isV15: boolean;
   readonly asV15: MetadataV15;
-  readonly type: 'V0' | 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8' | 'V9' | 'V10' | 'V11' | 'V12' | 'V13' | 'V14' | 'V15';
+  readonly isV16: boolean;
+  readonly asV16: MetadataV16;
+  readonly type: 'V0' | 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8' | 'V9' | 'V10' | 'V11' | 'V12' | 'V13' | 'V14' | 'V15' | 'V16';
 }
 
 /** @name MetadataLatest */
-export interface MetadataLatest extends MetadataV15 {}
+export interface MetadataLatest extends MetadataV16 {}
 
 /** @name MetadataV10 */
 export interface MetadataV10 extends Struct {
@@ -232,6 +259,16 @@ export interface MetadataV15 extends Struct {
   readonly custom: CustomMetadata15;
 }
 
+/** @name MetadataV16 */
+export interface MetadataV16 extends Struct {
+  readonly lookup: PortableRegistry;
+  readonly pallets: Vec<PalletMetadataV16>;
+  readonly extrinsic: ExtrinsicMetadataV16;
+  readonly apis: Vec<RuntimeApiMetadataV16>;
+  readonly outerEnums: OuterEnums15;
+  readonly custom: CustomMetadata15;
+}
+
 /** @name MetadataV9 */
 export interface MetadataV9 extends Struct {
   readonly modules: Vec<ModuleMetadataV9>;
@@ -319,16 +356,29 @@ export interface OuterEnums15 extends Struct {
   readonly errorType: SiLookupTypeId;
 }
 
+/** @name PalletAssociatedTypeMetadataV16 */
+export interface PalletAssociatedTypeMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly type: SiLookupTypeId;
+  readonly docs: Vec<Text>;
+}
+
 /** @name PalletCallMetadataLatest */
-export interface PalletCallMetadataLatest extends PalletCallMetadataV14 {}
+export interface PalletCallMetadataLatest extends PalletCallMetadataV16 {}
 
 /** @name PalletCallMetadataV14 */
 export interface PalletCallMetadataV14 extends Struct {
   readonly type: SiLookupTypeId;
 }
 
+/** @name PalletCallMetadataV16 */
+export interface PalletCallMetadataV16 extends Struct {
+  readonly type: SiLookupTypeId;
+  readonly deprecationInfo: EnumDeprecationInfoV16;
+}
+
 /** @name PalletConstantMetadataLatest */
-export interface PalletConstantMetadataLatest extends PalletConstantMetadataV14 {}
+export interface PalletConstantMetadataLatest extends PalletConstantMetadataV16 {}
 
 /** @name PalletConstantMetadataV14 */
 export interface PalletConstantMetadataV14 extends Struct {
@@ -338,24 +388,45 @@ export interface PalletConstantMetadataV14 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name PalletConstantMetadataV16 */
+export interface PalletConstantMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly type: SiLookupTypeId;
+  readonly value: Bytes;
+  readonly docs: Vec<Text>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name PalletErrorMetadataLatest */
-export interface PalletErrorMetadataLatest extends PalletErrorMetadataV14 {}
+export interface PalletErrorMetadataLatest extends PalletErrorMetadataV16 {}
 
 /** @name PalletErrorMetadataV14 */
 export interface PalletErrorMetadataV14 extends Struct {
   readonly type: SiLookupTypeId;
 }
 
+/** @name PalletErrorMetadataV16 */
+export interface PalletErrorMetadataV16 extends Struct {
+  readonly type: SiLookupTypeId;
+  readonly deprecationInfo: EnumDeprecationInfoV16;
+}
+
 /** @name PalletEventMetadataLatest */
-export interface PalletEventMetadataLatest extends PalletEventMetadataV14 {}
+export interface PalletEventMetadataLatest extends PalletEventMetadataV16 {}
 
 /** @name PalletEventMetadataV14 */
 export interface PalletEventMetadataV14 extends Struct {
   readonly type: SiLookupTypeId;
 }
 
+/** @name PalletEventMetadataV16 */
+export interface PalletEventMetadataV16 extends Struct {
+  readonly type: SiLookupTypeId;
+  readonly deprecationInfo: EnumDeprecationInfoV16;
+}
+
 /** @name PalletMetadataLatest */
-export interface PalletMetadataLatest extends PalletMetadataV15 {}
+export interface PalletMetadataLatest extends PalletMetadataV16 {}
 
 /** @name PalletMetadataV14 */
 export interface PalletMetadataV14 extends Struct {
@@ -380,8 +451,23 @@ export interface PalletMetadataV15 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name PalletMetadataV16 */
+export interface PalletMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly storage: Option<PalletStorageMetadataV16>;
+  readonly calls: Option<PalletCallMetadataV16>;
+  readonly events: Option<PalletEventMetadataV16>;
+  readonly constants: Vec<PalletConstantMetadataV16>;
+  readonly errors: Option<PalletErrorMetadataV16>;
+  readonly associatedTypes: Vec<PalletAssociatedTypeMetadataV16>;
+  readonly viewFunctions: Vec<PalletViewFunctionMetadataV16>;
+  readonly index: u8;
+  readonly docs: Vec<Text>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name PalletStorageMetadataLatest */
-export interface PalletStorageMetadataLatest extends PalletStorageMetadataV14 {}
+export interface PalletStorageMetadataLatest extends PalletStorageMetadataV16 {}
 
 /** @name PalletStorageMetadataV14 */
 export interface PalletStorageMetadataV14 extends Struct {
@@ -389,6 +475,22 @@ export interface PalletStorageMetadataV14 extends Struct {
   readonly items: Vec<StorageEntryMetadataV14>;
 }
 
+/** @name PalletStorageMetadataV16 */
+export interface PalletStorageMetadataV16 extends Struct {
+  readonly prefix: Text;
+  readonly items: Vec<StorageEntryMetadataV16>;
+}
+
+/** @name PalletViewFunctionMetadataV16 */
+export interface PalletViewFunctionMetadataV16 extends Struct {
+  readonly id: U8aFixed;
+  readonly name: Text;
+  readonly inputs: Vec<RuntimeApiMethodParamMetadataV15>;
+  readonly output: SiLookupTypeId;
+  readonly docs: Vec<Text>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name PortableType */
 export interface PortableType extends PortableTypeV14 {}
 
@@ -399,7 +501,7 @@ export interface PortableTypeV14 extends Struct {
 }
 
 /** @name RuntimeApiMetadataLatest */
-export interface RuntimeApiMetadataLatest extends RuntimeApiMetadataV15 {}
+export interface RuntimeApiMetadataLatest extends RuntimeApiMetadataV16 {}
 
 /** @name RuntimeApiMetadataV15 */
 export interface RuntimeApiMetadataV15 extends Struct {
@@ -408,6 +510,15 @@ export interface RuntimeApiMetadataV15 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name RuntimeApiMetadataV16 */
+export interface RuntimeApiMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly methods: Vec<RuntimeApiMethodMetadataV16>;
+  readonly docs: Vec<Text>;
+  readonly version: Compact<u32>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name RuntimeApiMethodMetadataV15 */
 export interface RuntimeApiMethodMetadataV15 extends Struct {
   readonly name: Text;
@@ -416,6 +527,15 @@ export interface RuntimeApiMethodMetadataV15 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name RuntimeApiMethodMetadataV16 */
+export interface RuntimeApiMethodMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly inputs: Vec<RuntimeApiMethodParamMetadataV15>;
+  readonly output: SiLookupTypeId;
+  readonly docs: Vec<Text>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name RuntimeApiMethodParamMetadataV15 */
 export interface RuntimeApiMethodParamMetadataV15 extends Struct {
   readonly name: Text;
@@ -433,7 +553,7 @@ export interface SignedExtensionMetadataV14 extends Struct {
 }
 
 /** @name StorageEntryMetadataLatest */
-export interface StorageEntryMetadataLatest extends StorageEntryMetadataV14 {}
+export interface StorageEntryMetadataLatest extends StorageEntryMetadataV16 {}
 
 /** @name StorageEntryMetadataV10 */
 export interface StorageEntryMetadataV10 extends Struct {
@@ -474,6 +594,16 @@ export interface StorageEntryMetadataV14 extends Struct {
   readonly docs: Vec<Text>;
 }
 
+/** @name StorageEntryMetadataV16 */
+export interface StorageEntryMetadataV16 extends Struct {
+  readonly name: Text;
+  readonly modifier: StorageEntryModifierV14;
+  readonly type: StorageEntryTypeV14;
+  readonly fallback: Bytes;
+  readonly docs: Vec<Text>;
+  readonly deprecationInfo: ItemDeprecationInfoV16;
+}
+
 /** @name StorageEntryMetadataV9 */
 export interface StorageEntryMetadataV9 extends Struct {
   readonly name: Text;
@@ -694,4 +824,26 @@ export interface StorageMetadataV9 extends Struct {
   readonly items: Vec<StorageEntryMetadataV9>;
 }
 
+/** @name TransactionExtensionMetadataLatest */
+export interface TransactionExtensionMetadataLatest extends TransactionExtensionMetadataV16 {}
+
+/** @name TransactionExtensionMetadataV16 */
+export interface TransactionExtensionMetadataV16 extends Struct {
+  readonly identifier: Text;
+  readonly type: SiLookupTypeId;
+  readonly implicit: SiLookupTypeId;
+}
+
+/** @name VariantDeprecationInfoV16 */
+export interface VariantDeprecationInfoV16 extends Enum {
+  readonly isDummyVariant: boolean;
+  readonly isDeprecatedWithoutNote: boolean;
+  readonly isDeprecated: boolean;
+  readonly asDeprecated: {
+    readonly note: Text;
+    readonly since: Option<Text>;
+  } & Struct;
+  readonly type: 'DummyVariant' | 'DeprecatedWithoutNote' | 'Deprecated';
+}
+
 export type PHANTOM_METADATA = 'metadata';
diff --git a/packages/types/src/interfaces/metadata/v16.ts b/packages/types/src/interfaces/metadata/v16.ts
new file mode 100644
index 00000000000..3a635cd1455
--- /dev/null
+++ b/packages/types/src/interfaces/metadata/v16.ts
@@ -0,0 +1,168 @@
+// Copyright 2017-2025 @polkadot/types authors & contributors
+// SPDX-License-Identifier: Apache-2.0
+
+// order important in structs... :)
+/* eslint-disable sort-keys */
+
+import type { DefinitionsTypes } from '../../types/index.js';
+
+export const v16: DefinitionsTypes = {
+  // actual v16 definition
+  MetadataV16: {
+    lookup: 'PortableRegistry',
+    pallets: 'Vec<PalletMetadataV16>',
+    extrinsic: 'ExtrinsicMetadataV16',
+    apis: 'Vec<RuntimeApiMetadataV16>',
+    outerEnums: 'OuterEnums15',
+    custom: 'CustomMetadata15'
+  },
+
+  // ---- Pallet definitions ----
+  PalletMetadataV16: {
+    name: 'Text',
+    storage: 'Option<PalletStorageMetadataV16>',
+    calls: 'Option<PalletCallMetadataV16>',
+    events: 'Option<PalletEventMetadataV16>',
+    constants: 'Vec<PalletConstantMetadataV16>',
+    errors: 'Option<PalletErrorMetadataV16>',
+    associatedTypes: 'Vec<PalletAssociatedTypeMetadataV16>',
+    viewFunctions: 'Vec<PalletViewFunctionMetadataV16>',
+    index: 'u8',
+    docs: 'Vec<Text>',
+    // Deprecation info
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  },
+  PalletStorageMetadataV16: {
+    prefix: 'Text',
+    items: 'Vec<StorageEntryMetadataV16>'
+  },
+  StorageEntryMetadataV16: {
+    name: 'Text',
+    modifier: 'StorageEntryModifierV14',
+    type: 'StorageEntryTypeV14',
+    fallback: 'Bytes',
+    docs: 'Vec<Text>',
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  },
+  ItemDeprecationInfoV16: {
+    _enum: {
+      // Item is not deprecated.
+      NotDeprecated: 'Null',
+      // Item is fully deprecated without a note.
+      DeprecatedWithoutNote: 'Null',
+      // Item is fully deprecated with a note and an optional `since` field.
+      Deprecated: {
+        // Note explaining the deprecation
+        note: 'Text',
+        // Optional value for noting the version when the deprecation occurred.
+        since: 'Option<Text>'
+      }
+    }
+  },
+  PalletCallMetadataV16: {
+    type: 'SiLookupTypeId',
+    // Deprecation status of the pallet call
+    deprecationInfo: 'EnumDeprecationInfoV16'
+  },
+  // Deprecation information for enums in which specific variants can be deprecated.
+  // If the map is empty, then nothing is deprecated.
+  EnumDeprecationInfoV16: 'BTreeMap<u8, VariantDeprecationInfoV16>',
+  VariantDeprecationInfoV16: {
+    _enum: {
+      // Dummy variant, just here to force DeprecatedWithoutNote
+      // to have index 1 and Deprecated to have index 2
+      DummyVariant: 'Null',
+      // Variant is deprecated without a note.
+      DeprecatedWithoutNote: 'Null',
+      // Variant is deprecated with a note and an optional `since` field.
+      Deprecated: {
+        // Note explaining the deprecation
+        note: 'Text',
+        // Optional value for noting the version when the deprecation occurred.
+        since: 'Option<Text>'
+      }
+
+    }
+  },
+  PalletEventMetadataV16: {
+    type: 'SiLookupTypeId',
+    // Deprecation info
+    deprecationInfo: 'EnumDeprecationInfoV16'
+  },
+  PalletConstantMetadataV16: {
+    name: 'Text',
+    type: 'SiLookupTypeId',
+    value: 'Bytes',
+    docs: 'Vec<Text>',
+    // Deprecation info
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  },
+  PalletErrorMetadataV16: {
+    type: 'SiLookupTypeId',
+    // Deprecation info
+    deprecationInfo: 'EnumDeprecationInfoV16'
+  },
+  PalletAssociatedTypeMetadataV16: {
+    name: 'Text',
+    type: 'SiLookupTypeId',
+    docs: 'Vec<Text>'
+  },
+  PalletViewFunctionMetadataV16: {
+    id: '[u8; 32]',
+    // Method name.
+    name: 'Text',
+    // Method par  ameters.
+    inputs: 'Vec<RuntimeApiMethodParamMetadataV15>',
+    // Method output.
+    output: 'SiLookupTypeId',
+    // Method documentation.
+    docs: 'Vec<T::String>',
+    // Deprecation info
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  },
+
+  // ---- Extrinsic definitions ----
+  ExtrinsicMetadataV16: {
+  // Extrinsic versions supported by the runtime.
+    versions: 'Vec<u8>',
+    // The type of the address that signs the extrinsic
+    addressType: 'SiLookupTypeId',
+    // The type of the outermost Call enum.
+    callType: 'SiLookupTypeId',
+    // The type of the extrinsic's signature.
+    signatureType: 'SiLookupTypeId',
+    // A mapping of supported transaction extrinsic versions to their respective transaction extension indexes.
+    //
+    // For each supported version number, list the indexes, in order, of the extensions used.
+    transactionExtensionsByVersion: 'BTreeMap<u8, Vec<Compact<u32>>>',
+    // The transaction extensions in the order they appear in the extrinsic.
+    transactionExtensions: 'Vec<TransactionExtensionMetadataV16>'
+  },
+  TransactionExtensionMetadataV16: {
+  // The unique transaction extension identifier, which may be different from the type name.
+    identifier: 'Text',
+    // The type of the transaction extension, with the data to be included in the extrinsic.
+    type: 'SiLookupTypeId',
+    // The type of the implicit data, with the data to be included in the signed payload.
+    implicit: 'SiLookupTypeId'
+  },
+
+  // ---- Runtime Api definitions ----
+  RuntimeApiMetadataV16: {
+    name: 'Text',
+    methods: 'Vec<RuntimeApiMethodMetadataV16>',
+    docs: 'Vec<Text>',
+    // Runtime API version.
+    version: 'Compact<u32>',
+    // Deprecation info
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  },
+  RuntimeApiMethodMetadataV16: {
+    name: 'Text',
+    inputs: 'Vec<RuntimeApiMethodParamMetadataV15>',
+    output: 'SiLookupTypeId',
+    docs: 'Vec<Text>',
+    // Deprecation info
+    deprecationInfo: 'ItemDeprecationInfoV16'
+  }
+};
diff --git a/packages/types/src/metadata/MetadataVersioned.ts b/packages/types/src/metadata/MetadataVersioned.ts
index 8ae3a3d2dd1..b3e36a4609f 100644
--- a/packages/types/src/metadata/MetadataVersioned.ts
+++ b/packages/types/src/metadata/MetadataVersioned.ts
@@ -3,7 +3,7 @@
 
 import type { AnyJson } from '@polkadot/types-codec/types';
 import type { HexString } from '@polkadot/util/types';
-import type { MetadataAll, MetadataLatest, MetadataV9, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15 } from '../interfaces/metadata/index.js';
+import type { MetadataAll, MetadataLatest, MetadataV9, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15, MetadataV16 } from '../interfaces/metadata/index.js';
 import type { Registry } from '../types/index.js';
 import type { MetaVersionAll, MetaVersionAsX } from './versions.js';
 
@@ -16,7 +16,8 @@ import { toV12 } from './v11/toV12.js';
 import { toV13 } from './v12/toV13.js';
 import { toV14 } from './v13/toV14.js';
 import { toV15 } from './v14/toV15.js';
-import { toLatest } from './v15/toLatest.js';
+import { toV16 } from './v15/toV16.js';
+import { toLatest } from './v16/toLatest.js';
 import { MagicNumber } from './MagicNumber.js';
 import { LATEST_VERSION, TO_CALLS_VERSION } from './versions.js';
 
@@ -130,12 +131,19 @@ export class MetadataVersioned extends Struct {
   }
 
   /**
-   * @description Returns the wrapped values as a V14 object
+   * @description Returns the wrapped values as a V15 object
    */
   public get asV15 (): MetadataV15 {
     return this.#getVersion(15, toV15);
   }
 
+  /**
+  * @description Returns the wrapped values as a V16 object
+  */
+  public get asV16 (): MetadataV16 {
+    return this.#getVersion(16, toV16);
+  }
+
   /**
    * @description Returns the wrapped values as a latest version object
    */
diff --git a/packages/types/src/metadata/util/testUtil.ts b/packages/types/src/metadata/util/testUtil.ts
index 8362af91f99..7b619edd2c8 100644
--- a/packages/types/src/metadata/util/testUtil.ts
+++ b/packages/types/src/metadata/util/testUtil.ts
@@ -34,6 +34,7 @@ interface MetadataJson {
     v13: MetadataJsonDef;
     v14: MetadataJsonDef;
     v15: MetadataJsonDef;
+    v16: MetadataJsonDef;
   }
 }
 
diff --git a/packages/types/src/metadata/v15/toV16.ts b/packages/types/src/metadata/v15/toV16.ts
new file mode 100644
index 00000000000..40c80c05295
--- /dev/null
+++ b/packages/types/src/metadata/v15/toV16.ts
@@ -0,0 +1,147 @@
+// Copyright 2017-2025 @polkadot/types authors & contributors
+// SPDX-License-Identifier: Apache-2.0
+
+import type { ExtrinsicMetadataV15, ExtrinsicMetadataV16, ItemDeprecationInfoV16, MetadataV15, MetadataV16, PalletAssociatedTypeMetadataV16, PalletCallMetadataV14, PalletCallMetadataV16, PalletConstantMetadataV14, PalletConstantMetadataV16, PalletErrorMetadataV14, PalletErrorMetadataV16, PalletEventMetadataV14, PalletEventMetadataV16, PalletMetadataV15, PalletMetadataV16, PalletStorageMetadataV14, PalletStorageMetadataV16, RuntimeApiMetadataV15, RuntimeApiMetadataV16, StorageEntryMetadataV16, TransactionExtensionMetadataV16 } from '../../interfaces/metadata/index.js';
+import type { Registry } from '../../types/index.js';
+
+import { type Vec } from '@polkadot/types-codec';
+import { objectSpread } from '@polkadot/util';
+
+function palletsFromV15 (registry: Registry, palletV15: PalletMetadataV15): PalletMetadataV16 {
+  const deprecationInfo: ItemDeprecationInfoV16 = registry.createTypeUnsafe('ItemDeprecationInfoV16', ['NotDeprecated']);
+  const associatedTypes: Vec<PalletAssociatedTypeMetadataV16> = registry.createTypeUnsafe('Vec<PalletAssociatedTypeMetadataV16>', [[]]);
+  const viewFunctions: Vec<PalletAssociatedTypeMetadataV16> = registry.createTypeUnsafe('Vec<PalletViewFunctionMetadataV16>', [[]]);
+
+  return registry.createTypeUnsafe('PalletMetadataV16', [
+    objectSpread({}, palletV15, {
+      associatedTypes,
+      calls: palletV15.calls.isSome ? convertCalls(registry, palletV15.calls.unwrap()) : null,
+      constants: convertConstants(registry, palletV15.constants),
+      deprecationInfo,
+      errors: palletV15.errors.isSome ? converErrors(registry, palletV15.errors.unwrap()) : null,
+      events: palletV15.events.isSome ? convertEvents(registry, palletV15.events.unwrap()) : null,
+      storage: palletV15.storage.isSome ? convertStorage(registry, palletV15.storage.unwrap()) : null,
+      viewFunctions
+    })
+  ]);
+}
+
+function convertStorage (registry: Registry, storage: PalletStorageMetadataV14): PalletStorageMetadataV16 {
+  const deprecationInfo: ItemDeprecationInfoV16 = registry.createTypeUnsafe('ItemDeprecationInfoV16', ['NotDeprecated']);
+
+  const items: StorageEntryMetadataV16[] = storage.items.map((item) =>
+    registry.createTypeUnsafe('StorageEntryMetadataV16', [
+      objectSpread({}, item, { deprecationInfo })
+    ])
+  );
+
+  return registry.createTypeUnsafe('PalletStorageMetadataV16', [{
+    items: registry.createTypeUnsafe('Vec<StorageEntryMetadataV16>', [items]),
+    prefix: storage.prefix
+  }]);
+}
+
+function convertCalls (registry: Registry, calls: PalletCallMetadataV14): PalletCallMetadataV16 {
+  const deprecationInfo = registry.createTypeUnsafe('EnumDeprecationInfoV16', []);
+
+  return registry.createTypeUnsafe('PalletCallMetadataV16', [{
+    deprecationInfo,
+    type: calls.type
+  }]);
+}
+
+function convertEvents (registry: Registry, events: PalletEventMetadataV14): PalletEventMetadataV16 {
+  const deprecationInfo = registry.createTypeUnsafe('EnumDeprecationInfoV16', []);
+
+  return registry.createTypeUnsafe('PalletEventMetadataV16', [{
+    deprecationInfo,
+    type: events.type
+  }]);
+}
+
+function convertConstants (registry: Registry, constants: Vec<PalletConstantMetadataV14>): Vec<PalletConstantMetadataV16> {
+  const deprecationInfo: ItemDeprecationInfoV16 = registry.createTypeUnsafe('ItemDeprecationInfoV16', ['NotDeprecated']);
+
+  return registry.createTypeUnsafe('Vec<PalletConstantMetadataV16>', [
+    constants.map((constant) => registry.createTypeUnsafe('PalletConstantMetadataV16', [
+      objectSpread({}, constant, { deprecationInfo })
+    ]))]
+  );
+}
+
+function converErrors (registry: Registry, errors: PalletErrorMetadataV14): PalletErrorMetadataV16 {
+  const deprecationInfo = registry.createTypeUnsafe('EnumDeprecationInfoV16', []);
+
+  return registry.createTypeUnsafe('PalletErrorMetadataV16', [{
+    deprecationInfo,
+    type: errors.type
+  }]);
+}
+
+function extrinsicFromV15 (registry: Registry, extrinsicV15: ExtrinsicMetadataV15): ExtrinsicMetadataV16 {
+  const transactionExtensions: TransactionExtensionMetadataV16[] = extrinsicV15.signedExtensions.map(({ additionalSigned, identifier, type }) =>
+    registry.createTypeUnsafe('TransactionExtensionMetadataV16', [{
+      identifier,
+      implict: additionalSigned,
+      type
+    }])
+  );
+
+  const indexes = transactionExtensions.map((_, i) =>
+    registry.createTypeUnsafe('Compact<u32>', [i])
+  );
+
+  const transactionExtensionsByVersion = registry.createTypeUnsafe(
+    'BTreeMap<u8, Vec<Compact<u32>>>',
+    [new Map([[registry.createTypeUnsafe('u8', [extrinsicV15.version]), registry.createTypeUnsafe('Vec<Compact<u32>>', [indexes])]])]
+  );
+
+  return registry.createTypeUnsafe('ExtrinsicMetadataV16', [
+    {
+      addressType: extrinsicV15.addressType,
+      callType: extrinsicV15.callType,
+      signatureType: extrinsicV15.signatureType,
+      transactionExtensions,
+      transactionExtensionsByVersion,
+      versions: [extrinsicV15.version]
+    }
+  ]);
+}
+
+function apisFromV15 (registry: Registry, runtimeApiV15: RuntimeApiMetadataV15): RuntimeApiMetadataV16 {
+  const deprecationInfo = registry.createTypeUnsafe('ItemDeprecationInfoV16', ['NotDeprecated']);
+
+  const methods = runtimeApiV15.methods.map((method) =>
+    registry.createTypeUnsafe('RuntimeApiMethodMetadataV16',
+      [objectSpread({}, method, { deprecationInfo })]
+    )
+  );
+
+  return registry.createTypeUnsafe('RuntimeApiMetadataV16', [
+    objectSpread({}, runtimeApiV15, {
+      deprecationInfo,
+      methods,
+      version: registry.createTypeUnsafe('Compact<u32>', [0])
+    })
+  ]);
+}
+
+/**
+ * Convert the Metadata to v16
+ * @internal
+ **/
+export function toV16 (registry: Registry, v15: MetadataV15, _: number): MetadataV16 {
+  const pallets: PalletMetadataV16[] = v15.pallets.map((pallet) => {
+    return palletsFromV15(registry, pallet);
+  });
+  const extrinsic: ExtrinsicMetadataV16 = extrinsicFromV15(registry, v15.extrinsic);
+  const apis: RuntimeApiMetadataV16[] = v15.apis.map((runtimeApi) => apisFromV15(registry, runtimeApi));
+
+  return registry.createTypeUnsafe('MetadataV16', [
+    objectSpread({}, v15, {
+      apis,
+      extrinsic,
+      pallets
+    })
+  ]);
+}
diff --git a/packages/types/src/metadata/v16/Metadata.spec.ts b/packages/types/src/metadata/v16/Metadata.spec.ts
new file mode 100644
index 00000000000..d1fa599bdd0
--- /dev/null
+++ b/packages/types/src/metadata/v16/Metadata.spec.ts
@@ -0,0 +1,30 @@
+// Copyright 2017-2025 @polkadot/types authors & contributors
+// SPDX-License-Identifier: Apache-2.0
+
+/* import assetHubKusamaData from '@polkadot/types-support/metadata/v16/asset-hub-kusama-hex';
+import assetHubPolkadotData from '@polkadot/types-support/metadata/v16/asset-hub-polkadot-hex';
+import kusamaData from '@polkadot/types-support/metadata/v16/kusama-hex';
+import polkadotData from '@polkadot/types-support/metadata/v16/polkadot-hex';
+import substrateData from '@polkadot/types-support/metadata/v16/substrate-hex';*/
+
+import { testMeta } from '../util/testUtil.js';
+
+// TODO: Once MetadataV16 lands in an official release, pull the
+// latest metadata for each chain and update the tests
+testMeta(16, {
+/*   'asset-hub-kusama': {
+    data: assetHubKusamaData
+  },
+  'asset-hub-polkadot': {
+    data: assetHubPolkadotData
+  },
+  kusama: {
+    data: kusamaData
+  },
+  polkadot: {
+    data: polkadotData
+  },
+  substrate: {
+    data: substrateData
+  }*/
+});
diff --git a/packages/types/src/metadata/v15/toLatest.ts b/packages/types/src/metadata/v16/toLatest.ts
similarity index 68%
rename from packages/types/src/metadata/v15/toLatest.ts
rename to packages/types/src/metadata/v16/toLatest.ts
index 646e8a1f2c3..2ae9f109dd7 100644
--- a/packages/types/src/metadata/v15/toLatest.ts
+++ b/packages/types/src/metadata/v16/toLatest.ts
@@ -2,12 +2,12 @@
 // SPDX-License-Identifier: Apache-2.0
 
 import type { Registry } from '@polkadot/types-codec/types';
-import type { MetadataLatest, MetadataV15 } from '../../interfaces/metadata/index.js';
+import type { MetadataLatest, MetadataV16 } from '../../interfaces/metadata/index.js';
 
 /**
  * Convert the Metadata (which is an alias) to latest
  * @internal
  **/
-export function toLatest (_registry: Registry, v15: MetadataV15, _metaVersion: number): MetadataLatest {
-  return v15;
+export function toLatest (_registry: Registry, v16: MetadataV16, _metaVersion: number): MetadataLatest {
+  return v16;
 }
diff --git a/packages/types/src/metadata/versions.ts b/packages/types/src/metadata/versions.ts
index 33877d49e17..0abf5400f70 100644
--- a/packages/types/src/metadata/versions.ts
+++ b/packages/types/src/metadata/versions.ts
@@ -3,7 +3,7 @@
 
 // Use these to generate all the Meta* types below via template keys
 // NOTE: Keep from latest -> earliest, see the LATEST_VERSION 0 index
-export const KNOWN_VERSIONS = [15, 14, 13, 12, 11, 10, 9] as const;
+export const KNOWN_VERSIONS = [16, 15, 14, 13, 12, 11, 10, 9] as const;
 export const LATEST_VERSION = KNOWN_VERSIONS[0];
 
 // This is part of migration. The toCallsOnly would be usede for esxtensions,


Reviews:
user: login: TarikGul
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T20:34:52Z
user: login: TarikGul
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T20:38:03Z
user: login: TarikGul
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T20:39:17Z
user: login: TarikGul
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T20:42:32Z
user: login: TarikGul
body: Few questions and nits
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-14T20:42:40Z
user: login: valentinfernandez1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T12:21:17Z
user: login: TarikGul
body: Great job!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-16T12:04:24Z

Review comments:
diff_hunk: @@ -22,7 +23,9 @@ import { Decorate } from './Decorate.js';
 
 const KEEPALIVE_INTERVAL = 10000;
 const WITH_VERSION_SHORTCUT = false;
-const SUPPORTED_METADATA_VERSIONS = [15, 14];
+
+// TODO: Remove U32::MAX when metadata 16 is stabilized.
path: packages/api/src/base/Init.ts
user: login: TarikGul
body: We can remove this comment
created_at: 2025-05-14T20:34:51Z
author_association: MEMBER
diff_hunk: @@ -17,6 +18,21 @@ import { ignoreUnusedLookups } from './lookup.js';
 
 const generateForMetaTemplate = Handlebars.compile(readTemplate('consts'));
 
+function getDeprecationNotice (deprecationInfo: ItemDeprecationInfoV16, name: string): string {
path: packages/typegen/src/generate/consts.ts
user: login: TarikGul
body: I think we can have just one single `getDeprecationNotice` by using Generics.

so:

```typescript
function getDeprecationNotice<T>(deprecationInfo: T, name: string)
```

Then we can call it by doing:

```typescript
getDeprecationNotice<ItemDeprecationInfoV16>(foo, bar);
```
created_at: 2025-05-14T20:38:03Z
author_association: MEMBER
diff_hunk: @@ -329,7 +329,11 @@ export class GenericExtrinsic<A extends AnyTuple = AnyTuple> extends ExtrinsicBa
   static LATEST_EXTRINSIC_VERSION = LATEST_EXTRINSIC_VERSION;
 
   constructor (registry: Registry, value?: GenericExtrinsic | ExtrinsicValue | AnyU8a | Call, { preamble, version }: CreateOptions = {}) {
-    super(registry, decodeExtrinsic(registry, value, version || registry.metadata.extrinsic.version?.toNumber(), preamble), undefined, preamble);
+    const versionsLength = registry.metadata.extrinsic.versions.length;
+    const highestSupportedVersion = versionsLength ? registry.metadata.extrinsic.versions[versionsLength - 1] : undefined;
+
+    console.log(registry.metadata.extrinsic.versions);
path: packages/types/src/extrinsic/Extrinsic.ts
user: login: TarikGul
body: Rouge console
created_at: 2025-05-14T20:39:17Z
author_association: MEMBER
diff_hunk: @@ -16,8 +16,8 @@ const CMD = {
 };
 
 // V15
-const META_VERSION_HEX = '0x0f000000';
-const META_VERSION = 15;
+const META_VERSION_HEX = '0x10000000';
path: scripts/metadata-get.mjs
user: login: TarikGul
body: I would suggest we only change this when its time to get the new metadata in a stable sdk release. That way for every release before that happens we can still get metadata v15 and update it. Thoughts?
created_at: 2025-05-14T20:42:31Z
author_association: MEMBER
diff_hunk: @@ -16,8 +16,8 @@ const CMD = {
 };
 
 // V15
-const META_VERSION_HEX = '0x0f000000';
-const META_VERSION = 15;
+const META_VERSION_HEX = '0x10000000';
path: scripts/metadata-get.mjs
user: login: valentinfernandez1
body: good catch, I was using it for testing and forgot to change it back.

created_at: 2025-05-15T12:21:17Z
author_association: CONTRIBUTOR

PR comments:
user: login: valentinfernandez1
created_at: 2025-04-21T20:01:13Z
body: The implementation is mostly done, except for the update of the metadata files for Polkadot, Kusama, AssetHub, and Substrate. These will be added in a follow up PR once they're available on their respective chains.

Since MetadataV16 [hasn't been finalized yet](https://forum.polkadot.network/t/stabilizing-v16-metadata/12352), I'm planning to keep this PR as a draft for now, as things are still subject to change.

That said, feel free to take a look and share any early feedback in the meantime 🙏🏻 
author_association: CONTRIBUTOR
user: login: valentinfernandez1
created_at: 2025-05-14T19:27:20Z
body: Metadata V16 has been stabilized on [polkadotSDK](https://github.com/paritytech/polkadot-sdk/pull/8443) so this can now be merged.
author_association: CONTRIBUTOR
user: login: valentinfernandez1
created_at: 2025-05-15T15:21:52Z
body: All comments have been addressed

author_association: CONTRIBUTOR
user: login: polkadot-js-bot
created_at: 2025-05-18T13:31:20Z
body: This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
author_association: NONE