Skip to content

Commit

Permalink
Merge 6e0c114 into 5ad60e7
Browse files Browse the repository at this point in the history
  • Loading branch information
FroVolod authored Jun 21, 2021
2 parents 5ad60e7 + 6e0c114 commit cb3dacd
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 34 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ on:
workflow_dispatch:
pull_request:
branches: [master]
push:
# push:
#Enable when testing release infrastructure on a branch.
branches: [master]
# branches: [master]
jobs:
create-release:
name: create-release
Expand All @@ -20,7 +20,7 @@ jobs:
- name: Get the release version from the tag
# if: env.NEAR_CLI_VERSION == ''
run: |
echo "NEAR_CLI_VERSION=0.1.2" >> $GITHUB_ENV
echo "NEAR_CLI_VERSION=0.1.3" >> $GITHUB_ENV
echo "version is: ${{ env.NEAR_CLI_VERSION }}"
- name: Create GitHub release
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ use async_recursion::async_recursion;
#[derive(Debug, Default, clap::Clap)]
pub struct CliFullAccessType {
#[clap(subcommand)]
next_action: Option<super::super::CliSkipNextAction>,
next_action: Option<super::super::super::CliSkipNextAction>,
}

#[derive(Debug)]
pub struct FullAccessType {
pub next_action: Box<super::super::NextAction>,
pub next_action: Box<super::super::super::NextAction>,
}

