diff --git a/README.md b/README.md index 7bfc1dc662c7d506d573a80f3f66f621852baf85..38eb3a801b0c9dcd4f4974323548c194ff36c793 100644 --- a/README.md +++ b/README.md @@ -70,5 +70,7 @@ Secret key format can be changed using `--secret-format` with the following valu ## TODO - [x] implement config formatter -- [ ] add link/unlink account commands -- [ ] migrate all xt to submit_call_and_look_event \ No newline at end of file +- [x] add link/unlink account commands +- [ ] migrate all xt to submit_call_and_look_event +- [ ] add transfer with unit (ÄžD, UD...) +- [ ] \ No newline at end of file diff --git a/src/commands/account.rs b/src/commands/account.rs index dc86d706acaceeaa13d5121f537e6e4c2485ca5b..3d8844d96a2421dd31ef5038d3c3b26840bcb951 100644 --- a/src/commands/account.rs +++ b/src/commands/account.rs @@ -27,6 +27,8 @@ pub enum Subcommand { /// List of target addresses dests: Vec<AccountId>, }, + /// Unlink the account from the linked identity + Unlink, } /// handle account commands @@ -48,6 +50,9 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( Subcommand::TransferMultiple { amount, dests } => { commands::transfer::transfer_multiple(&data, amount, dests).await?; } + Subcommand::Unlink => { + unlink_account(&data).await?; + } }; Ok(()) @@ -78,3 +83,12 @@ pub async fn get_account_info( .fetch(&runtime::storage().system().account(account_id), None) .await } + +/// unlink account +pub async fn unlink_account(data: &Data) -> Result<(), subxt::Error> { + submit_call_and_look_event::< + runtime::account::events::AccountUnlinked, + StaticTxPayload<runtime::account::calls::UnlinkIdentity>, + >(data, &runtime::tx().account().unlink_identity()) + .await +} diff --git a/src/commands/identity.rs b/src/commands/identity.rs index 02f75fbbd0e34379a218f89a6e2e266b8b30e89e..b361755c51e571302d7315d91686724a5bb09ba0 100644 --- a/src/commands/identity.rs +++ b/src/commands/identity.rs @@ -3,7 +3,9 @@ use crate::*; use crate::{ commands::revocation::generate_revoc_doc, runtime::runtime_types::{ - common_runtime::entities::IdtyData, pallet_identity::types::*, sp_core::sr25519::Signature, + common_runtime::entities::{IdtyData, NewOwnerKeySignature}, + pallet_identity::types::*, + sp_core::sr25519::Signature, sp_runtime::MultiSignature, }, }; @@ -40,6 +42,11 @@ pub enum Subcommand { GenRevocDoc, /// Display member count MemberCount, + /// Link an account to the identity + LinkAccount { + /// address of the account that has to be linked + address: AccountId, + }, } /// handle identity commands @@ -88,6 +95,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( .unwrap() ) } + Subcommand::LinkAccount { address } => { + data = data.fetch_idty_index().await?; // idty index required for payload + link_account(&data, address).await?; + } }; Ok(()) @@ -258,3 +269,34 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> { } Ok(()) } + +type LinkAccountPayload = Vec<u8>; +/// generate link account document +pub fn generate_link_account( + data: &Data, + address: AccountId, +) -> (LinkAccountPayload, sp_core::sr25519::Signature) { + let payload = (b"link", data.genesis_hash, data.idty_index(), address).encode(); + let signature = data.keypair().sign(&payload); + (payload, signature) +} + +/// link an account to the identity +pub async fn link_account(data: &Data, address: AccountId) -> Result<(), subxt::Error> { + let (_payload, signature) = generate_link_account(&data, address.clone()); + + // this is a hack, see + // https://substrate.stackexchange.com/questions/10309/how-to-use-core-crypto-types-instead-of-runtime-types + let signature = Signature(signature.0); + + submit_call_and_look_event::< + runtime::account::events::AccountLinked, + StaticTxPayload<runtime::identity::calls::LinkAccount>, + >( + data, + &runtime::tx() + .identity() + .link_account(address, NewOwnerKeySignature(signature)), + ) + .await +} diff --git a/src/main.rs b/src/main.rs index e4c0b008508f7c00651d44bf841772ccc9bd8b9b..1c90aacc3cbf9037f90b0a032c2d2d89ffe1f39f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,7 +92,7 @@ pub enum Subcommand { Config(conf::Subcommand), } -/// maint function +/// main function #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), GcliError> { // init logger diff --git a/src/runtime_config.rs b/src/runtime_config.rs index d62c5e1172f96d69ab3eed69296462a8a4d0ff31..f0eff326e055c05bfad520b2ab9ffe7a5209b436 100644 --- a/src/runtime_config.rs +++ b/src/runtime_config.rs @@ -5,8 +5,8 @@ )] pub mod runtime { // IF NEEDED - // #[subxt(substitute_type = "spcore::sr25519::Signature")] - // use crate::gdev::runtime_types::sp_core::sr25519::Signature; + // #[subxt(substitute_type = "sp_core::sr25519::Signature")] + // use crate::runtime::runtime_types::sp_core::sr25519::Signature; } // declare custom types