Docs

author_submitAndWatchExtrinsic - Neuroweb RPC Method

Submit an extrinsic and subscribe to lifecycle status updates on Neuroweb. Track transactions from pool admission through finalization with real-time WebSocket events for decentralized knowledge graphs (DKG), verifiable AI, supply chain audits, and knowledge mining.

Submits a signed extrinsic to Neuroweb and returns a subscription that emits status updates as the transaction progresses through the lifecycle -- from entering the transaction pool, through block inclusion, to finalization. This is a WebSocket-only subscription method.

Why Neuroweb? Build on the decentralized AI blockchain powering 125M+ Knowledge Assets with MIT-awarded technology with OriginTrail DKG V8 with 500-1000x scalability, 40% of US imports secured, EVM compatibility, and Best Decentralized AI Project (MIT).

When to Use This Method

author_submitAndWatchExtrinsic is essential for AI developers, knowledge graph builders, and teams requiring verifiable AI solutions:

  • Transaction Lifecycle Tracking -- Receive real-time status events as your extrinsic moves from the pool into a block and reaches finality on Neuroweb
  • Confirmation Waiting -- Block until a transaction reaches a specific finality level (e.g., inBlock or finalized) before proceeding with dependent logic
  • Error Detection -- Detect dropped, invalid, or usurped transactions immediately instead of polling, critical for decentralized knowledge graphs (DKG), verifiable AI, supply chain audits, and knowledge mining
  • User-Facing Feedback -- Power progress indicators and toast notifications in dApp interfaces with granular status updates

Code Examples

Common Use Cases

1. Transaction Confirmation with Timeout

Wait for finalization with a configurable timeout to avoid hanging indefinitely:

JavaScript
import { ApiPromise, WsProvider, Keyring } from '@polkadot/api';

async function sendAndConfirm(api, sender, tx, timeoutMs = 120000) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      reject(new Error('Transaction confirmation timed out'));
    }, timeoutMs);

    tx.signAndSend(sender, ({ status, dispatchError, events }) => {
      if (dispatchError) {
        clearTimeout(timer);
        if (dispatchError.isModule) {
          const { docs, name, section } = api.registry.findMetaError(dispatchError.asModule);
          reject(new Error(`${section}.${name}: ${docs.join(' ')}`));
        } else {
          reject(new Error(dispatchError.toString()));
        }
      }

      if (status.isFinalized) {
        clearTimeout(timer);
        resolve({
          blockHash: status.asFinalized.toHex(),
          events: events.map((e) => `${e.event.section}.${e.event.method}`)
        });
      }
    }).catch((err) => {
      clearTimeout(timer);
      reject(err);
    });
  });
}

2. Batch Transaction Pipeline

Submit multiple extrinsics sequentially and track each one through finalization:

JavaScript
async function submitBatch(api, sender, calls) {
  const results = [];
  let nonce = (await api.rpc.system.accountNextIndex(sender.address)).toNumber();

  for (const call of calls) {
    const result = await new Promise((resolve, reject) => {
      call.signAndSend(sender, { nonce: nonce++ }, ({ status, dispatchError }) => {
        if (dispatchError) {
          const decoded = dispatchError.isModule
            ? api.registry.findMetaError(dispatchError.asModule)
            : { name: dispatchError.toString() };
          reject(new Error(`Dispatch error: ${decoded.name}`));
        }

        if (status.isFinalized) {
          resolve({ blockHash: status.asFinalized.toHex(), nonce: nonce - 1 });
        }
      });
    });
    results.push(result);
    console.log(`Tx nonce=${result.nonce} finalized in ${result.blockHash}`);
  }

  return results;
}

3. Reorg-Aware Event Handling

Handle block retractions gracefully, re-evaluating transaction inclusion after reorganizations:

JavaScript
async function sendWithReorgHandling(api, sender, tx) {
  let includedBlock = null;

  return new Promise((resolve, reject) => {
    tx.signAndSend(sender, ({ status, events }) => {
      if (status.isReady) {
        console.log('Transaction in ready queue');
      }

      if (status.isInBlock) {
        includedBlock = status.asInBlock.toHex();
        console.log(`Included in block: ${includedBlock}`);
      }

      if (status.isRetracted) {
        console.warn(`Block retracted: ${status.asRetracted.toHex()} -- waiting for re-inclusion`);
        includedBlock = null;
      }

      if (status.isFinalized) {
        console.log(`Finalized in block: ${status.asFinalized.toHex()}`);
        resolve({ finalized: status.asFinalized.toHex(), events });
      }

      if (status.isDropped || status.isInvalid) {
        reject(new Error(`Transaction ${status.type}`));
      }

      if (status.isUsurped) {
        reject(new Error(`Transaction usurped by ${status.asUsurped.toHex()}`));
      }
    });
  });
}

Status Flow

Text
              ┌─────────────────────────────────────┐
              │          future (nonce gap)          │
              └──────────────┬──────────────────────┘
                             │ nonce becomes current

 submit ──► ready ──► broadcast ──► inBlock ──► finalized ✓
              │                       │
              ├──► dropped ✗          ├──► retracted (reorg) ──► inBlock (re-included)
              ├──► invalid ✗          └──► finalityTimeout ✗
              └──► usurped ✗

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
1002Verification errorThe extrinsic has an invalid signature, wrong format, or failed validation -- re-sign and resubmit
1010Invalid transactionBad nonce, insufficient balance, or the call is not permitted -- check account state with system_accountNextIndex
1014Priority too lowTransaction pool rejected the extrinsic because a higher-priority transaction exists for the same nonce -- increase tip or wait
-32603Internal errorNode encountered an unexpected error -- retry after delay
Connection closedWebSocket droppedThe subscription is lost -- reconnect and check author_pendingExtrinsics or re-query chain state to determine transaction outcome
  • author_submitExtrinsic -- Submit an extrinsic without subscribing to status updates (fire-and-forget)
  • system_accountNextIndex -- Get the next valid nonce for an account, including pending pool transactions
  • author_pendingExtrinsics -- List all extrinsics currently in the transaction pool
  • payment_queryInfo -- Estimate the fee for an extrinsic before submission
  • chain_getFinalizedHead -- Get the hash of the latest finalized block