miracle_api/dmt/
social_claim_data.rs

1use steel::*;
2
3// ===== SOCIAL MARKETING REWARDS SYSTEM INSTRUCTIONS =====
4
5/// Social claim data for social media engagement rewards.
6///
7/// This struct contains the data required for claiming social marketing rewards.
8/// Social rewards require payment activity in the same epoch and are verified
9/// through oracle signatures to prevent gaming.
10///
11/// ## Data Structure
12/// ```rust
13/// struct SocialClaimData {
14///     post_url: String,               // Social media post URL
15///     oracle_signature: [u8; 64],     // Oracle verification signature
16///     engagement_score: u32,          // Future: engagement-based rewards
17///     post_timestamp: i64,            // When post was made
18///     _padding: [u8; 4],              // For future extensibility
19/// }
20/// ```
21///
22/// ## Oracle Signature Message Format
23/// The oracle must sign a message with this format:
24///
25/// `epoch:user_pubkey:post_url:engagement_score:post_timestamp`
26///
27/// Example: `"100:ABC123...:https://twitter.com/user/123:500:1640995200"`
28///
29/// This format prevents replay attacks by including epoch and user context.
30///
31/// ## Verification Requirements
32/// - Payment activity required in same epoch
33/// - Oracle signature verification
34/// - Daily limits enforcement
35/// - Content requirements (#MiracleRewards, @MiracleProtocol)
36///
37/// ## Anti-Gaming Measures
38/// - Daily limits per user (max 3 posts per day)
39/// - Payment requirement ensures real users
40/// - Oracle verification prevents fake posts
41/// - Content requirements ensure quality engagement
42/// - Epoch-specific signatures prevent replay attacks
43#[repr(C)]
44#[derive(Debug, Clone, Copy, Pod, Zeroable)]
45pub struct SocialClaimData {
46    /// Social media post URL for verification.
47    /// Must contain required hashtags and mentions.
48    pub post_url: [u8; 256], // Fixed-size URL field
49
50    /// Oracle signature for post verification.
51    /// This signature validates that the post meets requirements.
52    pub oracle_signature: [u8; 64],
53
54    /// Timestamp when the post was made.
55    /// Used for daily limit calculations and verification.
56    pub post_timestamp: [u8; 8], // i64
57
58    /// Engagement score for future tiered rewards.
59    /// Currently unused, reserved for future engagement-based rewards.
60    pub engagement_score: [u8; 4], // u32
61
62    /// Padding for future extensibility.
63    /// Reserved for additional social claim features.
64    pub _padding: [u8; 4],
65}
66
67impl SocialClaimData {
68    /// Deserialize from bytes manually
69    pub fn from_bytes(data: &[u8]) -> Result<Self, &'static str> {
70        let expected_size = std::mem::size_of::<Self>();
71        if data.len() < expected_size {
72            return Err("Insufficient data for SocialClaimData");
73        }
74
75        let post_url: [u8; 256] = data[0..256].try_into().map_err(|_| "Invalid post_url")?;
76        let oracle_signature: [u8; 64] = data[256..320]
77            .try_into()
78            .map_err(|_| "Invalid oracle_signature")?;
79        let post_timestamp: [u8; 8] = data[320..328]
80            .try_into()
81            .map_err(|_| "Invalid post_timestamp")?;
82        let engagement_score: [u8; 4] = data[328..332]
83            .try_into()
84            .map_err(|_| "Invalid engagement_score")?;
85        let _padding: [u8; 4] = data[332..336].try_into().map_err(|_| "Invalid padding")?;
86
87        Ok(Self {
88            post_url,
89            oracle_signature,
90            engagement_score,
91            post_timestamp,
92            _padding,
93        })
94    }
95}