diff --git a/crates/chain/src/chain_oracle.rs b/crates/chain/src/chain_oracle.rs
new file mode 100644
index 00000000..ccf3bc09
--- /dev/null
+++ b/crates/chain/src/chain_oracle.rs
@@ -0,0 +1,162 @@
+use core::{convert::Infallible, marker::PhantomData};
+
+use alloc::collections::BTreeMap;
+use bitcoin::BlockHash;
+
+use crate::BlockId;
+
+/// Represents a service that tracks the best chain history.
+/// TODO: How do we ensure the chain oracle is consistent across a single call?
+/// * We need to somehow lock the data! What if the ChainOracle is remote?
+/// * Get tip method! And check the tip still exists at the end! And every internal call
+/// does not go beyond the initial tip.
+pub trait ChainOracle {
+ /// Error type.
+ type Error: core::fmt::Debug;
+
+ /// Get the height and hash of the tip in the best chain.
+ fn get_tip_in_best_chain(&self) -> Result