I want to add my chain types to the Polkadot-js/apps
in order to reflect the changes on frontend. I've tried generating types using this tutorial, but I've no idea how can I use them in Polkadot-js/apps
for my custom chain. If anyone could point to a tutorial or an implementation to this, that'd be super helpful.
Thank you.
1 Answer
In the Usage section of the Polkadot.js typegen tutorial it first shows how to extract the types from your custom type definitions, for example see how the Edgeware team releases versions their types for the community here, then when they create an instance of the API they introduce the types registry to inject the types and override existing types as described here so the API understands the types from the metadata.
For example, if you built your custom chain using the substrate-node-template but you changed the implementation so the default Balance type of u128
here became u64
instead, then you would create the instance of your API with:
import { ApiPromise, WsProvider } from '@polkadot/api';
const wsProvider = new WsProvider('ws://127.0.0.1:9944');
const api = await ApiPromise.create({
provider: wsProvider,
types: {
Balance: 'u64'
}
});
Alternatively you could create it using the syntax const api = new ApiPromise({ provider: wsProvider, types: { ... } });
as mentioned here.
So if you were building your frontend based on the substrate-front-end-template then you would add those custom types here where they create the instance of the API.
As mentioned at https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/settings/developer, if you are a development team with at least a test network that is available and listed at https://polkadot.js.org/apps, then you could consider modifying the apps-config package and creating a Pull Request into the https://github.com/polkadot-js repository to add the types directly so they would be automatically configured when anyone tried to connect to it.
Or if you just wanted to interact with your custom Substrate node running on your local machine you could just go to: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/settings/developer, paste your additional types, and then press the Save button.
For example, below is an example of the custom types you might paste to be compatible with a recent release of the Polkadot.js API where you could add the correct AccountInfo
type for your chain, such as providing a value of AccountInfoWithDualRefCount
if your custom chain uses the old-style double refcount (with 4 bytes missing) if the API defaulted to more recent triple refcount.
In the example below we have also assumed that the custom chain uses a custom Balance
type of u64
, an Address
type of MultiAddress
as shown here, and where a standalone chain is being used with two session keys (i.e. Grandpa, Aura) in the chain specification so custom Keys
type of SessionKeys2
is used.
If you were to modify your custom chain to use four session keys instead (i.e. Grandpa, Babe, ImOnline, AuthorityDiscovery) then you would change the value to SessionKeys4
.
{
AccountInfo: "AccountInfoWithDualRefCount",
Keys: "SessionKeys2",
Address: "MultiAddress",
LookupSource: "MultiAddress",
Balance: "u64",
UserInfo: {
"user_dna": "[u8; 16]"
"user_name": "Text",
"user_address": "AccountId",
"user_storage_hash": "Hash",
"user_dob": "Date",
"user_reward": "Balance",
"user_reward_at_block": "Moment"
}
}
If you created your chain based on the substrate-node-template and in runtime/lib.rs you added the following types to configure the pallet-template.
impl pallet_template::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
// https://polkadot.js.org/api/types
type UserDNA = [u8; 16];
type UserIndex = u64;
type UserName = Vec<u8>; // Text
type UserAddress = AccountId;
type UserExternalStorageHash = Hash;
// https://docs.rs/chrono/latest/chrono/
type UserDOB = i64;
// https://substrate.recipes/currency.html#just-plain-currency
type UserReward = Balance;
type UserRewardAtBlock = u64;
}
Then in pallets/template/src/lib.rs, you could use user-defined structs and use them to set and retrieve data from storage, as shown here in the Substrate kitties tutorial and elsewhere here.
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct User(pub [u8; 16]);
#[cfg_attr(feature = "std", derive(Debug))]
#[derive(Encode, Decode, Default, Clone, PartialEq)]
// Generic type parameters
pub struct UserInfo<U, V, W, X, Y, Z> {
pub user_name: U, // Text
pub user_address: V, // AccountId
pub user_storage_hash: W, // Hash
pub user_dob: X, // i64
pub user_reward: Y, // Balance
pub user_reward_at_block: Z // u64
}
-
Thank you for your detailed answer. But, I'd want the types generated from
typegen
to be used in thepolkadot-js/apps/packages/apps-config/src/api/typesBundle.ts
instead of theDeveloper
tab on explorer. Can you please explain how would I do that?– DiscardoCommented Feb 8, 2023 at 5:49 -
There are example PRs with "custom types" here: github.com/polkadot-js/apps/pulls?q=is%3Apr+custom+types Commented Feb 8, 2023 at 9:50
-
At that link the best PR is by InterBTC github.com/polkadot-js/apps/pull/6779/files where they import custom types from NPM npmjs.com/package/@interlay/interbtc-types. PRs by Spartan, Subspace, KILT, and BitCountry are also good. You can't fetch from external json file like I did in this PR here github.com/polkadot-js/apps/pull/3084. Specify
minmax
for the metadataOverrideVersionedType
(i.e. where min (v >= min) and max (v <= max)). Note that typesBundle.ts file is automatically generated by runningyarn run build:extra
Commented Feb 8, 2023 at 10:10 -
-