The parser module (lib/parser.ts) provides utilities for working with Dedot client metadata, enabling the extrinsic builder to dynamically generate pallet and method options from chain metadata.
Generate a list of pallet options from chain metadata.
function createSectionOptions(
metadata: Metadata["latest"] | null
): { text: string; value: number; docs: string[] }[] | nullParameters:
metadata- The latest metadata from a Dedot client (client.metadata.latest)
Returns: Array of pallet options sorted alphabetically by name, or null if metadata is unavailable
Example:
import { createSectionOptions } from "@/lib/parser";
const client = await DedotClient.new("wss://rpc.polkadot.io");
const sections = createSectionOptions(client.metadata.latest);
// Returns array like:
// [
// { value: 4, text: "Balances", docs: ["The Balances pallet provides..."] },
// { value: 0, text: "System", docs: ["The System pallet provides..."] },
// { value: 25, text: "Utility", docs: ["A utility pallet..."] },
// ...
// ]
// Use in a select/dropdown
<Select>
{sections?.map(section => (
<SelectItem key={section.value} value={section.value.toString()}>
{section.text}
</SelectItem>
))}
</Select>Notes:
- Only returns pallets that have callable extrinsics (filters out pallets without
calls) - Results are sorted alphabetically by pallet name
- The
valueis the pallet index used for call encoding - The
docsarray contains pallet documentation from metadata
Generate a list of method options for a specific pallet.
function createMethodOptions(
client: DedotClient<PolkadotApi>,
sectionIndex: number
): { text: string; value: number }[] | nullParameters:
client- Connected Dedot client instancesectionIndex- The pallet index fromcreateSectionOptions
Returns: Array of method options, or null if pallet has no calls
Example:
import { createMethodOptions } from "@/lib/parser";
// Get methods for the Balances pallet (index 4)
const methods = createMethodOptions(client, 4);
// Returns array like:
// [
// { text: "transferAllowDeath", value: 0 },
// { text: "forceTransfer", value: 2 },
// { text: "transferKeepAlive", value: 3 },
// { text: "transferAll", value: 4 },
// ...
// ]Notes:
- Uses the client's registry to resolve the calls enum type
- The
valueis the method variant index used for call encoding - Method names are returned as-is from metadata (typically camelCase)
Get detailed type information for a specific type ID.
function getArgType(
client: DedotClient<PolkadotApi>,
typeId: number
): TypeDef | { type: "Enum"; value: { members: EnumMember[] } }Parameters:
client- Connected Dedot client instancetypeId- The type ID from metadata
Returns: Type definition details, with expanded enum members for enum types
Example:
import { getArgType } from "@/lib/parser";
// Get type info for MultiAddress (type ID 113)
const typeInfo = getArgType(client, 113);
// For an enum type, returns:
// {
// type: "Enum",
// value: {
// members: [
// { name: "Id", fields: [{ typeId: 0, typeName: "AccountId" }], index: 0 },
// { name: "Index", fields: [{ typeId: 114, typeName: "AccountIndex" }], index: 1 },
// { name: "Raw", fields: [{ typeId: 14, typeName: "Vec<u8>" }], index: 2 },
// ...
// ]
// }
// }To get the parameters for a specific method, you need to traverse the metadata:
function getMethodFields(client, palletIndex, methodIndex) {
// Find the pallet
const pallet = client.metadata.latest.pallets.find(
p => p.index === palletIndex
);
if (!pallet?.calls) return [];
// Get the calls type ID
const callsTypeId = typeof pallet.calls === "number"
? pallet.calls
: pallet.calls.typeId;
// Get the enum type definition
const palletCalls = client.registry.findType(callsTypeId);
if (palletCalls.typeDef.type !== "Enum") return [];
// Find the specific method variant
const method = palletCalls.typeDef.value.members.find(
m => m.index === methodIndex
);
if (!method) return [];
// Return the fields (parameters)
return method.fields.map((field, index) => ({
name: field.name || `arg${index}`,
typeId: field.typeId,
typeName: field.typeName || "",
}));
}Example usage:
// Get parameters for Balances::transferKeepAlive
const fields = getMethodFields(client, 4, 3);
// [
// { name: "dest", typeId: 113, typeName: "MultiAddress" },
// { name: "value", typeId: 6, typeName: "Compact<Balance>" }
// ]Complete example showing how to build a pallet/method selector:
import { useState, useMemo } from "react";
import { createSectionOptions, createMethodOptions } from "@/lib/parser";
function ExtrinsicSelector({ client }) {
const [selectedPallet, setSelectedPallet] = useState("");
const [selectedMethod, setSelectedMethod] = useState("");
// Get all pallets
const pallets = useMemo(() => {
if (!client?.metadata?.latest) return [];
return createSectionOptions(client.metadata.latest) || [];
}, [client]);
// Get methods for selected pallet
const methods = useMemo(() => {
if (!client || !selectedPallet) return [];
const palletIndex = parseInt(selectedPallet);
return createMethodOptions(client, palletIndex) || [];
}, [client, selectedPallet]);
// Reset method when pallet changes
useEffect(() => {
setSelectedMethod("");
}, [selectedPallet]);
return (
<div>
<Select value={selectedPallet} onValueChange={setSelectedPallet}>
{pallets.map(p => (
<SelectItem key={p.value} value={p.value.toString()}>
{p.text}
</SelectItem>
))}
</Select>
{selectedPallet && (
<Select value={selectedMethod} onValueChange={setSelectedMethod}>
{methods.map(m => (
<SelectItem key={m.value} value={m.value.toString()}>
{m.text}
</SelectItem>
))}
</Select>
)}
</div>
);
}Understanding the Dedot metadata structure helps when working with these APIs:
client.metadata.latest = {
pallets: [
{
index: number, // Pallet index
name: string, // Pallet name (e.g., "Balances")
calls: number | { typeId: number }, // Calls type ID
docs: string[], // Documentation
// ... other fields
},
// ...
],
types: [...], // Type registry
};
// Types are stored in the registry
client.registry.findType(typeId) = {
path: string[], // Type path (e.g., ["sp_runtime", "MultiAddress"])
params: TypeParam[], // Generic parameters
typeDef: TypeDef, // The type definition
docs: string[], // Type documentation
};