-
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #392 Signed-off-by: Yuki Kishimoto <[email protected]>
- Loading branch information
Showing
7 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "nostr-keyring" | ||
version = "0.29.0" | ||
edition = "2021" | ||
description = "Nostr Keyring" | ||
authors.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
license.workspace = true | ||
readme = "README.md" | ||
rust-version.workspace = true | ||
keywords = ["nostr", "keyring"] | ||
|
||
[dependencies] | ||
#keyring = "2.3" # TODO: use only for ios target? | ||
nostr = { workspace = true, default-features = false, features = ["std", "nip49"] } | ||
thiserror.workspace = true | ||
|
||
[target.'cfg(not(all(target_os = "android", target_os = "ios")))'.dependencies] | ||
dirs = "5.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Nostr Keyring | ||
|
||
Keyring for Nostr apps. | ||
|
||
## State | ||
|
||
**This library is in an ALPHA state**, things that are implemented generally work but the API will change in breaking ways. | ||
|
||
## Donations | ||
|
||
`rust-nostr` is free and open-source. This means we do not earn any revenue by selling it. Instead, we rely on your financial support. If you actively use any of the `rust-nostr` libs/software/services, then please [donate](https://rust-nostr.org/donate). | ||
|
||
## License | ||
|
||
This project is distributed under the MIT software license - see the [LICENSE](../../LICENSE) file for details |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2022-2023 Yuki Kishimoto | ||
// Copyright (c) 2023-2024 Rust Nostr Developers | ||
// Distributed under the MIT software license | ||
|
||
pub const ACCOUNT: u8 = 0; | ||
pub const NAME: u8 = 1; | ||
pub const ACCOUNT_KEY_UNENCRYPTED: u8 = 2; | ||
pub const ACCOUNT_KEY_ENCRYPTED: u8 = 3; | ||
pub const ACCOUNT_KEY_WATCH_ONLY: u8 = 4; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) 2022-2023 Yuki Kishimoto | ||
// Copyright (c) 2023-2024 Rust Nostr Developers | ||
// Distributed under the MIT software license | ||
|
||
use std::collections::BTreeSet; | ||
use std::fs; | ||
use std::path::{Path, PathBuf}; | ||
|
||
use thiserror::Error; | ||
|
||
pub(crate) const ACCOUNT_EXTENSION: &str = "ncryptsec"; | ||
pub(crate) const ACCOUNT_DOT_EXTENSION: &str = ".ncryptsec"; | ||
|
||
#[derive(Debug, Error)] | ||
pub enum Error { | ||
#[error(transparent)] | ||
IO(#[from] std::io::Error), | ||
#[error("Impossible to get file name")] | ||
FailedToGetFileName, | ||
} | ||
|
||
pub fn accounts_dir<P>(base_path: P) -> Result<PathBuf, Error> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let base_path: &Path = base_path.as_ref(); | ||
fs::create_dir_all(&base_path)?; | ||
|
||
let accounts_path: PathBuf = base_path.join("keys"); | ||
Ok(accounts_path) | ||
} | ||
|
||
pub fn get_accounts_list<P>(path: P) -> Result<BTreeSet<String>, Error> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let mut names: BTreeSet<String> = BTreeSet::new(); | ||
|
||
// Get and iterate all paths | ||
let paths = fs::read_dir(path)?; | ||
for path in paths { | ||
let path: PathBuf = path?.path(); | ||
|
||
// Check if path has file name | ||
if let Some(name) = path.file_name().and_then(|n| n.to_str()) { | ||
// Check if file name terminate with extension | ||
if name.ends_with(ACCOUNT_DOT_EXTENSION) { | ||
// Split file name and extension | ||
let mut split = name.split(ACCOUNT_DOT_EXTENSION); | ||
if let Some(value) = split.next() { | ||
names.insert(value.to_string()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Ok(names) | ||
} | ||
|
||
pub(crate) fn get_account_file<P, S>(base_path: P, name: S) -> Result<PathBuf, Error> | ||
where | ||
P: AsRef<Path>, | ||
S: Into<String>, | ||
{ | ||
let mut keychain_file: PathBuf = base_path.as_ref().join(name.into()); | ||
keychain_file.set_extension(ACCOUNT_EXTENSION); | ||
Ok(keychain_file) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright (c) 2022-2023 Yuki Kishimoto | ||
// Copyright (c) 2023-2024 Rust Nostr Developers | ||
// Distributed under the MIT software license | ||
|
||
use nostr::prelude::*; | ||
|
||
pub enum Version { | ||
V1, | ||
} | ||
|
||
pub struct NostrKeyringDat { | ||
version: Version, | ||
list: Vec<Account>, | ||
} | ||
|
||
pub struct Account { | ||
name: String, | ||
key: AccountKey, | ||
} | ||
|
||
pub enum AccountKey { | ||
Unencrypted(SecretKey), | ||
Encrypted(EncryptedSecretKey), | ||
WatchOnly(PublicKey), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright (c) 2022-2023 Yuki Kishimoto | ||
// Copyright (c) 2023-2024 Rust Nostr Developers | ||
// Distributed under the MIT software license | ||
|
||
#![forbid(unsafe_code)] | ||
#![warn(missing_docs)] | ||
#![warn(rustdoc::bare_urls)] | ||
|
||
//! Nostr Keyring | ||
// * Save in OS keyring? | ||
// * Save in ~/.nostr/accounts.dat or ~/.nostr/keys.dat | ||
|
||
use std::collections::BTreeMap; | ||
use std::path::{Path, PathBuf}; | ||
|
||
use nostr::prelude::*; | ||
use thiserror::Error; | ||
use crate::format::AccountKey; | ||
|
||
mod constants; | ||
mod dir; | ||
mod format; | ||
|
||
/// Nostr Keyring error | ||
#[derive(Debug, Error)] | ||
pub enum Error { | ||
/// Dir error | ||
#[error(transparent)] | ||
Dir(#[from] dir::Error), | ||
/// Can't get home directory | ||
#[error("Can't get home directory")] | ||
CantGetHomeDir, | ||
} | ||
|
||
pub enum Version { | ||
V1, | ||
} | ||
|
||
pub struct NostrKeyring { | ||
path: PathBuf, | ||
version: Version, | ||
accounts: BTreeMap<String, AccountKey>, | ||
} | ||
|
||
impl NostrKeyring { | ||
/// Get list of available accounts | ||
#[cfg(not(all(target_os = "android", target_os = "ios")))] | ||
pub fn open() -> Result<Self, Error> { | ||
let home_dir: PathBuf = dirs::home_dir().ok_or(Error::CantGetHomeDir)?; | ||
todo!() | ||
} | ||
|
||
/// Open Nostr Keyring from custom path | ||
pub fn open_in<P>(base_path: P) -> Result<Self, Error> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
todo!() | ||
} | ||
|
||
/// Create new empty nostr keyring | ||
/// | ||
/// Return error if already exists | ||
#[cfg(not(all(target_os = "android", target_os = "ios")))] | ||
pub fn create() -> Result<Self, Error> { | ||
let home_dir: PathBuf = dirs::home_dir().ok_or(Error::CantGetHomeDir)?; | ||
todo!() | ||
} | ||
|
||
/// Create new empty nostr keyring in custom path | ||
pub fn create_in<P>(base_path: P) -> Result<Self, Error> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
todo!() | ||
} | ||
|
||
/// Get list of available accounts | ||
#[inline(always)] | ||
pub fn list_accounts(&self) -> &BTreeMap<String, AccountKey> { | ||
&self.accounts | ||
} | ||
|
||
/// Add account | ||
#[inline(always)] | ||
pub fn add_account(&mut self, name: String, key: AccountKey) { | ||
self.accounts.insert(name, key); | ||
} | ||
|
||
/// Remove account from keyring | ||
#[inline(always)] | ||
pub fn remove_account(&mut self, name: &str) { | ||
self.accounts.remove(name); | ||
} | ||
|
||
/// Write keyring to file | ||
pub fn save(&self) -> Result<(), Error> { | ||
todo!() | ||
} | ||
} |