diff --git a/src/commands.rs b/src/commands.rs
index f419bf31866d46b3a4c0c9d4a919847b8257b869..dc2ab80a11f89c838bf0c569de0333179223443d 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -1,3 +1,4 @@
+pub mod account;
 pub mod collective;
 pub mod expire;
 pub mod identity;
diff --git a/src/commands/account.rs b/src/commands/account.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a04649c32764c02980a3e5616a73fb4f150ec1bb
--- /dev/null
+++ b/src/commands/account.rs
@@ -0,0 +1,28 @@
+use crate::*;
+
+use anyhow::Result;
+use sp_core::crypto::AccountId32;
+
+pub async fn get_balance(data: Data) -> Result<()> {
+	let account_id = data.address();
+	let account_info = get_account_info(data.client(), &account_id).await?;
+	if let Some(account_info) = account_info {
+		println!(
+			"{account_id} has {}",
+			data.format_balance(account_info.data.free)
+		);
+	} else {
+		println!("account {account_id} does not exist")
+	}
+	Ok(())
+}
+
+pub async fn get_account_info(
+	client: Client,
+	account_id: &AccountId32,
+) -> Result<Option<AccountInfo>> {
+	Ok(client
+		.storage()
+		.fetch(&runtime::storage().system().account(account_id), None)
+		.await?)
+}
diff --git a/src/commands/identity.rs b/src/commands/identity.rs
index 71562d9e3d44f0a6232ebe9dcd562b39883881f7..5f10aa622f47c497bd4efc4926968d3f993a7789 100644
--- a/src/commands/identity.rs
+++ b/src/commands/identity.rs
@@ -1,8 +1,11 @@
 use crate::indexer::*;
 use crate::*;
 
+use crate::commands::revocation::get_revoc_doc;
 use crate::runtime::runtime_types::common_runtime::entities::IdtyData;
 use crate::runtime::runtime_types::pallet_identity::types::*;
+use crate::runtime::runtime_types::sp_core::sr25519::Signature;
+use crate::runtime::runtime_types::sp_runtime::MultiSignature;
 use anyhow::{anyhow, Result};
 use sp_core::{crypto::AccountId32, sr25519::Pair};
 use std::str::FromStr;
