Skip to content

Commit

Permalink
Improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
praveenperera committed Jul 28, 2024
1 parent 148f9a9 commit 0e5b19a
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords = ["bitcoin", "bip329", "labels"]
categories = ["bitcoin"]

[features]
default = ["encryption", "uniffi"]
default = ["encryption"]
encryption = ["dep:age", "dep:hex"]
uniffi = ["dep:uniffi"]

Expand Down
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
# bip329

A library for working with (BIP329 labels)[https://github.com/bitcoin/bips/blob/master/bip-00329.mediawiki].
A library for working with [BIP329 labels](https://github.com/bitcoin/bips/blob/master/bip-00329.mediawiki).

This library provides a way to work with BIP329 labels in a Rust program.

The main data structure is the `Labels` struct, which is a list of `Label` structs.
The main data structure is the [`Labels`] struct, which is a list of `Label` structs.

The `Label` enum is a discriminated union of all the different types of labels.
The [`Label`] enum is a discriminated union of all the different types of labels.

The `Labels` struct can be exported to a JSONL file.
The [`Labels`] struct can be exported to a JSONL file.

The `Labels` struct can be imported from a JSONL file.

Example Import:
The [`Labels`] struct can be imported from a JSONL file.

#### Example Import:
```rust
use bip329::Labels;

let labels = Labels::try_from_file("tests/data/labels.jsonl").unwrap();
```

Example Export:

#### Example Export:
```rust
use bip329::Labels;

Expand All @@ -30,7 +28,18 @@ let labels = Labels::try_from_file("tests/data/labels.jsonl").unwrap();

// Create a JSONL string
let jsonl = labels.export().unwrap();
```

You can encrypt and decrypt the [`Labels`] into/from the [`encryption::EncryptedLabels`] struct using the `encryption` feature.

License: Apache-2.0
#### Example encryption:
```rust
use bip329::{Labels, encryption::EncryptedLabels};

let labels = Labels::try_from_file("tests/data/labels.jsonl").unwrap();
let encrypted = EncryptedLabels::encrypt(&labels, "passphrase").unwrap();
let decrypted: Labels = encrypted.decrypt("passphrase").unwrap();
```


License: Apache-2.0
28 changes: 19 additions & 9 deletions src/encryption.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
//! Module for encrypting and decrypting labels.
use std::{
io::{Read as _, Write as _},
path::Path,
};

use age::secrecy::Secret;
use serde::{Deserialize, Serialize};

use crate::{error::EncryptionError, Labels};

use crate::{error::EncryptionError, EncryptedLabels, Labels};
/// A list of encrypted labels.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct EncryptedLabels(Vec<u8>);

#[cfg(feature = "uniffi")]
uniffi::custom_newtype!(EncryptedLabels, Vec<u8>);

impl EncryptedLabels {
/// Encrypt the Labels struct using the given passphrase.
Expand All @@ -28,14 +38,9 @@ impl EncryptedLabels {
Ok(Self(encrypted))
}

/// Get the encrypted bytes of the EncryptedLabels struct.
pub fn into_bytes(self) -> Vec<u8> {
self.0
}

/// Create a new EncryptedLabels struct from a hex encoded string.
pub fn from_hex_encoded(hex_encoded: &str) -> Result<Self, EncryptionError> {
let encrypted = hex::decode(hex_encoded)?;
pub fn from_hex(hex: &str) -> Result<Self, EncryptionError> {
let encrypted = hex::decode(hex)?;
Ok(Self(encrypted))
}

Expand All @@ -47,6 +52,11 @@ impl EncryptedLabels {
Ok(Self(encrypted))
}

/// Get the encrypted bytes of the EncryptedLabels struct.
pub fn into_bytes(self) -> Vec<u8> {
self.0
}

/// Decrypt the EncryptedLabels struct using the given passphrase.
pub fn decrypt(&self, passphrase: &str) -> Result<Labels, EncryptionError> {
let encrypted = &self.0;
Expand All @@ -71,7 +81,7 @@ impl EncryptedLabels {
}

/// Export the EncryptedLabels struct to a hex encoded string.
pub fn to_hex_encoded(&self) -> Result<String, EncryptionError> {
pub fn to_hex(&self) -> Result<String, EncryptionError> {
let encrypted = &self.0;
let hex_encoded = hex::encode(encrypted);

Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Module for all error types used in this crate.
#[cfg(feature = "uniffi")]
pub mod ffi;

Expand Down
2 changes: 1 addition & 1 deletion src/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Labels {
}

/// Export the Labels struct to a file.
pub fn export_to_file(&self, path: &str) -> Result<(), ExportError> {
pub fn export_to_file(&self, path: impl AsRef<Path>) -> Result<(), ExportError> {
let contents = self.export()?;
std::fs::write(path, contents)?;
Ok(())
Expand Down
56 changes: 24 additions & 32 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
//!
//! This library provides a way to work with BIP329 labels in a Rust program.
//!
//! The main data structure is the `[Labels]` struct, which is a list of `Label` structs.
//! The main data structure is the [`Labels`] struct, which is a list of `Label` structs.
//!
//! The `[Label]` enum is a discriminated union of all the different types of labels.
//! The [`Label`] enum is a discriminated union of all the different types of labels.
//!
//! The `[Labels]` struct can be exported to a JSONL file.
//! The [`Labels`] struct can be exported to a JSONL file.
//!
//! The `[Labels]` struct can be imported from a JSONL file.
//! The [`Labels`] struct can be imported from a JSONL file.
//!
//! Example Import:
//! ### Example Import:
//! ```rust
//! use bip329::Labels;
//!
//! let labels = Labels::try_from_file("tests/data/labels.jsonl").unwrap();
//! ```
//!
//! Example Export:
//! ### Example Export:
//! ```rust
//! use bip329::Labels;
//!
Expand All @@ -28,15 +28,15 @@
//! let jsonl = labels.export().unwrap();
//! ```
//!
//! You can encrypt and decrypt the `[Labels]` struct using the `encryption` feature.
//! You can encrypt and decrypt the [`Labels`] into/from the [`encryption::EncryptedLabels`] struct using the `encryption` feature.
//!
//! Example encryption:
//! ### Example encryption:
//! ```rust
//! use bip329::{Labels, encryption::EncryptedLabels};
//!
//! let labels = Labels::try_from_file("tests/data/labels.jsonl").unwrap();
//! let encrypted = EncryptedLabels::encrypt(&labels, "passphrase").unwrap();
//! let decrypted = encrypted.decrypt("passphrase").unwrap();
//! let decrypted: Labels = encrypted.decrypt("passphrase").unwrap();
//! ```
//!
pub mod error;
Expand All @@ -56,15 +56,7 @@ pub struct Labels(Vec<Label>);
#[cfg(feature = "uniffi")]
uniffi::custom_newtype!(Labels, Vec<Label>);

#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct EncryptedLabels(Vec<u8>);

#[cfg(feature = "uniffi")]
uniffi::custom_newtype!(EncryptedLabels, Vec<u8>);

/// Labels are the main data structure for BIP329 labels.
/// They are a list of Labels, each of which is a type of label.
/// The type of label is determined by the `type` field.
/// The main data structure for BIP329 labels.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[serde(tag = "type")]
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
Expand All @@ -88,69 +80,69 @@ pub enum Label {
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct TransactionRecord {
#[serde(rename = "ref")]
ref_: String,
pub ref_: String,
#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
origin: Option<String>,
pub origin: Option<String>,
}

/// An address label.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct AddressRecord {
#[serde(rename = "ref")]
ref_: String,
pub ref_: String,
#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
pub label: Option<String>,
}

/// A public key label.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct PublicKeyRecord {
#[serde(rename = "ref")]
ref_: String,
pub ref_: String,

#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
pub label: Option<String>,
}

/// An input label.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct InputRecord {
#[serde(rename = "ref")]
ref_: String,
pub ref_: String,
#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
pub label: Option<String>,
}

/// An output label.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct OutputRecord {
#[serde(rename = "ref")]
ref_: String,
pub ref_: String,

#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
pub label: Option<String>,

#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "serde_util::deserialize_string_or_bool"
)]
spendable: Option<bool>,
pub spendable: Option<bool>,
}

/// An extended public key label.
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct ExtendedPublicKeyRecord {
#[serde(rename = "ref")]
ref_: String,
label: Option<String>,
pub ref_: String,
pub label: Option<String>,
}

impl OutputRecord {
Expand Down
5 changes: 0 additions & 5 deletions test/loop_back_test.rs

This file was deleted.

13 changes: 12 additions & 1 deletion tests/loop_back_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bip329::Labels;
use bip329::{encryption::EncryptedLabels, Labels};

#[test]
fn test_loop_back() {
Expand All @@ -25,3 +25,14 @@ fn loop_back_test_vector() {

assert_eq!(labels_1, labels_2);
}

#[test]
fn test_loop_back_encryption() {
use pretty_assertions::assert_eq;

let labels_1 = Labels::try_from_file("tests/data/labels.jsonl").unwrap();
let encrypted = EncryptedLabels::encrypt(&labels_1, "passphrase").unwrap();
let decrypted = encrypted.decrypt("passphrase").unwrap();

assert_eq!(labels_1, decrypted);
}

0 comments on commit 0e5b19a

Please sign in to comment.