diff --git a/bridges/relays/client-substrate/Cargo.toml b/bridges/relays/client-substrate/Cargo.toml
index 4dd797528040970622617b683d955676edc9a908..359f049d9dbd0994c9f12b2c4b1ba755808a99be 100644
--- a/bridges/relays/client-substrate/Cargo.toml
+++ b/bridges/relays/client-substrate/Cargo.toml
@@ -39,6 +39,7 @@ pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "ma
 sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/bridges/relays/client-substrate/src/client.rs b/bridges/relays/client-substrate/src/client.rs
index a1c8a22be19d00b2ceaa453444dc0f4ccd1de0a0..8a0875a89763ef6575b6895f6ccff5bf8192f37e 100644
--- a/bridges/relays/client-substrate/src/client.rs
+++ b/bridges/relays/client-substrate/src/client.rs
@@ -52,6 +52,8 @@ use sp_version::RuntimeVersion;
 use std::future::Future;
 
 const SUB_API_GRANDPA_AUTHORITIES: &str = "GrandpaApi_grandpa_authorities";
+const SUB_API_GRANDPA_GENERATE_KEY_OWNERSHIP_PROOF: &str =
+	"GrandpaApi_generate_key_ownership_proof";
 const SUB_API_TXPOOL_VALIDATE_TRANSACTION: &str = "TaggedTransactionQueue_validate_transaction";
 const SUB_API_TX_PAYMENT_QUERY_INFO: &str = "TransactionPaymentApi_query_info";
 const MAX_SUBSCRIPTION_CAPACITY: usize = 4096;
@@ -713,6 +715,23 @@ impl<C: Chain> Client<C> {
 		Ok(Subscription(Mutex::new(receiver)))
 	}
 
+	// TODO: remove warning after implementing
+	// https://github.com/paritytech/parity-bridges-common/issues/39
+	#[allow(dead_code)]
+	async fn generate_grandpa_key_ownership_proof(
+		&self,
+		at: HashOf<C>,
+		set_id: sp_consensus_grandpa::SetId,
+		authority_id: sp_consensus_grandpa::AuthorityId,
+	) -> Result<Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof>> {
+		self.typed_state_call(
+			SUB_API_GRANDPA_GENERATE_KEY_OWNERSHIP_PROOF.into(),
+			(set_id, authority_id),
+			Some(at),
+		)
+		.await
+	}
+
 	/// Execute jsonrpsee future in tokio context.
 	async fn jsonrpsee_execute<MF, F, T>(&self, make_jsonrpsee_future: MF) -> Result<T>
 	where