Skip to content

Commit

Permalink
keyring: add nostr-keyring
Browse files Browse the repository at this point in the history
Closes #392

Signed-off-by: Yuki Kishimoto <[email protected]>
  • Loading branch information
yukibtc committed Jul 4, 2024
1 parent c8e3d5b commit 770d804
Show file tree
Hide file tree
Showing 12 changed files with 680 additions and 1 deletion.
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions crates/nostr-keyring/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "nostr-keyring"
version = "0.32.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"
15 changes: 15 additions & 0 deletions crates/nostr-keyring/README.md
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
25 changes: 25 additions & 0 deletions crates/nostr-keyring/examples/keyring.rs
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_keyring::prelude::*;

fn main() {
let mut keyring = NostrKeyring::open().unwrap();

let keys =
Keys::parse("nsec12kcgs78l06p30jz7z7h3n2x2cy99nw2z6zspjdp7qc206887mwvs95lnkx").unwrap();
let account = Account::new(
"Test",
keys.public_key(),
AccountSecretKey::Unencrypted(keys.secret_key().unwrap().clone()),
);
keyring.add_account(account).unwrap();

// Get accounts
for (index, account) in keyring.accounts().iter().enumerate() {
println!("Account #{index}:");
println!("- Name: {}", account.name());
println!("- Public Key: {}", account.public_key());
}
}
79 changes: 79 additions & 0 deletions crates/nostr-keyring/src/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

use std::cmp::Ordering;

use nostr::prelude::*;

/// Secret Key
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AccountSecretKey {
/// Encrypted
Encrypted(EncryptedSecretKey),
/// Unencrypted
Unencrypted(SecretKey),
}

/// Account
#[derive(Debug, Clone)]
pub struct Account {
pub(crate) name: String,
pub(crate) public_key: PublicKey,
pub(crate) secret_key: AccountSecretKey, // TODO: allow only encrypted secret key?
}

impl PartialEq for Account {
fn eq(&self, other: &Self) -> bool {
self.public_key == other.public_key
}
}

impl Eq for Account {}

impl PartialOrd for Account {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Account {
fn cmp(&self, other: &Self) -> Ordering {
// Sort ASC by name.
// If name are equals, sort by public key.
if self.name != other.name {
self.name.cmp(&other.name)
} else {
self.public_key.cmp(&other.public_key)
}
}
}

impl Account {
#[inline]
pub fn new<S>(name: S, public_key: PublicKey, secret_key: AccountSecretKey) -> Self
where
S: Into<String>,
{
Self {
name: name.into(),
public_key,
secret_key,
}
}

#[inline]
pub fn name(&self) -> &str {
&self.name
}

#[inline]
pub fn public_key(&self) -> &PublicKey {
&self.public_key
}

#[inline]
pub fn secret_key(&self) -> &AccountSecretKey {
&self.secret_key
}
}
12 changes: 12 additions & 0 deletions crates/nostr-keyring/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

pub const DEFAULT_FILE_NAME: &str = "keyring";
pub const EXTENSION: &str = "dat";

pub const ACCOUNT: u8 = 0x00;
pub const NAME: u8 = 0x01;
pub const PUBLIC_KEY: u8 = 0x02;
pub const SECRET_KEY_ENCRYPTED: u8 = 0x03;
pub const SECRET_KEY_UNENCRYPTED: u8 = 0x04;
Loading

0 comments on commit 770d804

Please sign in to comment.