diff --git a/.gitignore b/.gitignore
index d01bd1a..efe3eb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,4 +18,8 @@ Cargo.lock
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
\ No newline at end of file
+#.idea/
+
+# Added by cargo
+
+/target
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..a48a7ee
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "citrea-e2e"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+bollard = { version = "0.17.1" }
+bitcoin = { version = "0.32.2", features = ["serde", "rand"] }
+bitcoincore-rpc = { version = "0.18.0" }
+futures = "0.3"
+rand = "0.8"
+toml = "0.8.0"
+serde = { version = "1.0.192", default-features = false, features = ["alloc", "derive"] }
+serde_json = { version = "1.0", default-features = false }
+tokio = { version = "1.39", features = ["full"] }
+anyhow = { version = "1.0.68", default-features = false, features = ["std"] }
+tempfile = "3.8"
+async-trait = "0.1.71"
+
+[patch.crates-io]
+bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", rev = "0ae498d" }
\ No newline at end of file
diff --git a/src/bitcoin.rs b/src/bitcoin.rs
new file mode 100644
index 0000000..d75cebd
--- /dev/null
+++ b/src/bitcoin.rs
@@ -0,0 +1,366 @@
+use std::collections::HashSet;
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::time::{Duration, Instant};
+
+use anyhow::{bail, Context};
+use async_trait::async_trait;
+use bitcoin::Address;
+use bitcoin_da::service::{get_relevant_blobs_from_txs, FINALITY_DEPTH};
+use bitcoin_da::spec::blob::BlobWithSender;
+use bitcoincore_rpc::json::AddressType::Bech32m;
+use bitcoincore_rpc::{Auth, Client, RpcApi};
+use citrea_primitives::REVEAL_BATCH_PROOF_PREFIX;
+use futures::TryStreamExt;
+use tokio::process::Command;
+use tokio::sync::OnceCell;
+use tokio::time::sleep;
+
+use super::config::BitcoinConfig;
+use super::docker::DockerEnv;
+use super::framework::TestContext;
+use super::node::{LogProvider, Node, Restart, SpawnOutput};
+use super::Result;
+use crate::node::NodeKind;
+
+pub struct BitcoinNode {
+ spawn_output: SpawnOutput,
+ pub config: BitcoinConfig,
+ client: Client,
+ gen_addr: OnceCell
,
+ docker_env: Arc