mirror of
https://github.com/hinto-janai/cuprate.git
synced 2025-02-03 11:46:31 +00:00
add cuprate_types::json
This commit is contained in:
parent
88605b081f
commit
243d3675a6
9 changed files with 545 additions and 3 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -886,13 +886,16 @@ name = "cuprate-types"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
"curve25519-dalek",
|
||||
"monero-serai",
|
||||
"pretty_assertions",
|
||||
"proptest",
|
||||
"proptest-derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
|
|
@ -6,12 +6,16 @@ This allows all workspace crates to share, and aids compile times.
|
|||
If a 3rd party's crate/functions/types are small enough, it could be moved here to trim dependencies and allow easy modifications.
|
||||
|
||||
## Features
|
||||
Code can be selectively used/compiled with cargo's `--feature` or `features = ["..."]`.
|
||||
Modules can be selectively used/compiled with cargo's `--feature` or `features = ["..."]`.
|
||||
|
||||
All features on by default.
|
||||
All features are off by default.
|
||||
|
||||
See [`Cargo.toml`](Cargo.toml)'s `[features]` table to see what features there are and what they enable.
|
||||
|
||||
Special non-module related features:
|
||||
- `serde`: Enables serde implementations on applicable types
|
||||
- `std`: Enables usage of `std`
|
||||
|
||||
## `#[no_std]`
|
||||
Each modules documents whether it requires `std` or not.
|
||||
|
||||
|
|
|
@ -9,16 +9,18 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/types"
|
|||
keywords = ["cuprate", "types"]
|
||||
|
||||
[features]
|
||||
default = ["blockchain", "epee", "serde"]
|
||||
default = ["blockchain", "epee", "serde", "json"]
|
||||
blockchain = []
|
||||
epee = ["dep:cuprate-epee-encoding"]
|
||||
serde = ["dep:serde"]
|
||||
proptest = ["dep:proptest", "dep:proptest-derive"]
|
||||
json = []
|
||||
|
||||
[dependencies]
|
||||
cuprate-epee-encoding = { path = "../net/epee-encoding", optional = true }
|
||||
cuprate-fixed-bytes = { path = "../net/fixed-bytes" }
|
||||
|
||||
cfg-if = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
|
@ -29,6 +31,8 @@ proptest = { workspace = true, optional = true }
|
|||
proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = { workspace = true }
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
321
types/src/json/block.rs
Normal file
321
types/src/json/block.rs
Normal file
|
@ -0,0 +1,321 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "serde")] {
|
||||
use serde::{Serialize, Deserialize};
|
||||
// use monero_serai::{block::Block, transaction::Transaction};
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
///
|
||||
/// `/get_block`
|
||||
///
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Block {
|
||||
pub major_version: u64,
|
||||
pub minor_version: u64,
|
||||
pub timestamp: u64,
|
||||
pub prev_id: String,
|
||||
pub nonce: u32,
|
||||
pub miner_tx: MinerTransaction,
|
||||
pub tx_hashes: Vec<String>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct MinerTransaction {
|
||||
pub version: u64,
|
||||
pub unlock_time: u64,
|
||||
pub vin: Vec<Input>,
|
||||
pub vout: Vec<Output>,
|
||||
pub extra: Vec<u8>,
|
||||
|
||||
/// Should be [`None`] if [`Self::rct_signatures`] is [`Some`]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub signatures: Option<MinerTransactionSignature>,
|
||||
|
||||
/// Should be [`None`] if [`Self::signatures`] is [`Some`]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub rct_signatures: Option<MinerTransactionRctSignature>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[serde(transparent)]
|
||||
#[repr(transparent)]
|
||||
pub struct MinerTransactionSignature(Vec<()>);
|
||||
|
||||
impl MinerTransactionSignature {
|
||||
pub const fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct MinerTransactionRctSignature {
|
||||
pub r#type: u8,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Input {
|
||||
pub r#gen: Gen,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Gen {
|
||||
pub height: u64,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Output {
|
||||
pub amount: u64,
|
||||
pub target: Target,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Target {
|
||||
/// Should be [`None`] if [`Self::tagged_key`] is [`Some`]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub key: Option<String>,
|
||||
|
||||
/// Should be [`None`] if [`Self::key`] is [`Some`]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub tagged_key: Option<TaggedKey>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TaggedKey {
|
||||
pub key: String,
|
||||
pub view_tag: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
|
||||
const BLOCK_300000_JSON: &str = r#"{
|
||||
"major_version": 1,
|
||||
"minor_version": 0,
|
||||
"timestamp": 1415690591,
|
||||
"prev_id": "e97a0ab6307de9b9f9a9872263ef3e957976fb227eb9422c6854e989e5d5d34c",
|
||||
"nonce": 2147484616,
|
||||
"miner_tx": {
|
||||
"version": 1,
|
||||
"unlock_time": 300060,
|
||||
"vin": [
|
||||
{
|
||||
"gen": {
|
||||
"height": 300000
|
||||
}
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"amount": 47019296802,
|
||||
"target": {
|
||||
"key": "3c1dcbf5b485987ecef4596bb700e32cbc7bd05964e3888ffc05f8a46bf5fc33"
|
||||
}
|
||||
},
|
||||
{
|
||||
"amount": 200000000000,
|
||||
"target": {
|
||||
"key": "5810afc7a1b01a1c913eb6aab15d4a851cbc4a8cf0adf90bb80ac1a7ca9928aa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"amount": 3000000000000,
|
||||
"target": {
|
||||
"key": "520f49c5f2ce8456dc1a565f35ed3a5ccfff3a1210b340870a57d2749a81a2df"
|
||||
}
|
||||
},
|
||||
{
|
||||
"amount": 10000000000000,
|
||||
"target": {
|
||||
"key": "44d7705e62c76c2e349a474df6724aa1d9932092002b03a94f9c19d9d12b9427"
|
||||
}
|
||||
}
|
||||
],
|
||||
"extra": [
|
||||
1,
|
||||
251,
|
||||
8,
|
||||
189,
|
||||
254,
|
||||
12,
|
||||
213,
|
||||
173,
|
||||
108,
|
||||
61,
|
||||
156,
|
||||
198,
|
||||
144,
|
||||
151,
|
||||
31,
|
||||
130,
|
||||
141,
|
||||
211,
|
||||
120,
|
||||
55,
|
||||
81,
|
||||
98,
|
||||
32,
|
||||
247,
|
||||
111,
|
||||
127,
|
||||
254,
|
||||
170,
|
||||
170,
|
||||
240,
|
||||
124,
|
||||
190,
|
||||
223,
|
||||
2,
|
||||
8,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
64,
|
||||
184,
|
||||
115,
|
||||
46,
|
||||
246
|
||||
],
|
||||
"signatures": []
|
||||
},
|
||||
"tx_hashes": []
|
||||
}"#;
|
||||
|
||||
const BLOCK_3245409_JSON: &str = r#"{
|
||||
"major_version": 16,
|
||||
"minor_version": 16,
|
||||
"timestamp": 1727293028,
|
||||
"prev_id": "41b56c273d69def3294e56179de71c61808042d54c1e085078d21dbe99e81b6f",
|
||||
"nonce": 311,
|
||||
"miner_tx": {
|
||||
"version": 2,
|
||||
"unlock_time": 3245469,
|
||||
"vin": [
|
||||
{
|
||||
"gen": {
|
||||
"height": 3245409
|
||||
}
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"amount": 601012280000,
|
||||
"target": {
|
||||
"tagged_key": {
|
||||
"key": "8c0b16c6df02b9944b49f375d96a958a0fc5431c048879bb5bf25f64a1163b9e",
|
||||
"view_tag": "88"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"extra": [
|
||||
1,
|
||||
39,
|
||||
23,
|
||||
182,
|
||||
203,
|
||||
58,
|
||||
48,
|
||||
15,
|
||||
217,
|
||||
9,
|
||||
13,
|
||||
147,
|
||||
104,
|
||||
133,
|
||||
206,
|
||||
176,
|
||||
185,
|
||||
56,
|
||||
237,
|
||||
179,
|
||||
136,
|
||||
72,
|
||||
84,
|
||||
129,
|
||||
113,
|
||||
98,
|
||||
206,
|
||||
4,
|
||||
18,
|
||||
50,
|
||||
130,
|
||||
162,
|
||||
94,
|
||||
2,
|
||||
17,
|
||||
73,
|
||||
18,
|
||||
21,
|
||||
33,
|
||||
32,
|
||||
112,
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rct_signatures": {
|
||||
"type": 0
|
||||
}
|
||||
},
|
||||
"tx_hashes": [
|
||||
"eab76986a0cbcae690d8499f0f616f783fd2c89c6f611417f18011950dbdab2e",
|
||||
"57b19aa8c2cdbb6836cf13dd1e321a67860965c12e4418f3c30f58c8899a851e",
|
||||
"5340185432ab6b74fb21379f7e8d8f0e37f0882b2a7121fd7c08736f079e2edc",
|
||||
"01dc6d31db56d68116f5294c1b4f80b33b048b5cdfefcd904f23e6c0de3daff5",
|
||||
"c9fb6a2730678203948fef2a49fa155b63f35a3649f3d32ed405a6806f3bbd56",
|
||||
"af965cdd2a2315baf1d4a3d242f44fe07b1fd606d5f4853c9ff546ca6c12a5af",
|
||||
"97bc9e047d25fae8c14ce6ec882224e7b722f5e79b62a2602a6bacebdac8547b",
|
||||
"28c46992eaf10dc0cceb313c30572d023432b7bd26e85e679bc8fe419533a7bf",
|
||||
"c32e3acde2ff2885c9cc87253b40d6827d167dfcc3022c72f27084fd98788062",
|
||||
"19e66a47f075c7cccde8a7b52803119e089e33e3a4847cace0bd1d17b0d22bab",
|
||||
"8e8ac560e77a1ee72e82a5eb6887adbe5979a10cd29cb2c2a3720ce87db43a70",
|
||||
"b7ff5141524b5cca24de6780a5dbfdf71e7de1e062fd85f557fb3b43b8e285dc",
|
||||
"f09df0f113763ef9b9a2752ac293b478102f7cab03ef803a3d9db7585aea8912"
|
||||
]
|
||||
}"#;
|
||||
|
||||
fn test(block_json: &'static str) {
|
||||
let json = serde_json::from_str::<Block>(block_json).unwrap();
|
||||
let string = serde_json::to_string_pretty(&json).unwrap();
|
||||
assert_eq!(block_json, &string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_300000() {
|
||||
test(BLOCK_300000_JSON);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_3245409() {
|
||||
test(BLOCK_3245409_JSON);
|
||||
}
|
||||
}
|
6
types/src/json/mod.rs
Normal file
6
types/src/json/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
pub mod block;
|
||||
mod tx;
|
||||
pub mod tx_in_pool;
|
||||
|
||||
pub use block::Block;
|
||||
pub use tx::Transaction;
|
32
types/src/json/signature.rs
Normal file
32
types/src/json/signature.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "serde")] {
|
||||
use serde::{Serialize, Deserialize};
|
||||
// use monero_serai::{block::Block, transaction::Transaction};
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Signature {
|
||||
#[serde(rename = "ecdhinfo")]
|
||||
pub ecdh_info: (),
|
||||
#[serde(rename = "outPk")]
|
||||
pub out_pk: (),
|
||||
#[serde(rename = "txnFee")]
|
||||
pub txn_fee: (),
|
||||
pub r#type: (),
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RctSignature {
|
||||
#[serde(rename = "ecdhinfo")]
|
||||
pub ecdh_info: (),
|
||||
#[serde(rename = "outPk")]
|
||||
pub out_pk: (),
|
||||
#[serde(rename = "txnFee")]
|
||||
pub txn_fee: (),
|
||||
pub r#type: (),
|
||||
}
|
53
types/src/json/tx.rs
Normal file
53
types/src/json/tx.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "serde")] {
|
||||
use serde::{Serialize, Deserialize};
|
||||
// use monero_serai::{block::Block, transaction::Transaction};
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
///
|
||||
/// `/get_transactions`
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Transaction {
|
||||
pub version: u64,
|
||||
pub unlock_time: u64,
|
||||
pub vin: Vec<TransactionInput>,
|
||||
pub vout: Vec<TransactionOutput>,
|
||||
pub extra: [u8; 32],
|
||||
/// [`None`] on pruned transactions.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub signatures: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TransactionInput {
|
||||
pub key: TransactionInputKey,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TransactionInputKey {
|
||||
pub amount: u64,
|
||||
pub key_offsets: Vec<u64>,
|
||||
pub k_image: String,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TransactionOutput {
|
||||
pub amount: u64,
|
||||
pub target: TransactionOutputTarget,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TransactionOutputTarget {
|
||||
pub key: String,
|
||||
}
|
116
types/src/json/tx_in_pool.rs
Normal file
116
types/src/json/tx_in_pool.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
//! TODO
|
||||
|
||||
#![expect(non_snake_case, reason = "JSON fields have non snake-case casing")]
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "serde")] {
|
||||
use serde::{Serialize, Deserialize};
|
||||
// use monero_serai::{block::Block, transaction::Transaction};
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
///
|
||||
/// `/get_transaction_pool`
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct TransactionInPool {
|
||||
pub version: u64,
|
||||
pub unlock_time: u64,
|
||||
pub vin: Vec<Input>,
|
||||
pub vout: Vec<Output>,
|
||||
pub extra: [u8; 32],
|
||||
/// [`None`] on pruned transactions.
|
||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||
pub signatures: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RctSignatures {
|
||||
pub r#type: u8,
|
||||
pub txnFee: u64,
|
||||
pub ecdhInfo: Vec<EcdhInfo>,
|
||||
pub outPk: Vec<String>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RctSigPrunable {
|
||||
pub nbp: u64,
|
||||
pub bpp: Vec<Bpp>,
|
||||
pub CLSAGs: Vec<Clsag>,
|
||||
pub pseudoOuts: Vec<String>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Bpp {
|
||||
pub A: String,
|
||||
pub A1: String,
|
||||
pub B: String,
|
||||
pub r1: String,
|
||||
pub s1: String,
|
||||
pub d1: String,
|
||||
pub L: Vec<String>,
|
||||
pub R: Vec<String>,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Clsag {
|
||||
pub s: Vec<String>,
|
||||
pub c1: String,
|
||||
pub D: String,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct EcdhInfo {
|
||||
pub amount: String,
|
||||
pub mask: String,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Input {
|
||||
pub key: InputKey,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct InputKey {
|
||||
pub amount: u64,
|
||||
pub key_offsets: Vec<u64>,
|
||||
pub k_image: String,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Output {
|
||||
pub amount: u64,
|
||||
pub target: OutputTarget,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct OutputTarget {
|
||||
pub tagged_key: OutputTaggedKey,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct OutputTaggedKey {
|
||||
pub key: String,
|
||||
pub view_tag: String,
|
||||
}
|
|
@ -28,4 +28,7 @@ pub use types::{
|
|||
#[cfg(feature = "blockchain")]
|
||||
pub mod blockchain;
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub mod json;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Private
|
||||
|
|
Loading…
Reference in a new issue