impl From<CliFullAccessType> for FullAccessType {
fn from(item: CliFullAccessType) -> Self {
let skip_next_action: super::super::NextAction = match item.next_action {
Some(cli_skip_action) => super::super::NextAction::from(cli_skip_action),
None => super::super::NextAction::input_next_action(),
let skip_next_action: super::super::super::NextAction = match item.next_action {
Some(cli_skip_action) => super::super::super::NextAction::from(cli_skip_action),
None => super::super::super::NextAction::input_next_action(),
};
Self {
next_action: Box::new(skip_next_action),
Expand Down Expand Up @@ -50,12 +50,12 @@ impl FullAccessType {
..prepopulated_unsigned_transaction
};
match *self.next_action {
super::super::NextAction::AddAction(select_action) => {
super::super::super::NextAction::AddAction(select_action) => {
select_action
.process(unsigned_transaction, network_connection_config)
.await
}
super::super::NextAction::Skip(skip_action) => {
super::super::super::NextAction::Skip(skip_action) => {
skip_action
.process(unsigned_transaction, network_connection_config)
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ pub struct CliFunctionCallType {
#[clap(long)]
method_names: Option<String>,
#[clap(subcommand)]
next_action: Option<super::super::CliSkipNextAction>,
next_action: Option<super::super::super::CliSkipNextAction>,
}

#[derive(Debug)]
pub struct FunctionCallType {
pub allowance: Option<near_primitives::types::Balance>,
pub receiver_id: near_primitives::types::AccountId,
pub method_names: Vec<String>,
pub next_action: Box<super::super::NextAction>,
pub next_action: Box<super::super::super::NextAction>,
}

impl From<CliFunctionCallType> for FunctionCallType {
Expand All @@ -46,9 +46,9 @@ impl From<CliFunctionCallType> for FunctionCallType {
}
None => FunctionCallType::input_method_names(),
};
let skip_next_action: super::super::NextAction = match item.next_action {
Some(cli_skip_action) => super::super::NextAction::from(cli_skip_action),
None => super::super::NextAction::input_next_action(),
let skip_next_action: super::super::super::NextAction = match item.next_action {
Some(cli_skip_action) => super::super::super::NextAction::from(cli_skip_action),
None => super::super::super::NextAction::input_next_action(),
};
Self {
allowance,
Expand Down Expand Up @@ -159,12 +159,12 @@ impl FunctionCallType {
..prepopulated_unsigned_transaction
};
match *self.next_action {
super::super::NextAction::AddAction(select_action) => {
super::super::super::NextAction::AddAction(select_action) => {
select_action
.process(unsigned_transaction, network_connection_config)
.await
}
super::super::NextAction::Skip(skip_action) => {
super::super::super::NextAction::Skip(skip_action) => {
skip_action
.process(unsigned_transaction, network_connection_config)
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl AddAccessKeyAction {
network_connection_config: Option<crate::common::ConnectionConfig>,
) -> crate::CliResult {
match self.permission {
AccessKeyPermission::FullAccessAction(full_access_type) => {
AccessKeyPermission::GrantFullAccess(full_access_type) => {
full_access_type
.process(
self.nonce,
Expand All @@ -76,7 +76,7 @@ impl AddAccessKeyAction {
)
.await
}
AccessKeyPermission::FunctionCallAction(function_call_type) => {
AccessKeyPermission::GrantFunctionCallAccess(function_call_type) => {
function_call_type
.process(
self.nonce,
Expand All @@ -93,32 +93,32 @@ impl AddAccessKeyAction {
#[derive(Debug, clap::Clap)]
pub enum CliAccessKeyPermission {
/// Предоставьте данные для ключа с function call
FunctionCallAction(self::function_call_type::CliFunctionCallType),
GrantFunctionCallAccess(self::function_call_type::CliFunctionCallType),
/// Предоставьте данные для ключа с полным доступом
FullAccessAction(self::full_access_type::CliFullAccessType),
GrantFullAccess(self::full_access_type::CliFullAccessType),
}

#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumMessage, EnumIter))]
pub enum AccessKeyPermission {
#[strum_discriminants(strum(message = "A permission with function call"))]
FunctionCallAction(self::function_call_type::FunctionCallType),
GrantFunctionCallAccess(self::function_call_type::FunctionCallType),
#[strum_discriminants(strum(message = "A permission with full access"))]
FullAccessAction(self::full_access_type::FullAccessType),
GrantFullAccess(self::full_access_type::FullAccessType),
}

impl From<CliAccessKeyPermission> for AccessKeyPermission {
fn from(item: CliAccessKeyPermission) -> Self {
match item {
CliAccessKeyPermission::FunctionCallAction(cli_function_call_type) => {
CliAccessKeyPermission::GrantFunctionCallAccess(cli_function_call_type) => {
let function_call_type =
self::function_call_type::FunctionCallType::from(cli_function_call_type);
AccessKeyPermission::FunctionCallAction(function_call_type)
AccessKeyPermission::GrantFunctionCallAccess(function_call_type)
}
CliAccessKeyPermission::FullAccessAction(cli_full_access_type) => {
CliAccessKeyPermission::GrantFullAccess(cli_full_access_type) => {
let full_access_type =
self::full_access_type::FullAccessType::from(cli_full_access_type);
AccessKeyPermission::FullAccessAction(full_access_type)
AccessKeyPermission::GrantFullAccess(full_access_type)
}
}
}
Expand All @@ -138,11 +138,11 @@ impl AccessKeyPermission {
.interact()
.unwrap();
match variants[select_permission] {
AccessKeyPermissionDiscriminants::FunctionCallAction => Self::from(
CliAccessKeyPermission::FunctionCallAction(Default::default()),
AccessKeyPermissionDiscriminants::GrantFunctionCallAccess => Self::from(
CliAccessKeyPermission::GrantFunctionCallAccess(Default::default()),
),
AccessKeyPermissionDiscriminants::FullAccessAction => {
Self::from(CliAccessKeyPermission::FullAccessAction(Default::default()))
AccessKeyPermissionDiscriminants::GrantFullAccess => {
Self::from(CliAccessKeyPermission::GrantFullAccess(Default::default()))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use std::io::Write;
use std::str::FromStr;

fn bip32path_to_string(bip32path: &slip10::BIP32Path) -> String {
const HARDEND: u32 = 1 << 31;

format!(
"m/{}",
(0..bip32path.depth())
.map(|index| {
let value = *bip32path.index(index).unwrap();
if value < HARDEND {
value.to_string()
} else {
format!("{}'", value - HARDEND)
}
})
.collect::<Vec<String>>()
.join("/")
)
}

/// Generate a key pair of secret and public keys (use it anywhere you need
/// Ed25519 keys)
#[derive(Debug, Default, clap::Clap)]
pub struct CliGenerateKeypair {
#[clap(subcommand)]
permission: Option<super::add_access_key::CliAccessKeyPermission>,
}

#[derive(Debug)]
pub struct GenerateKeypair {
pub permission: super::add_access_key::AccessKeyPermission,
}

impl From<CliGenerateKeypair> for GenerateKeypair {
fn from(item: CliGenerateKeypair) -> Self {
let permission: super::add_access_key::AccessKeyPermission = match item.permission {
Some(cli_permission) => {
super::add_access_key::AccessKeyPermission::from(cli_permission)
}
None => super::add_access_key::AccessKeyPermission::choose_permission(),
};
Self { permission }
}
}

impl GenerateKeypair {
pub async fn process(
self,
prepopulated_unsigned_transaction: near_primitives::transaction::Transaction,
network_connection_config: Option<crate::common::ConnectionConfig>,
) -> crate::CliResult {
let new_master_seed_phrase_words_count: usize = 12;
let seed_phrase_hd_path = slip10::BIP32Path::from_str("m/44'/397'/0'").unwrap();

let (master_seed_phrase, master_seed) = {
let mnemonic = bip39::Mnemonic::generate(new_master_seed_phrase_words_count)?;
let mut master_seed_phrase = String::new();
for (index, word) in mnemonic.word_iter().enumerate() {
if index != 0 {
master_seed_phrase.push(' ');
}
master_seed_phrase.push_str(word);
}
(master_seed_phrase, mnemonic.to_seed(""))
};
let derived_private_key = slip10::derive_key_from_path(
&master_seed,
slip10::Curve::Ed25519,
&seed_phrase_hd_path,
)
.map_err(|err| {
color_eyre::Report::msg(format!(
"Failed to derive a key from the master key: {}",
err
))
})?;

let secret_keypair = {
let secret = ed25519_dalek::SecretKey::from_bytes(&derived_private_key.key)?;
let public = ed25519_dalek::PublicKey::from(&secret);
ed25519_dalek::Keypair { secret, public }
};
let implicit_account_id = hex::encode(&secret_keypair.public);
let public_key_str = format!(
"ed25519:{}",
bs58::encode(&secret_keypair.public).into_string()
);
let secret_keypair_str = format!(
"ed25519:{}",
bs58::encode(&secret_keypair.to_bytes()).into_string()
);
let public_key = near_crypto::PublicKey::from_str(&public_key_str)?;

let buf = format!(
"{}",
serde_json::json!({
"master_seed_phrase": master_seed_phrase,
"seed_phrase_hd_path": bip32path_to_string(&seed_phrase_hd_path),
"account_id": implicit_account_id,
"public_key": public_key_str,
"private_key": secret_keypair_str,
})
);
let home_dir = dirs::home_dir().expect("Impossible to get your home dir!");
let file_name: std::path::PathBuf =
format!("{}.json", &prepopulated_unsigned_transaction.receiver_id).into();
let mut path = std::path::PathBuf::from(&home_dir);
path.push(crate::consts::DIR_NAME_KEY_CHAIN);
std::fs::create_dir_all(&path)?;
path.push(file_name);
if path.exists() {
return Err(color_eyre::Report::msg(format!(
"The file: {} already exists!",
&path.display()
)));
};
std::fs::File::create(&path)
.map_err(|err| color_eyre::Report::msg(format!("Failed to create file: {:?}", err)))?
.write(buf.as_bytes())
.map_err(|err| {
color_eyre::Report::msg(format!("Failed to write to file: {:?}", err))
})?;
println!(
"The data for the access key is saved in a file {}",
&path.display()
);

match self.permission {
super::add_access_key::AccessKeyPermission::GrantFullAccess(full_access_type) => {
full_access_type
.process(
0,
prepopulated_unsigned_transaction,
network_connection_config,
public_key,
)
.await
}
super::add_access_key::AccessKeyPermission::GrantFunctionCallAccess(
function_call_type,
) => {
function_call_type
.process(
0,
prepopulated_unsigned_transaction,
network_connection_config,
public_key,
)
.await
}
}
}
}
Loading

0 comments on commit cb3dacd

Please sign in to comment.