author_submitExtrinsic - Mythos RPC Method
Submit a signed extrinsic to Mythos for inclusion in a block. Broadcast transactions for token transfers, staking operations, governance votes, and smart contract calls.
Submits a fully signed extrinsic to Mythos for inclusion in a future block. The extrinsic enters the transaction pool and is propagated to other nodes. This is the primary method for broadcasting any on-chain operation, including balance transfers, staking, governance, and pallet interactions.
Why Mythos? Build on the gaming blockchain powering FIFA Rivals and NFL Rivals with World ID verification with World ID proof-of-humanity, Polkadot security, Snowbridge cross-chain bridge, and 1M+ downloads per title.
When to Use This Method
author_submitExtrinsic is essential for game studios, player-driven economy builders, and teams requiring verified human-only gameplay:
- Token Transfers -- Send native tokens or assets between accounts on Mythos
- Staking and Governance -- Submit staking nominations, validator operations, and governance votes for AAA gaming (FIFA Rivals, NFL Rivals, Pudgy Party), player-owned economies, and bot-resistant matchmaking
- Smart Contract Interaction -- Call ink! or EVM smart contracts deployed on the chain
- Automated Systems -- Build bots, keepers, and automated transaction pipelines that submit extrinsics programmatically
Code Examples
Common Use Cases
1. Transfer with Fee Pre-Check
Verify fees and balance before submitting a transfer:
import { ApiPromise, WsProvider, Keyring } from '@polkadot/api';
async function safeTransfer(api, sender, recipient, amount) {
const transfer = api.tx.balances.transferKeepAlive(recipient, amount);
// Step 1: Estimate fee
const info = await transfer.paymentInfo(sender.address);
const fee = info.partialFee.toBigInt();
console.log(`Estimated fee: ${info.partialFee.toHuman()}`);
// Step 2: Check balance
const account = await api.query.system.account(sender.address);
const free = account.data.free.toBigInt();
const existentialDeposit = api.consts.balances.existentialDeposit.toBigInt();
const totalCost = BigInt(amount) + fee;
if (free - totalCost < existentialDeposit) {
throw new Error(`Insufficient balance. Need ${totalCost}, have ${free}`);
}
// Step 3: Submit
const hash = await transfer.signAndSend(sender);
console.log(`Submitted: ${hash.toHex()}`);
return hash;
}2. Batch Transaction Submission
Submit multiple operations in a single extrinsic:
async function submitBatch(api, sender, calls) {
const batch = api.tx.utility.batchAll(calls);
// Estimate total fee
const info = await batch.paymentInfo(sender.address);
console.log(`Batch fee: ${info.partialFee.toHuman()} for ${calls.length} calls`);
// Submit with event tracking
return new Promise((resolve, reject) => {
batch.signAndSend(sender, ({ status, events, dispatchError }) => {
if (dispatchError) {
if (dispatchError.isModule) {
const decoded = api.registry.findMetaError(dispatchError.asModule);
reject(new Error(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`));
} else {
reject(new Error(dispatchError.toString()));
}
}
if (status.isFinalized) {
const successEvents = events.filter(({ event }) =>
api.events.system.ExtrinsicSuccess.is(event)
);
resolve({
blockHash: status.asFinalized.toHex(),
success: successEvents.length > 0,
events: events.length
});
}
});
});
}
// Usage: batch multiple transfers
const calls = [
api.tx.balances.transferKeepAlive(recipient1, amount1),
api.tx.balances.transferKeepAlive(recipient2, amount2),
api.tx.balances.transferKeepAlive(recipient3, amount3)
];
const result = await submitBatch(api, sender, calls);3. Nonce Management for Sequential Transactions
Submit multiple transactions in rapid succession with correct nonce handling:
async function submitSequential(api, sender, extrinsics) {
// Get the starting nonce
let nonce = await api.rpc.system.accountNextIndex(sender.address);
const hashes = [];
for (const ext of extrinsics) {
const hash = await ext.signAndSend(sender, { nonce });
hashes.push(hash.toHex());
console.log(`Submitted with nonce ${nonce}: ${hash.toHex()}`);
nonce = nonce.addn(1);
}
return hashes;
}Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| 1010 | Invalid Transaction | Check signature, nonce, era, and that the extrinsic is properly SCALE-encoded |
| 1010 (bad signature) | Signature verification failed | Ensure the signing key matches the sender account and the correct genesis hash was used |
| 1010 (outdated) | Nonce too low | The nonce has already been used -- query the current nonce and rebuild the extrinsic |
| 1010 (stale) | Mortality period expired | The extrinsic era has passed -- rebuild with a current era or use an immortal era |
| 1012 | Transaction pool full | The node's pool is at capacity -- retry later or increase tip |
| -32603 | Internal error | Node may be syncing or experiencing issues -- check node health |
Related Methods
author_pendingExtrinsics-- Check the transaction pool for pending extrinsicspayment_queryInfo-- Estimate fees before submittingsystem_accountNextIndex-- Get the next valid nonce for an accountstate_call-- Call runtime APIs (e.g., for nonce viaAccountNonceApi)chain_getBlock-- Verify extrinsic inclusion in a block
system_properties
Get chain properties on Mythos including token symbol, decimals, and the address-format prefix when the chain exposes one. Essential for token formatting, wallet configuration, and address handling.
author_pendingExtrinsics
Get pending extrinsics in the transaction pool on Mythos. Monitor mempool activity, verify transaction submission, and analyze network congestion.