Newer
Older
Zeke Mostov
committed
import { Metadata } from '@polkadot/metadata';
import {
decorateConstants,
decorateExtrinsics,
} from '@polkadot/metadata/decorate';
import { Extrinsics } from '@polkadot/metadata/decorate/types';
import { Constants } from '@polkadot/metadata/decorate/types';
Zeke Mostov
committed
import { TypeRegistry } from '@polkadot/types';
import { getSpecTypes } from '@polkadot/types-known';
import memoizee from 'memoizee';
import {
KUSAMA_SS58_FORMAT,
POLKADOT_SS58_FORMAT,
WESTEND_SS58_FORMAT,
} from './constants';
/**
* JSON object of ChainProperties codec from `@polkadot/api`.
*/
export interface ChainProperties {
ss58Format: number;
tokenDecimals: number;
tokenSymbol: string;
}
* Hardcode some chain properties of known chains. These are normally returned
* by `system_properties` call, but since they don't change much, it's pretty
* safe to hardcode them.
*
* @ignore
* @todo Should we expose this publicly?
*/
const defaultChainProperties: Record<string, ChainProperties> = {
Kusama: {
ss58Format: KUSAMA_SS58_FORMAT,
tokenDecimals: 12,
tokenSymbol: 'KSM',
},
Polkadot: {
ss58Format: POLKADOT_SS58_FORMAT,
'Polkadot CC1': {
ss58Format: POLKADOT_SS58_FORMAT,
tokenDecimals: 12,
tokenSymbol: 'DOT',
},
Westend: {
ss58Format: WESTEND_SS58_FORMAT,
tokenDecimals: 12,
tokenSymbol: 'WND',
},
};
/**
* From a metadata hex string (for example returned by RPC), create a Metadata
* class instance. Metadata decoding is expensive, so this function is
* memoized.
* @param registry - The registry of the metadata.
* @param metadata - The metadata as hex string.
*/
function createMetadataUnmemoized(
registry: TypeRegistry,
metadataRpc: string
return new Metadata(registry, metadataRpc);
export const createMetadata = memoizee(createMetadataUnmemoized, {
length: 2,
});
/**
* From a metadata hex string (for example returned by RPC), create decorated
* modules with their calls (transactions).
* @param registry - The registry of the metadata.
* @param metadata - The metadata as hex string.
*/
export function createDecoratedTx(
registry: TypeRegistry,
metadataRpc: string
): Extrinsics {
const metadata = createMetadata(registry, metadataRpc);
return decorateExtrinsics(registry, metadata.asLatest, metadata.version);
}
/**
* From a metadata hex string (for example returned by RPC), create decorated
* modules with their constants.
*
* @param registry - The registry of the metadata.
* @param metadata - The metadata as hex string.
*/
export function createDecoratedConstants(
registry: TypeRegistry,
metadataRpc: string
): Constants {
return decorateConstants(
registry,
createMetadata(registry, metadataRpc).asLatest
);
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* Given a chain name, a spec name, and a spec version, return the
* corresponding type registry. This function only returns the correct type
* registry for the following chains:
* - Kusama,
* - Polkadot (incl. when running a dev node),
* - Westend.
* For other chains, please use `@polkadot/api`s `TypeRegistry` directly:
* `const registry = new TypeRegistry()`. If needed, you should also register
* your chain's custom types using `registry.register()`.
*
* @see https://github.com/polkadot-js/api/tree/master/packages/types-known
* @param chainName - The chain to create the type registry for. Returned by
* RPC `system_chain`.
* @param specName - The name of the runtime spec. Returned by RPC
* `state_getRuntimeVersion`.
* @param specVersion - The spec version of that chain for which we want to
* create a type registry. Returned by RPC `state_getRuntimeVersion`.
* @param metadataRpc - If you pass the optional `metadataRpc` argument, then
* this function will run `registry.setMetadata()`. **Important!** If you don't
* pass this argument, make sure to call `registry.setMetadata()` yourself!
*/
export function getRegistry(
chainName: 'Kusama' | 'Polkadot' | 'Polkadot CC1' | 'Westend',
specName: 'kusama' | 'polkadot' | 'westend',
specVersion: number,
metadataRpc?: string
): TypeRegistry {
const registry = new TypeRegistry();
// Register types specific to chain/runtimeVersion
registry.register(getSpecTypes(registry, chainName, specName, specVersion));
// Register the chain properties for this registry
registry.setChainProperties(
registry.createType('ChainProperties', defaultChainProperties[chainName])
);
if (metadataRpc) {
registry.setMetadata(createMetadata(registry, metadataRpc));
}
return registry;
}