1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This file implements Diem transaction metadata types to allow
//! easy parsing and introspection into metadata, whether the transaction
//! is using regular subaddressing, is subject to travel rule or corresponds
//! to an on-chain payment refund.

use serde::{Deserialize, Serialize};

/// List of all supported metadata types
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum Metadata {
    Undefined,
    GeneralMetadata(GeneralMetadata),
    TravelRuleMetadata(TravelRuleMetadata),
    UnstructuredBytesMetadata(UnstructuredBytesMetadata),
    RefundMetadata(RefundMetadata),
    CoinTradeMetadata(CoinTradeMetadata),
    PaymentMetadata(PaymentMetadata),
}

/// List of supported transaction metadata format versions for regular
/// addressing with optional subaddressing or refund reference
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum GeneralMetadata {
    GeneralMetadataVersion0(GeneralMetadataV0),
}

/// Transaction metadata for regular addressing with optional subaddressing
/// or refunded transaction reference
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct GeneralMetadataV0 {
    /// Subaddress to which the funds are being sent
    #[serde(with = "serde_bytes")]
    to_subaddress: Option<Vec<u8>>,
    /// Subaddress from which the funds are being sent
    #[serde(with = "serde_bytes")]
    from_subaddress: Option<Vec<u8>>,
    /// In the case of refunds, referenced_event refers to the event sequence
    /// number of the sender’s original sent payment event.
    /// Since refunds are just another form of P2P transfer, the referenced
    /// event field allows a refunded payment to refer back to the original
    /// payment
    referenced_event: Option<u64>,
}

impl GeneralMetadataV0 {
    pub fn new(
        to_subaddress: Option<Vec<u8>>,
        from_subaddress: Option<Vec<u8>>,
        referenced_event: Option<u64>,
    ) -> Self {
        GeneralMetadataV0 {
            to_subaddress,
            from_subaddress,
            referenced_event,
        }
    }

    pub fn to_subaddress(&self) -> &Option<Vec<u8>> {
        &self.to_subaddress
    }

    pub fn from_subaddress(&self) -> &Option<Vec<u8>> {
        &self.from_subaddress
    }

    pub fn referenced_event(&self) -> &Option<u64> {
        &self.referenced_event
    }
}

/// List of supported transaction metadata format versions for transactions
/// subject to travel rule
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum TravelRuleMetadata {
    TravelRuleMetadataVersion0(TravelRuleMetadataV0),
}

/// Transaction metadata format for transactions subject to travel rule
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TravelRuleMetadataV0 {
    /// Off-chain reference_id.  Used when off-chain APIs are used.
    /// Specifies the off-chain reference ID that was agreed upon in off-chain APIs.
    pub off_chain_reference_id: Option<String>,
}

/// Opaque binary transaction metadata
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct UnstructuredBytesMetadata {
    /// Unstructured byte vector metadata
    #[serde(with = "serde_bytes")]
    pub metadata: Option<Vec<u8>>,
}

/// List of supported transaction metadata format versions for refund transaction
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum RefundMetadata {
    RefundMetadataV0(RefundMetadataV0),
}

/// Transaction metadata format for transactions subject to refund transaction
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RefundMetadataV0 {
    /// Transaction version that is refunded
    pub transaction_version: u64,
    /// The reason of the refund
    pub reason: RefundReason,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum RefundReason {
    OtherReason,
    InvalidSubaddress,
    UserInitiatedPartialRefund,
    UserInitiatedFullRefund,
    InvalidReferenceId,
}

/// List of supported transaction metadata format versions for coin trade transaction
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum CoinTradeMetadata {
    CoinTradeMetadataV0(CoinTradeMetadataV0),
}

/// Transaction metadata format for coin trades (purchases/sells)
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct CoinTradeMetadataV0 {
    /// A list of trade_ids this transaction wants to settle
    pub trade_ids: Vec<String>,
}

/// List of supported transaction metadata format versions for transactions for payments
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum PaymentMetadata {
    PaymentMetadataVersion0(PaymentMetadataV0),
}

/// Transaction metadata format for transactions for payments
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct PaymentMetadataV0 {
    /// Reference ID needed for off-chain reference ID exchange.
    pub reference_id: [u8; 16],
}