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.
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 exampleempoorio-sdk transfer --ws <endpoint> ...). Itspackage.jsonlicense isUNLICENSEDand there's no publish workflow in the repo, so don't assumenpm install @empoorio/sdkresolves from the public registry — build from source until that's confirmed. - Rust —
empoorio-sdk: built onsubxt, the standard type-safe Substrate client library, which generates the sameapi.tx()-style typed call interface from chain metadata. Nocrates.iopublication has been confirmed either — treat as workspace-local until verified. (Don't confuse it with the separateemp-clicrate, whose installed binary isecc.) - Dart —
empoorio_chain_sdk: usespolkadartfor the native side andweb3dartfor 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?


