p2panda_core/lib.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3#![cfg_attr(doctest, doc=include_str!("../README.md"))]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6//! Core data types used across the p2panda stack to offer distributed, secure and efficient data
7//! transfer between peers.
8//!
9//! The main data type is a highly extensible, cryptographically secure append-only log
10//! implementation. It provides all the basic features required to implement more advanced
11//! distributed data types commonly required when building peer-to-peer and local-first
12//! applications.
13//!
14//! ## Features
15//!
16//! - Cryptographic signatures for authorship verification and tamper-proof messages
17//! - Authors can maintain one or many logs
18//! - Single-writer logs which can be combined to support multi-writer collaboration
19//! - Compatible with any application data and CRDT
20//! - Compatible with any networking scenario (for example packet radio or mesh-networks)
21//! - Fork-tolerant
22//! - Off-chain handling of payloads, can be deleted independently of log structure
23//! - Pruning of outdated messages
24//! - Highly extensible with custom features, for example prefix-deletion, ephemeral
25//! "self-destructing" messages, etc.
26//!
27//! p2panda logs are made up of [`Operation`]s. Authors sign operations using their cryptographic
28//! key (Ed25519) and append them to a hash-chain of operations. An author may have one or many
29//! logs. The precise means of identifying logs is not defined by this crate (see extensions).
30//!
31//! An operation is constructed from a [`Header`] and a [`Body`], the `Header` contains all metadata
32//! associated with the particular operation, and the `Body` contains the actual application message
33//! bytes. This separation allows "off-chain" handling, where the important bits in the headers are
34//! transmitted via an prioritised channel and secondary information, such as the body, can be
35//! loaded "lazily". Additionally it allows deletion of payloads without breaking the integrity of
36//! the append-only log.
37//!
38//! ## Extensions
39//!
40//! Custom extension fields can be defined by users of this library to introduce additional
41//! functionality depending on their particular use cases. p2panda provides our own extensions which
42//! are required when using our other crates offering more advanced functionality needed for
43//! application building (CRDTs, access control, encryption, ephemeral data, garbage collection,
44//! etc.), but it's entirely possible for users to define their own extensions as well.
45//!
46//! ## Examples
47//!
48//! **Create and sign operations**
49//!
50//! ```
51//! use p2panda_core::{Body, Header, SigningKey};
52//!
53//! // Every operation is cryptographically authenticated by an author by signing it with an
54//! // Ed25519 key pair. This method generates a new private key for us which needs to be securely
55//! // stored for re-use.
56//! let signing_key = SigningKey::generate();
57//!
58//! // Operations consist of an body (with the actual application data) and a header,
59//! // enhancing the data to be used in distributed networks.
60//! let body = Body::from_bytes("Hello, Sloth!".as_bytes());
61//!
62//! let header = Header::builder()
63//! .body(&body)
64//! // Sign the header with the author's private key. From now on it's ready to be sent!
65//! .build(&signing_key, ());
66//! ```
67//!
68//! **Extend operations with custom features**
69//!
70//! ```rust
71//! use p2panda_core::{Header, SigningKey};
72//! use serde::{Serialize, Deserialize};
73//!
74//! // Extend operations with an "expiry" field we can use to implement "ephemeral messages"
75//! // in our application, which get automatically deleted after the expiration timestamp is due.
76//! #[derive(Clone, Debug, Default, Hash, Eq, PartialEq, Serialize, Deserialize)]
77//! pub struct Expiry(u64);
78//!
79//! // Multiple extensions can be combined in a custom type.
80//! #[derive(Clone, Debug, Default, Serialize, Deserialize)]
81//! struct CustomExtensions {
82//! expiry: Expiry,
83//! }
84//!
85//! let signing_key = SigningKey::generate();
86//!
87//! let header = Header::builder()
88//! .body(b"Hello, Panda!")
89//! .build(&signing_key, CustomExtensions {
90//! expiry: Expiry(1787246716),
91//! });
92//! ```
93pub mod cbor;
94pub mod cursor;
95pub mod hash;
96pub mod identity;
97pub mod logs;
98pub mod operation;
99pub mod prune;
100mod serde;
101#[cfg(any(test, feature = "test_utils"))]
102pub mod test_utils;
103pub mod timestamp;
104pub mod topic;
105pub mod traits;
106
107pub use cursor::Cursor;
108pub use hash::{Hash, HashError};
109pub use identity::{IdentityError, Signature, SigningKey, VerifyingKey};
110pub use logs::{LogId, SeqNum};
111pub use operation::{
112 AnyHeader, AnyOperation, Body, Header, HeaderError, Operation, OperationError, RawOperation,
113 validate_backlink, validate_header, validate_operation,
114};
115pub use prune::PruneFlag;
116pub use timestamp::Timestamp;
117pub use topic::Topic;
118pub use traits::{Author, Extensions, OperationId};