#[repr(C)]pub struct Claim {
pub epoch: [u8; 8],
pub payment_proof_length: u8,
pub seal_proof_length: u8,
pub participant_type: u8,
pub has_social: u8,
pub _padding: [u8; 4],
}
Expand description
Claim instruction data for Dual Merkle Tree system with optional social rewards.
This instruction allows users to claim rewards based on their activity contributions for a specific epoch using the Dual Merkle Tree verification system. The claim is verified using both a payment merkle proof and a seal merkle proof, with the payment root embedded in the seal proof data for explicit verification. Optionally, users can also claim social marketing rewards for the same epoch if they have verified social media engagement.
§Dual Merkle Verification
- Payment Proof: Verifies user’s activity within the epoch
- Seal Proof: Verifies the payment merkle root is authentic (from oracle)
- Payment Root: Embedded in seal proof data for explicit verification
- Dual Verification: Both proofs must pass for a valid claim
§Social Rewards Support
- Payment-First: Social rewards require payment activity verification
- Oracle Verification: Social posts must be verified by oracle signature
- Optional: Users can choose payment-only or payment+social claims
- Unified: Single instruction supports both reward types
§Data Structure
The instruction uses a hybrid approach with fixed-size fields followed by variable-length data:
// Fixed-size struct (23 bytes)
struct Claim {
epoch: [u8; 8], // 8 bytes - Epoch number for the claim
payment_proof_length: u8, // 1 byte - Length of payment merkle path
seal_proof_length: u8, // 1 byte - Length of seal merkle path
participant_type: u8, // 1 byte - 0 for customer, 1 for merchant
has_social: u8, // 1 byte - 0=payment only, 1=has social data
_padding: [u8; 4], // 4 bytes - Padding for alignment
}
// Variable-size additional data (appended after fixed struct)
// participant_data: DailyParticipantData // Variable size - Actual participant data for verification
// payment_proof: Vec<[u8; 32]> // payment_proof_length * 32 bytes
// payment_indices: Vec<u8> // payment_proof_length * 1 byte
// seal_proof: Vec<[u8; 32]> // seal_proof_length * 32 bytes
// seal_indices: Vec<u8> // seal_proof_length * 1 byte
// payment_root: [u8; 32] // Payment root (embedded in seal proof data)
// epoch_data: EpochClaimData // Epoch-specific data for accurate historical reward calculation
// social_data: SocialClaimData // Optional: only if has_social = 1
§Security Features
- Payment Proof: Ensures claim data integrity within an epoch
- Seal Proof: Ensures payment merkle root is authentic (from oracle)
- Payment Root: Explicitly provided for verification
- Dual Verification: Both proofs must pass for a valid claim
- Oracle Verification: Social posts verified by authorized oracle
- Unlimited History: No storage limits for historical claims
§On-Chain Reward Calculation
The reward amount is calculated on-chain using the transparent formula: payment_reward = (activity_count * customer_reward_pool) / total_customer_activity social_reward = base_reward_per_post * (1 + engagement_score / 1000)
Where:
activity_count
is extracted from the payment merkle proofcustomer_reward_pool
andtotal_customer_activity
are read from the Snapshotbase_reward_per_post
and engagement data come from social verification
§Historical Claims Support
For historical epoch claims, the instruction includes epoch-specific data:
- Current Epoch: Uses on-chain snapshot data for reward calculation
- Historical Epochs: Uses epoch-specific data embedded in the instruction
- No On-Chain Storage: Historical data comes with the claim instruction
- Accurate Rewards: Users get correct rewards for historical activity
This enables the Dual Merkle Tree’s promise of unlimited claim history without requiring expensive on-chain storage of historical snapshots.
§Off-Chain Development
When building claim instructions off-chain:
- Set
payment_proof_length
andseal_proof_length
to actual path lengths - Set
has_social
to 1 if social data is included, 0 otherwise - Append payment proof data after the fixed struct
- Append payment indices data (1 = right, 0 = left)
- Append seal proof data
- Append seal indices data (1 = right, 0 = left)
- Append payment root data (32 bytes)
- Append epoch-specific data (EpochClaimData) for accurate historical calculations
- If has_social = 1, append SocialClaimData
- Verify total instruction size doesn’t exceed Solana limits
See DUAL_MERKLE_TREE_DESIGN.md
for detailed implementation examples.
Fields§
§epoch: [u8; 8]
§payment_proof_length: u8
§seal_proof_length: u8
§participant_type: u8
§_padding: [u8; 4]
Implementations§
Source§impl Claim
impl Claim
pub fn try_from_bytes(data: &[u8]) -> Result<&Self, ProgramError>
Trait Implementations§
Source§impl Discriminator for Claim
impl Discriminator for Claim
fn discriminator() -> u8
impl Copy for Claim
impl Pod for Claim
Auto Trait Implementations§
impl Freeze for Claim
impl RefUnwindSafe for Claim
impl Send for Claim
impl Sync for Claim
impl Unpin for Claim
impl UnwindSafe for Claim
Blanket Implementations§
Source§impl<T> AccountDeserialize for Twhere
T: Discriminator + Pod,
impl<T> AccountDeserialize for Twhere
T: Discriminator + Pod,
fn try_from_bytes(data: &[u8]) -> Result<&T, ProgramError>
fn try_from_bytes_mut(data: &mut [u8]) -> Result<&mut T, ProgramError>
Source§impl<T> AccountHeaderDeserialize for Twhere
T: Discriminator + Pod,
impl<T> AccountHeaderDeserialize for Twhere
T: Discriminator + Pod,
fn try_header_from_bytes(data: &[u8]) -> Result<(&T, &[u8]), ProgramError>
fn try_header_from_bytes_mut( data: &mut [u8], ) -> Result<(&mut T, &mut [u8]), ProgramError>
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
Source§type Bits = T
type Bits = T
Self
must have the same layout as the specified Bits
except for
the possible invalid bit patterns being checked during
is_valid_bit_pattern
.Source§fn is_valid_bit_pattern(_bits: &T) -> bool
fn is_valid_bit_pattern(_bits: &T) -> bool
bits
as &Self
.Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more