⚠️Blast API (blastapi.io) ends Oct 31. Migrate to Dwellir and skip the expensive compute units.
Switch Today →
Skip to main content

author_submitAndWatchExtrinsic - JSON-RPC Method

Description

Submits an extrinsic and returns a subscription ID to receive real-time status updates about the transaction's lifecycle. This JSON-RPC method is only available via WebSocket connections and provides notifications when the transaction enters the pool, gets included in a block, and becomes finalized.

Parameters

ParameterTypeRequiredDescription
extrinsicstringYesHex-encoded signed extrinsic to submit and watch

Returns

FieldTypeDescription
resultstringSubscription ID for receiving status updates

Subscription Updates

The subscription will emit the following status updates:

StatusDescription
readyTransaction is in the ready queue
broadcastTransaction has been broadcast to peers
inBlockTransaction included in a block (with block hash)
retractedTransaction was retracted (with block hash)
finalityTimeoutMaximum finality timeout reached
finalizedTransaction is finalized (with block hash)
usurpedTransaction was usurped by another
droppedTransaction dropped from the pool
invalidTransaction is invalid

Request Example

{
"jsonrpc": "2.0",
"method": "author_submitAndWatchExtrinsic",
"params": [
"0x450284008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48..."
],
"id": 1
}

Response Example

{
"jsonrpc": "2.0",
"result": "CWz4K7hQdp8xFhS",
"id": 1
}

Subscription Update Examples

// Ready status
{
"jsonrpc": "2.0",
"method": "author_extrinsicUpdate",
"params": {
"subscription": "CWz4K7hQdp8xFhS",
"result": "ready"
}
}

// In block status
{
"jsonrpc": "2.0",
"method": "author_extrinsicUpdate",
"params": {
"subscription": "CWz4K7hQdp8xFhS",
"result": {
"inBlock": "0x5d83e66b61701da7b6e3e8c9d8e2e57e1391e3e58e677b30e1f391d568c9ca24"
}
}
}

// Finalized status
{
"jsonrpc": "2.0",
"method": "author_extrinsicUpdate",
"params": {
"subscription": "CWz4K7hQdp8xFhS",
"result": {
"finalized": "0x5d83e66b61701da7b6e3e8c9d8e2e57e1391e3e58e677b30e1f391d568c9ca24"
}
}
}

Code Examples

JavaScript (WebSocket)

const WebSocket = require('ws');

const submitAndWatch = async (extrinsic) => {
const ws = new WebSocket('wss://api-polkadot.n.dwellir.com', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});

return new Promise((resolve, reject) => {
let subscriptionId;

ws.on('open', () => {
ws.send(JSON.stringify({
jsonrpc: '2.0',
method: 'author_submitAndWatchExtrinsic',
params: [extrinsic],
id: 1
}));
});

ws.on('message', (data) => {
const response = JSON.parse(data);

// Initial subscription response
if (response.id === 1) {
subscriptionId = response.result;
console.log('Watching transaction:', subscriptionId);
}

// Status updates
if (response.method === 'author_extrinsicUpdate') {
const status = response.params.result;
console.log('Status update:', status);

if (status.finalized) {
console.log('Transaction finalized in block:', status.finalized);
ws.close();
resolve(status.finalized);
}

if (status === 'dropped' || status === 'invalid') {
ws.close();
reject(new Error(`Transaction ${status}`));
}
}
});

ws.on('error', reject);
});
};

Python (websocket-client)

import json
import websocket

def submit_and_watch_extrinsic(extrinsic, api_key):
"""Submit extrinsic and watch its status"""

ws_url = "wss://api-polkadot.n.dwellir.com"
headers = {"Authorization": f"Bearer {api_key}"}

subscription_id = None
finalized_block = None

def on_message(ws, message):
nonlocal subscription_id, finalized_block
data = json.loads(message)

# Initial subscription
if data.get("id") == 1:
subscription_id = data["result"]
print(f"Watching: {subscription_id}")

# Status updates
if data.get("method") == "author_extrinsicUpdate":
status = data["params"]["result"]
print(f"Status: {status}")

if isinstance(status, dict):
if "finalized" in status:
finalized_block = status["finalized"]
print(f"Finalized in: {finalized_block}")
ws.close()
elif "inBlock" in status:
print(f"In block: {status['inBlock']}")
elif status in ["dropped", "invalid"]:
print(f"Transaction {status}")
ws.close()

def on_open(ws):
subscribe_msg = {
"jsonrpc": "2.0",
"method": "author_submitAndWatchExtrinsic",
"params": [extrinsic],
"id": 1
}
ws.send(json.dumps(subscribe_msg))

ws = websocket.WebSocketApp(
ws_url,
header=headers,
on_message=on_message,
on_open=on_open
)

ws.run_forever()
return finalized_block

TypeScript (@polkadot/api)

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

async function submitAndWatchExtrinsic() {
const provider = new WsProvider('wss://api-polkadot.n.dwellir.com');
const api = await ApiPromise.create({ provider });

// Create and sign transaction
const transfer = api.tx.balances.transfer(
'RECIPIENT_ADDRESS',
1000000000000
);

// Submit and watch
const unsub = await transfer.signAndSend(
sender,
({ status, events }) => {
if (status.isReady) {
console.log('Transaction is ready');
} else if (status.isBroadcast) {
console.log('Transaction has been broadcast');
} else if (status.isInBlock) {
console.log(`Transaction included in block: ${status.asInBlock}`);
} else if (status.isFinalized) {
console.log(`Transaction finalized: ${status.asFinalized}`);
unsub();
} else if (status.isDropped || status.isInvalid) {
console.error('Transaction failed');
unsub();
}
}
);
}

Use Cases

  1. Transaction Confirmation: Wait for finality before proceeding
  2. User Notifications: Update UI with real-time transaction status
  3. Automated Workflows: Trigger actions after transaction finalization
  4. Error Recovery: Handle failed transactions automatically
  5. Cross-chain Operations: Coordinate actions after confirmations

Notes

  • WebSocket connection required (not available via HTTPS)
  • Subscription automatically ends after finalization or failure
  • Use author_unwatchExtrinsic to manually unsubscribe
  • Consider network delays and finalization time (typically 12-60 seconds)
  • Handle connection drops and implement reconnection logic