Registering a Dialect

registerDialect(vm, factory) to install a dialect under a new vm token — the same registry inversion as custom providers — with the vm whitelist opening automatically and the built-in evm/svm tokens now protected.

registerDialect installs a ChainDialect under a vm token. One call teaches the library about the chain, opens the vm whitelist to that token, and makes any Network on it a first-class network. This is the same registry inversion the custom providers use: Address resolves its dialect through the registry instead of a hardcoded switch, which is what lets a new chain be added without editing core.

Signature

register-dialect.ts
import { ChainDialect, registerDialect } from "wative-core";

class XvmDialect extends ChainDialect {
  /* ...the full contract... */
}

// One call teaches the library about "xvm" and opens the whitelist to that token.
registerDialect("xvm", () => new XvmDialect());

registerDialect(vm: string, factory: () => ChainDialect): void

ParameterTypeNotes
vmstringThe vm token. Normalized to a trimmed, lowercased form, so registerDialect("XVM", …) resolves for a later lookup of "xvm".
factory() => ChainDialectProduces the dialect. It is invoked to obtain a fresh instance each time a dialect is resolved.

A later registration for the same custom vm replaces the earlier one. Pass a factory (not an instance) so each resolution gets its own dialect.

The vm whitelist opens automatically

vm tokens are validated against a whitelist at every construction boundary. The token type is VmTokenChainVM | (string & {}) — so the built-in evm / svm / sui autocomplete while any registered string is still accepted. A token that is neither built in nor registered is refused.

registerDialect flips its token on. Before registering, constructing a Network with that vm throws PARAMETER_ERROR; afterwards it is accepted:

registered-vm-is-first-class.ts
import { Network } from "wative-core";

// After registerDialect("xvm", …):
const xnet = new Network({
  slug: "xvm-testnet",
  name: "XVM Testnet",
  chainId: 909090,
  rpcUrl: "https://rpc.xvm.example",
  nativeCurrency: { name: "XVM", symbol: "XVM", decimals: 9 },
  vm: "xvm",
});
// xnet.vm === "xvm"

// An unregistered vm is refused at construction:
new Network({
  slug: "nope-net",
  name: "Nope",
  chainId: 111111,
  rpcUrl: "https://nope.example",
  nativeCurrency: { name: "N", symbol: "N", decimals: 9 },
  vm: "totally-unregistered",
}); // throws WativeError("PARAMETER_ERROR")

Built-in dialects are protected

The built-in evm and svm dialects register at module load and are immutable. A later attempt to re-register either token is refused:

builtin-protection.ts
registerDialect("evm", () => new MyEvmDialect());
// throws WativeError("PARAMETER_ERROR"):
//   The built-in "evm" dialect cannot be replaced.

Routing via Workspace and Address

Once a vm is registered, a Network declared on it behaves like any built-in network. Add it to a workspace and it is discoverable by slug; addresses created on that network delegate their signing, transaction building, and transfer lowering to the registered dialect.

workspace-with-custom-vm.ts
import { Workspace, Network } from "wative-core";

const ws = await Workspace.open({ path: "./my-wallet", password: "…" });

const xnet = new Network({
  slug: "xvm-testnet",
  name: "XVM Testnet",
  chainId: 909090,
  rpcUrl: "https://rpc.xvm.example",
  nativeCurrency: { name: "XVM", symbol: "XVM", decimals: 9 },
  vm: "xvm",
});
await ws.networks.add(xnet);

ws.networks.bySlug("xvm-testnet").vm; // "xvm"

await ws.lock();

Last updated on