solana_conditional_liquidity/
origin.rs

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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
use solana_program::{account_info::AccountInfo, pubkey, pubkey::Pubkey};

use crate::is_invoked_by_segmenter;

/// The identifier for the origin of an invocation. This identifies the application or frontend from
/// which the invocation originated.
pub type Origin = u16;

pub mod origin_identity {
    use super::Origin;

    /// Origin when the application or frontend is unknown or could not be verified
    pub const UNKNOWN: Origin = 0;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VerifyOriginResult {
    /// The invocation was signed by a segmenter
    InvokedBySegmenter(Origin),
    /// The invocation was not signed by a segmenter
    NotInvokedBySegmenter,
}

/// Checks whether the invocation was signed by a segmenter and verifies the origin of the
/// invocation. Use this if you want to branch on the origin of the invocation.
///
/// Examples
///
/// ```
/// use solana_conditional_liquidity::{origin_identity, verify_origin, Origin, VerifyOriginResult};
/// use solana_program::account_info::AccountInfo;
///
/// fn handler(
///     registry: &AccountInfo<'_>,
///     segmenter: &AccountInfo<'_>,
///     claimed_origin: Origin,
/// ) {
///     let VerifyOriginResult::InvokedBySegmenter(origin) =
///         verify_origin(claimed_origin, registry, segmenter)
///     else {
///         // The invocation wasn't signed by a segmenter
///         return;
///     };
///
///     // Branch on the origin here
///     match origin {
///         // Add special logic for specific origins here...
///         origin_identity::UNKNOWN => {
///             // Origin is unknown or could not be verified
///         }
///         // These identifiers are just examples, but you get the idea...
///         // origin_identity::DFLOW_MOBILE => {}
///         // origin_identity::DFLOW_WEB => {}
///         // origin_identity::PHANTOM_MOBILE => {}
///         // origin_identity::PHANTOM_EXTENSION => {}
///         // origin_identity::SOLFLARE_MOBILE => {}
///         // origin_identity::SOLFLARE_EXTENSION => {}
///         _ => {
///             // Fallback for any other origin. This is different than the origin being unknown.
///         }
///     };
/// }
/// ```
pub fn verify_origin(
    claimed_origin: Origin,
    registry: &AccountInfo<'_>,
    segmenter: &AccountInfo<'_>,
) -> VerifyOriginResult {
    if !is_invoked_by_segmenter(registry, segmenter) {
        return VerifyOriginResult::NotInvokedBySegmenter;
    }

    if registry.key != &ORIGIN_VERIFYING_SEGMENTER_REGISTRY {
        return VerifyOriginResult::InvokedBySegmenter(origin_identity::UNKNOWN);
    }

    // If one of the DFlow segmenters signed the invocation, we can trust the origin
    VerifyOriginResult::InvokedBySegmenter(claimed_origin)
}

/// The origin-verifying registry is a special registry that contains segmenters that verify the
/// origin of the invocation
pub const ORIGIN_VERIFYING_SEGMENTER_REGISTRY: Pubkey =
    pubkey!("Reg1Y127DNKYUTf3LinfEs3oiSiywJsyAobJMjqYqDE");

#[cfg(test)]
mod tests {
    use std::{cell::RefCell, rc::Rc};

    use base64::Engine;
    use solana_program::system_program;

    use crate::Registry;

    use super::*;

    #[test]
    fn test_verify_origin() {
        let mut registry_data = base64::engine::general_purpose::STANDARD
                .decode("L65u9ri2/NoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADmpy9pZ0kSP2HFqsTSMjxFxburQjxQioc8A4BaVKbWtBAWsWrJs+pByyagNT2RTZ5E/wZAQB0FNhQpY/WTUev0FyJOST1AtAGCROxwJ16TmEm/91X11Lmzcymw9zcmibQnqAzYRp+mQPsmo+2htSt8O7nGFhRpTDQdq9qCtx9jA==")
                .unwrap();

        // Registry is the origin-verifying registry
        let mut registry_lamports = 15200640;
        let registry = AccountInfo {
            key: &pubkey!("Reg1Y127DNKYUTf3LinfEs3oiSiywJsyAobJMjqYqDE"),
            is_signer: false,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut registry_lamports)),
            data: Rc::new(RefCell::new(&mut registry_data)),
            owner: &Registry::PROGRAM_ID,
            executable: false,
            rent_epoch: 18446744073709551615,
        };

        // Signed and exists in origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &pubkey!("F2Me9XknvkPYjvoEgTXXKqARg58Ezo6ZmGhpYdS3UTmF"),
            is_signer: true,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::InvokedBySegmenter(1)
        );

        // Didn't sign but exists in origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &pubkey!("F2Me9XknvkPYjvoEgTXXKqARg58Ezo6ZmGhpYdS3UTmF"),
            is_signer: false,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::NotInvokedBySegmenter
        );

        // Signed but doesn't exist in origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &Pubkey::new_unique(),
            is_signer: true,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::NotInvokedBySegmenter
        );
    }

    #[test]
    fn test_verify_origin_non_verifying_registry() {
        let mut registry_data = base64::engine::general_purpose::STANDARD
                .decode("L65u9ri2/NoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADmpy9pZ0kSP2HFqsTSMjxFxburQjxQioc8A4BaVKbWtBAWsWrJs+pByyagNT2RTZ5E/wZAQB0FNhQpY/WTUev0FyJOST1AtAGCROxwJ16TmEm/91X11Lmzcymw9zcmibQnqAzYRp+mQPsmo+2htSt8O7nGFhRpTDQdq9qCtx9jA==")
                .unwrap();

        // Registry is valid but isn't the origin-verifying registry
        let mut registry_lamports = 15200640;
        let registry = AccountInfo {
            key: &Pubkey::new_unique(),
            is_signer: false,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut registry_lamports)),
            data: Rc::new(RefCell::new(&mut registry_data)),
            owner: &Registry::PROGRAM_ID,
            executable: false,
            rent_epoch: 18446744073709551615,
        };

        // Segmenter signed and exists in non-origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &pubkey!("F2Me9XknvkPYjvoEgTXXKqARg58Ezo6ZmGhpYdS3UTmF"),
            is_signer: true,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::InvokedBySegmenter(origin_identity::UNKNOWN)
        );

        // Segmenter didn't sign but exists in non-origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &pubkey!("F2Me9XknvkPYjvoEgTXXKqARg58Ezo6ZmGhpYdS3UTmF"),
            is_signer: false,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::NotInvokedBySegmenter
        );

        // Segmenter signed but doesn't exist in non-origin-verifying registry
        let mut segmenter_lamports = 0;
        let mut segmenter_data = [];
        let segmenter = AccountInfo {
            key: &Pubkey::new_unique(),
            is_signer: true,
            is_writable: false,
            lamports: Rc::new(RefCell::new(&mut segmenter_lamports)),
            data: Rc::new(RefCell::new(&mut segmenter_data)),
            owner: &system_program::id(),
            executable: false,
            rent_epoch: 18446744073709551615,
        };
        assert_eq!(
            verify_origin(1, &registry, &segmenter),
            VerifyOriginResult::NotInvokedBySegmenter
        );
    }
}