@@ -106,14 +109,14 @@ pub async fn create_identity(
 	client: Client,
 	target: AccountId32,
 ) -> Result<TxProgress, subxt::Error> {
-	Ok(client
+	client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().create_identity(target),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await?)
+		.await
 }
 
 pub async fn confirm_identity(
@@ -121,12 +124,39 @@ pub async fn confirm_identity(
 	client: Client,
 	name: String,
 ) -> Result<TxProgress, subxt::Error> {
-	Ok(client
+	client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().confirm_identity(name),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await?)
+		.await
+}
+
+// TODO : use Result<TxProgress, subxt::Error> instead of Result<()>
+pub async fn revoke_identity(pair: Pair, client: Client, account_id: AccountId32) -> Result<()> {
+	let (idty_index, signature) = get_revoc_doc(&client, &pair).await?;
+
+	// Transform signature to MultiSignature
+	// TODO: this is a hack, we should be able to use the signature directly
+	let signature = Signature(signature.0);
+	let multisign = MultiSignature::Sr25519(signature);
+
+	client
+		.tx()
+		.sign_and_submit_then_watch(
+			&runtime::tx()
+				.identity()
+				.revoke_identity(idty_index, account_id, multisign),
+			&PairSigner::new(pair),
+			BaseExtrinsicParamsBuilder::new(),
+		)
+		.await?
+		.wait_for_in_block()
+		.await?
+		.wait_for_success()
+		.await?;
+
+	Ok(())
 }
diff --git a/src/commands/revocation.rs b/src/commands/revocation.rs
index a03dd9c33153379a033ef8ce378b6fe52a01c577..69a23041b00143a53d15233f22f78ff222712844 100644
--- a/src/commands/revocation.rs
+++ b/src/commands/revocation.rs
@@ -2,12 +2,22 @@ use crate::*;
 
 use anyhow::Result;
 use futures::join;
+use sp_core::sr25519::Signature;
 use sp_core::{sr25519::Pair, Encode, Pair as _};
 
-pub async fn gen_revoc_doc(api: &Client, pair: &Pair) -> Result<()> {
+pub async fn generate_revoc_doc(api: &Client, pair: &Pair) -> Result<()> {
+	let signature = get_revoc_doc(api, pair).await?.1;
+
+	println!("0x{}", hex::encode(signature));
+
+	Ok(())
+}
+
+pub async fn get_revoc_doc(api: &Client, pair: &Pair) -> Result<(u32, Signature)> {
 	let account_id: sp_core::crypto::AccountId32 = pair.public().into();
 	let addr_idty_index = runtime::storage().identity().identity_index_of(&account_id);
 	let addr_block_hash = runtime::storage().system().block_hash(0);
+	// Multiple fetches can be done in a single request.
 	let (idty_index, genesis_hash) = join!(
 		api.storage().fetch(&addr_idty_index, None,),
 		api.storage().fetch(&addr_block_hash, None)
@@ -17,7 +27,5 @@ pub async fn gen_revoc_doc(api: &Client, pair: &Pair) -> Result<()> {
 	let payload = (b"revo", genesis_hash, idty_index).encode();
 	let signature = pair.sign(&payload);
 
-	println!("0x{}", hex::encode(signature));
-
-	Ok(())
+	Ok((idty_index, signature))
 }
diff --git a/src/main.rs b/src/main.rs
index 00dfb471286846072dccb0cdc3170ca3e710fdd4..3f8ec7a72885e295886b96b4e7793e4f2de4ba5e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,17 +6,28 @@ mod keys;
 use clap::Parser;
 use codec::Encode;
 use keys::*;
+use serde::Deserialize;
 use sp_core::sr25519::Pair;
 use sp_core::H256;
 
 #[cfg(feature = "dev")]
-#[subxt::subxt(runtime_metadata_path = "res/metadata.scale")]
-pub mod runtime {}
+#[subxt::subxt(
+	runtime_metadata_path = "res/metadata.scale",
+	derive_for_all_types = "Debug"
+)]
+pub mod runtime {
+	// IF NEEDED
+	// #[subxt(substitute_type = "spcore::sr25519::Signature")]
+	// use crate::gdev::runtime_types::sp_core::sr25519::Signature;
+}
 
 pub type Client = subxt::OnlineClient<Runtime>;
 pub type AccountId = subxt::ext::sp_runtime::AccountId32;
 pub type TxInBlock = subxt::tx::TxInBlock<Runtime, Client>;
 pub type TxProgress = subxt::tx::TxProgress<Runtime, Client>;
+pub type Balance = u64;
+pub type AccountData = runtime::runtime_types::pallet_duniter_account::types::AccountData<Balance>;
+pub type AccountInfo = runtime::runtime_types::frame_system::AccountInfo<u32, AccountData>;
 
 pub enum Runtime {}
 impl subxt::config::Config for Runtime {
@@ -88,14 +99,25 @@ pub struct Data {
 	pub address: Option<AccountId>,
 	pub keypair: Option<Pair>,
 	pub idty_index: Option<u32>,
+	pub token_decimals: u32,
+	pub token_symbol: String,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct SystemProperties {
+	token_decimals: u32,
+	token_symbol: String,
 }
 
 // implement helper functions for Data
 impl Data {
-	/// constructor
+	/// --- constructor ---
 	pub fn new(args: Args) -> Self {
 		Self {
 			args,
+			token_decimals: 0,
+			token_symbol: "tokens".into(),
 			..Default::default()
 		}
 	}
@@ -111,7 +133,16 @@ impl Data {
 		self.keypair.clone().unwrap()
 	}
 	pub fn idty_index(&self) -> u32 {
-		self.idty_index.clone().unwrap()
+		self.idty_index.unwrap()
+	}
+	// --- methods ---
+	pub fn format_balance(&self, amount: Balance) -> String {
+		let base: u32 = 10;
+		format!(
+			"{} {}",
+			(amount as f32) / (base.pow(self.token_decimals) as f32),
+			self.token_symbol
+		)
 	}
 	// --- mutators ---
 	/// force an address if needed
@@ -161,6 +192,16 @@ impl Data {
 		);
 		Ok(self)
 	}
+	/// get properties
+	pub async fn fetch_system_properties(mut self) -> Result<Self, anyhow::Error> {
+		let system_properties = self.client().clone().rpc().system_properties().await?;
+		let system_properties = serde_json::from_value::<SystemProperties>(
+			serde_json::Value::Object(system_properties),
+		)?;
+		self.token_decimals = system_properties.token_decimals;
+		self.token_symbol = system_properties.token_symbol;
+		Ok(self)
+	}
 }
 
 /// track progress of transaction on the network
@@ -202,7 +243,7 @@ impl From<anyhow::Error> for GcliError {
 
 #[derive(Clone, Debug, clap::Subcommand, Default)]
 pub enum Subcommand {
-	// TODO flodef
+	/// Fetch account balance
 	#[default]
 	GetBalance,
 	/// Create and certify an identity
@@ -313,6 +354,8 @@ pub enum Subcommand {
 	},
 	/// Rotate and set session keys
 	UpdateKeys,
+	/// Revoke an identity
+	RevokeIdentity,
 }
 
 #[tokio::main(flavor = "current_thread")]
@@ -323,7 +366,15 @@ async fn main() -> Result<(), GcliError> {
 	let mut data = Data::new(args.clone());
 
 	match args.subcommand {
-		Subcommand::GetBalance => {}
+		Subcommand::GetBalance => {
+			data = data
+				.build_keypair()
+				.build_client()
+				.await
+				.fetch_system_properties()
+				.await?;
+			commands::account::get_balance(data).await?
+		}
 		Subcommand::CreateIdentity { target } => {
 			data = data.build_client().await.build_keypair();
 			let progress =
@@ -417,7 +468,7 @@ async fn main() -> Result<(), GcliError> {
 			.await?
 		}
 		Subcommand::GenRevocDoc => {
-			commands::revocation::gen_revoc_doc(
+			commands::revocation::generate_revoc_doc(
 				&Client::from_url(&args.url).await.unwrap(),
 				&get_keys(
 					args.secret_format,
@@ -611,6 +662,21 @@ async fn main() -> Result<(), GcliError> {
 		)
 		.await
 		.unwrap(),
+		Subcommand::RevokeIdentity => {
+			let (address, pair) = get_keys(
+				args.secret_format,
+				&args.address,
+				&args.secret,
+				NeededKeys::Secret,
+			)?;
+
+			commands::identity::revoke_identity(
+				pair.unwrap(),
+				Client::from_url(&args.url).await.unwrap(),
+				address.unwrap(),
+			)
+			.await?
+		}
 	}
 
 	Ok(())