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

bridge_grandpa_getProof - JSON-RPC Method

Description

bridge_grandpa_getProof assembles a GRANDPA finality proof for a bridged relay chain (Westend, Bridge Bulletin, or Snowbridge) using the headers tracked on Bridge Hub. Relayers call this method to fetch the justification and authority set proof required to submit finalized headers on the destination chain.

This RPC endpoint is enabled for bridge instances configured in Bridge Hub and mirrors the logic used by on-chain pallet_bridge_grandpa light clients.

Parameters

ParameterTypeRequiredDescription
bridgestringYesBridge instance identifier ("westend", "polkadot_bulletin", "snowbridge", etc.).
headerHashstringYesHex-encoded hash of the bridged relay-chain header you want to prove finalized.
bestKnownFinalizedstringNoOptional hash of the last header you already finalized on the target chain. Helps Bridge Hub return minimal proofs.

Returns

FieldTypeDescription
encodedHeaderstringSCALE-encoded header that should be submitted to the destination chain.
finalityProofobjectGRANDPA proof containing justification, authoritySetId, and authoritySetProof.
bestKnownFinalizedstringHash of the highest header Bridge Hub considers finalized for the requested bridge instance.
authoritiesarrayOptional list of authority IDs included when the validator set changes.

Request Example

{
"jsonrpc": "2.0",
"method": "bridge_grandpa_getProof",
"params": [
{
"bridge": "westend",
"headerHash": "0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1"
}
],
"id": 1
}

Response Example

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"encodedHeader": "0x04000000a1b5...",
"finalityProof": {
"justification": "0x3c0400ff...",
"authoritySetId": 42,
"authoritySetProof": [
"0x012345...",
"0x987654..."
]
},
"bestKnownFinalized": "0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1",
"authorities": [
"0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
"0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"
]
}
}

Code Examples

cURL

curl https://api-bridge-hub-polkadot.n.dwellir.com/YOUR_API_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "bridge_grandpa_getProof",
"params": [{
"bridge": "westend",
"headerHash": "0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1"
}],
"id": 42
}'

JavaScript (polkadot.js)

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

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

const proof = await api.rpc.bridgeGrandpa.getProof({
bridge: 'westend',
headerHash: '0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1'
});

console.log('Encoded header:', proof.encodedHeader.toHex());
console.log('Justification length:', proof.finalityProof.justification.length);

Python (substrate-interface)

from substrateinterface import SubstrateInterface

substrate = SubstrateInterface(
url="wss://api-bridge-hub-polkadot.n.dwellir.com/YOUR_API_KEY"
)

params = {
"bridge": "westend",
"headerHash": "0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1"
}

proof = substrate.rpc_request("bridge_grandpa_getProof", [params])

encoded_header = proof['result']['encodedHeader']
justification = proof['result']['finalityProof']['justification']
print("Encoded header:", encoded_header)
print("Justification bytes:", len(justification) // 2)

Rust (jsonrpsee)

use jsonrpsee::{rpc_params, ws_client::WsClientBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = WsClientBuilder::default()
.build("wss://api-bridge-hub-polkadot.n.dwellir.com/YOUR_API_KEY")
.await?;

let proof: serde_json::Value = client
.request(
"bridge_grandpa_getProof",
rpc_params![{"bridge": "westend", "headerHash": "0x8cf2d8b30b86c7a8123ed5a3b92fe74195117cf1999440db0b9c7df24b5e70f1"}]
)
.await?;

println!("Finality proof: {proof:#?}");
Ok(())
}

Usage Notes

  • Always submit proofs in order; Bridge Hub enforces forward-only finality updates per bridge.
  • If the validator set rotates, authoritySetProof and authorities are included so the destination chain can verify the new set.
  • Combine the response with bridge_messages_getProof when relaying messages tied to the same header.