@@ -31,8 +31,9 @@ import polkadotRpc from '@polkadot/types-support/metadata/v15/polkadot-rpc';
3131import polkadotVer from '@polkadot/types-support/metadata/v15/polkadot-ver' ;
3232import substrateMeta from '@polkadot/types-support/metadata/v15/substrate-hex' ;
3333import { isHex , stringCamelCase , stringLowerFirst } from '@polkadot/util' ;
34+ import { blake2AsHex } from '@polkadot/util-crypto' ;
3435
35- import { assertFile , getMetadataViaWs , getRpcMethodsViaWs } from './util/index.js' ;
36+ import { assertFile , getMetadataViaWs , getRpcMethodsViaWs , getRuntimeVersionViaWs } from './util/index.js' ;
3637
3738interface SectionItem {
3839 link ?: string ;
@@ -318,6 +319,63 @@ function addRuntime (_runtimeDesc: string, registry: Registry): string {
318319 } ) ;
319320}
320321
322+ /** @internal */
323+ function addLegacyRuntime ( _runtimeDesc : string , _registry : Registry , apis ?: ApiDef [ ] ) {
324+ return renderPage ( {
325+ description : 'The following section contains known runtime calls that may be available on specific runtimes (depending on configuration and available pallets). These call directly into the WASM runtime for queries and operations.' ,
326+ sections : Object
327+ . keys ( definitions )
328+ . filter ( ( key ) => Object . keys ( definitions [ key as 'babe' ] . runtime || { } ) . length !== 0 )
329+ . sort ( )
330+ . reduce ( ( all : Section [ ] , _sectionName ) : Section [ ] => {
331+ Object
332+ . entries ( definitions [ _sectionName as 'babe' ] . runtime || { } )
333+ . forEach ( ( [ apiName , versions ] ) => {
334+ versions
335+ . sort ( ( a , b ) => b . version - a . version )
336+ . forEach ( ( { methods, version } , index ) => {
337+ if ( apis ) {
338+ // if we are passing the api hashes and we cannot find this one, skip it
339+ const apiHash = blake2AsHex ( apiName , 64 ) ;
340+ const api = apis . find ( ( [ hash ] ) => hash === apiHash ) ;
341+
342+ if ( ! api || api [ 1 ] !== version ) {
343+ return ;
344+ }
345+ } else if ( index ) {
346+ // we only want the highest version
347+ return ;
348+ }
349+
350+ const container : Section = { items : [ ] , name : apiName } ;
351+
352+ all . push ( container ) ;
353+
354+ Object
355+ . entries ( methods )
356+ . sort ( ( [ a ] , [ b ] ) => a . localeCompare ( b ) )
357+ . forEach ( ( [ methodName , { description, params, type } ] ) : void => {
358+ const args = params . map ( ( { name, type } ) : string => {
359+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
360+ return name + ': `' + type + '`' ;
361+ } ) . join ( ', ' ) ;
362+
363+ container . items . push ( {
364+ interface : '`' + `api.call.${ stringCamelCase ( apiName ) } .${ stringCamelCase ( methodName ) } ` + '`' ,
365+ name : `${ stringCamelCase ( methodName ) } (${ args } ): ${ '`' + type + '`' } ` ,
366+ runtime : '`' + `${ apiName } _${ methodName } ` + '`' ,
367+ summary : description
368+ } ) ;
369+ } ) ;
370+ } ) ;
371+ } ) ;
372+
373+ return all ;
374+ } , [ ] ) . sort ( sortByName ) ,
375+ title : 'Runtime'
376+ } ) ;
377+ }
378+
321379/** @internal */
322380function addConstants ( runtimeDesc : string , { lookup, pallets } : MetadataLatest ) : string {
323381 return renderPage ( {
@@ -504,28 +562,40 @@ function writeFile (name: string, ...chunks: any[]): void {
504562 writeStream . end ( ) ;
505563}
506564
507- interface ArgV { chain ?: string ; endpoint ?: string ; }
565+ interface ArgV { chain ?: string ; endpoint ?: string ; metadataVer ?: number ; }
508566
509567async function mainPromise ( ) : Promise < void > {
510- const { chain, endpoint } = yargs ( hideBin ( process . argv ) ) . strict ( ) . options ( {
568+ const { chain, endpoint, metadataVer } = yargs ( hideBin ( process . argv ) ) . strict ( ) . options ( {
511569 chain : {
512570 description : 'The chain name to use for the output (defaults to "Substrate")' ,
513571 type : 'string'
514572 } ,
515573 endpoint : {
516574 description : 'The endpoint to connect to (e.g. wss://kusama-rpc.polkadot.io) or relative path to a file containing the JSON output of an RPC state_getMetadata call' ,
517575 type : 'string'
576+ } ,
577+ metadataVer : {
578+ description : 'The metadata version to use for generating type information. This will use state_call::Metadata_metadata_at_version to query metadata' ,
579+ type : 'number'
518580 }
519581 } ) . argv as ArgV ;
520582
583+ /**
584+ * This is unique to when the endpoint arg is used. Since the endpoint requires us to query the chain, it may query the chains
585+ * rpc state_getMetadata method to get metadata, but this restricts us to v14 only. Therefore we must also check if the `metadataVer` is passed
586+ * in as well. These checks will help us decide if we are using v14 or newer.
587+ */
588+ const useV14Metadata = endpoint && ( ( metadataVer && metadataVer < 15 ) || ! metadataVer ) ;
521589 const chainName = chain || 'Substrate' ;
522590 let metaHex : HexString ;
523591 let rpcMethods : string [ ] | undefined ;
592+ let runtimeApis : ApiDef [ ] | undefined ;
524593
525594 if ( endpoint ) {
526595 if ( endpoint . startsWith ( 'wss://' ) || endpoint . startsWith ( 'ws://' ) ) {
527- metaHex = await getMetadataViaWs ( endpoint ) ;
596+ metaHex = await getMetadataViaWs ( endpoint , metadataVer ) ;
528597 rpcMethods = await getRpcMethodsViaWs ( endpoint ) ;
598+ runtimeApis = await getRuntimeVersionViaWs ( endpoint ) ;
529599 } else {
530600 metaHex = (
531601 JSON . parse (
@@ -544,9 +614,16 @@ async function mainPromise (): Promise<void> {
544614 metaHex = substrateMeta ;
545615 }
546616
617+ let metadata : Metadata ;
547618 const registry = new TypeRegistry ( ) ;
548- const opaqueMetadata = registry . createType ( 'Option<OpaqueMetadata>' , registry . createType ( 'Raw' , metaHex ) . toU8a ( ) ) . unwrap ( ) ;
549- const metadata = new Metadata ( registry , opaqueMetadata . toHex ( ) ) ;
619+
620+ if ( useV14Metadata ) {
621+ metadata = new Metadata ( registry , metaHex ) ;
622+ } else {
623+ const opaqueMetadata = registry . createType ( 'Option<OpaqueMetadata>' , registry . createType ( 'Raw' , metaHex ) . toU8a ( ) ) . unwrap ( ) ;
624+
625+ metadata = new Metadata ( registry , opaqueMetadata . toHex ( ) ) ;
626+ }
550627
551628 registry . setMetadata ( metadata ) ;
552629
@@ -556,7 +633,9 @@ async function mainPromise (): Promise<void> {
556633
557634 writeFile ( `${ docRoot } /rpc.md` , addRpc ( runtimeDesc , rpcMethods ) ) ;
558635
559- writeFile ( `${ docRoot } /runtime.md` , addRuntime ( runtimeDesc , registry ) ) ;
636+ useV14Metadata
637+ ? writeFile ( `${ docRoot } /runtime.md` , addLegacyRuntime ( runtimeDesc , registry , runtimeApis ) )
638+ : writeFile ( `${ docRoot } /runtime.md` , addRuntime ( runtimeDesc , registry ) ) ;
560639
561640 writeFile ( `${ docRoot } /constants.md` , addConstants ( runtimeDesc , latest ) ) ;
562641 writeFile ( `${ docRoot } /storage.md` , addStorage ( runtimeDesc , latest ) ) ;
0 commit comments