Wallet & SDK Integration
Materios is a Substrate chain, but it is not a stock Substrate chain. Two deviations will break an integration that assumes the defaults, and both fail in ways that are easy to misdiagnose. Read this page before writing signing code.
Everything below was verified against live preprod on 2026-08-25.
Connection facts
RPC (WebSocket)
wss://materios.fluxpointstudios.com/preprod-rpc
Chain
Materios Preprod v6
Genesis hash
0x0e46e33f639a56cc8780fd871d9a15e16d99af248526f907cb560cb40849f7bf
Spec version
235
Transaction version
4
Block time
6 seconds
Finality
GRANDPA
system_properties.ss58Format
42
tokenSymbol / tokenDecimals
MATRA / 6
Preprod is a public testnet. The native token here is tMATRA and has no economic value. Mainnet parameters will differ; do not hardcode preprod values into a build you intend to point at mainnet.
Deviation 1 — the fee extension is ChargeMotra, not ChargeTransactionPayment
This is the one that breaks most clients.
Materios pays transaction fees in MOTRA, not MATRA, through a custom pallet. The runtime's signed extensions are:
CheckNonZeroSender, CheckSpecVersion, CheckTxVersion, CheckGenesis,
CheckMortality, CheckNonce, CheckWeight, ChargeMotraA stock Substrate chain ends that list with ChargeTransactionPayment, which carries a Compact<Balance> tip. ChargeMotra carries no tip field. There is nothing to encode in that position.
What breaks
Any client that hardcodes the default extension set — rather than reading the extension list out of chain metadata — will append a Compact<tip> that the runtime does not expect. The extra bytes shift the payload, the signature fails to verify, and every transaction is rejected, not just tipped ones.
polkadot-js
Works. It builds the extension list from metadata, so it picks up ChargeMotra automatically.
subxt
Breaks unless you define a custom SignedExtra. Its default assumes ChargeTransactionPayment.
txwrapper-core
Breaks. Its transaction construction assumes the default set.
py-substrate-interface
Breaks on the tip path. Do not pass a tip argument.
There is also no TransactionPaymentApi on this runtime. payment_queryInfo returns Method not found, so tx.paymentInfo() throws — do not call it to estimate fees, and do not treat the throw as a connectivity failure.
What to do
Build the signed extension set from chain metadata. Never hardcode it. This is the single change that makes most clients work.
Never set a tip. There is no field for one. Omit the parameter entirely rather than passing zero.
Do not call
paymentInfo(). Fee estimation goes through MOTRA; see below.
Deviation 2 — the SS58 prefix is reported two different ways
The chain reports two different SS58 prefixes depending on where you look:
system_properties.ss58Format→ 42 (the generic Substrate prefix)the runtime constant
System::SS58Prefix→ 0
Both refer to the same 32-byte public key. They produce different address strings for the same account, so a tool reading one source and a tool reading the other will disagree textually while being in perfect agreement about the underlying key.
This bites hardest in comparisons: an address that looks completely different from the one in your database may be the same account. A string equality check across two tools that chose different prefixes silently returns "no match" forever.
What to do
Treat the 32-byte public key as the account identity, not the encoded string.
Normalise before comparing. Decode to the public key, then re-encode to one prefix.
Display with prefix 42. That matches
system_properties, the explorer, and the gateway, so it is what users will see elsewhere.
The prefix split is a known inconsistency and is queued to be reconciled in a future runtime upgrade. Until then, normalise.
The two-token model
MATRA
6
Yes
Staking, governance, transfers, balances
MOTRA
15
No
Transaction fees only
MOTRA is a capacity token, not a currency. It is generated passively from the MATRA an account holds, decays if unused, and is burned when spent on fees. It cannot be transferred between accounts. The pattern mirrors NIGHT generating DUST on Midnight.
Consequences for a wallet:
tokenDecimalsinsystem_propertiesis 6 — that is MATRA only. MOTRA's 15 decimals are not advertised there. Formatting a MOTRA balance with 6 decimals overstates it by a factor of 10⁹.An account with MATRA but no MOTRA yet cannot transact. MOTRA accrues over blocks. A freshly funded account needs to wait before its first transaction, which looks like a bug if you are not expecting it.
A zero MATRA balance means MOTRA generation has stopped. Fee capacity is downstream of the MATRA holding, so a fully swept account cannot pay to move anything.
Fees never touch the MATRA supply. MOTRA is consumed; no MATRA is burned or minted by fee flow.
Verification checklist
Run these against a real connection before declaring an integration working. Each one targets a specific way this chain differs from the default.
Step 4 is not optional. The ChargeMotra failure is an encoding mismatch that only surfaces when the runtime verifies a real signature — every offline check passes right up until submission.
Getting test funds
The gateway exposes a faucet for preprod:
One drip per address. A second call returns Address already received a drip rather than topping up. After the drip, allow a few blocks for MOTRA to accrue before your first transaction.
Where to go next
Materios overview — architecture, pallets, current network parameters
Node requirements — running your own node or RPC endpoint
Cardano L1 anchoring — how Materios state settles to Cardano
If you hit something this page does not cover, open an issue on Flux-Point-Studios/docs — integration friction is worth documenting for the next team.
Last updated

