Extrinsics

Summary

There's no account/program-style instruction to hand-build (program_id + AccountMeta[] + opaque data). You call a pallet's dispatchable function directly through a typed API — the standard Substrate pattern api.tx.<pallet>.<call>(...args) — and the runtime resolves storage access itself. Everything below is the same for any Substrate/FRAME chain, not an EmpoorioChain invention.

Account/program chains require you to construct an Instruction — a program ID, an ordered AccountMeta array declaring which accounts are read, written, or must sign, and an opaque, program-defined byte array. EmpoorioChain has no equivalent of that model, and it shouldn't be translated: FRAME/Substrate chains don't have programs that a caller addresses by account, and there's no upfront account-locking list a client needs to assemble by hand.

The api.tx.<pallet>.<call>() pattern

Instead, you call a pallet's dispatchable function ("call") directly, with typed arguments, through @polkadot/api (or a client library built on top of it). This is generic Substrate/FRAME tooling, not something EmpoorioChain customizes, so treat the Polkadot SDK's extrinsics documentation as the canonical reference for the mechanics — the example below just shows the shape of it against a real, confirmed EmpoorioChain extrinsic.

Native transfer via @polkadot/api
import { ApiPromise, WsProvider } from "@polkadot/api";
import { Keyring } from "@polkadot/keyring";
const api = await ApiPromise.create({
provider: new WsProvider(endpoint) // no single endpoint is currently published as stable — see Network status
});
const keyring = new Keyring({ type: "sr25519" });
const sender = keyring.addFromUri(mnemonicOrSeed);
// pallet: balances, call: transfer_allow_death
// (camelCase in @polkadot/api, snake_case as the on-chain call name)
const tx = api.tx.balances.transferAllowDeath(recipientAddress, amount);
const hash = await tx.signAndSend(sender);

balances.transfer_allow_death is one of the extrinsics with a real, measured testnet fee (0.000025 DMS) — see Fees. The same api.tx.<pallet>.<call>() pattern is how every other pallet call works: swap the pallet and call name, and pass that call's own typed arguments.

Because a call is typed rather than an opaque byte array, @polkadot/api resolves the correct argument types and call metadata by connecting to a live node and reading its runtime metadata (state_getMetadata) — there's no separate discriminator or account-list step to construct yourself.

Real SDKs that wrap this pattern

  • TypeScript — @empoorio/sdk: depends on @polkadot/api, @polkadot/keyring, and @polkadot/util-crypto, and ships a CLI binary, empoorio-sdk, for common operations without writing code directly (for example empoorio-sdk transfer --ws <endpoint> ...). Its package.json license is UNLICENSED and there's no publish workflow in the repo, so don't assume npm install @empoorio/sdk resolves from the public registry — build from source until that's confirmed.
  • Rust — empoorio-sdk: built on subxt, the standard type-safe Substrate client library, which generates the same api.tx()-style typed call interface from chain metadata. No crates.io publication has been confirmed either — treat as workspace-local until verified. (Don't confuse it with the separate emp-cli crate, whose installed binary is ecc.)
  • Dart — empoorio_chain_sdk: uses polkadart for the native side and web3dart for EVM. This is the SDK behind Eoonia Wallet's on-chain calls, and its native-call bindings are code-generated directly from live chain metadata rather than hand-written. Not yet published to pub.dev per its own README's conditional phrasing.

Don't copy an exact extrinsic name or argument list from documentation without checking it against a live node's metadata first. At least one pallet with a documented custom extrinsic list — pallet-emp-assets at runtime index 23 — actually resolves to upstream Parity pallet-assets under a workspace dependency alias, so its real call surface may not match older documentation. Call api.rpc.state.getMetadata() (or the equivalent in your SDK) against a live node before publishing or relying on a specific call signature.

Calling into the EVM side instead

If you're deploying Solidity through the EVM pallet rather than calling a native pallet, you don't use api.tx at all — you use standard Ethereum tooling (Hardhat, Foundry, ethers.js, viem) against EmpoorioChain's Ethereum-compatible JSON-RPC endpoint. See Programs for how the two models coexist.

Is this page helpful?

Tabla de Contenidos

Editar Página