rialo-aggregator-interface 0.1.10

Instructions and constructors for aggregators program
Documentation
// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Instructions for an Aggregator program.
//!
//! This module defines the instructions that are used for Aggregator programs. It only supports
//! the aggregation of an oracle's data.

use rialo_events_core::derive_event_address;
use rialo_s_instruction::{AccountMeta, Instruction};
use rialo_s_program::system_program;
use rialo_s_pubkey::Pubkey;
use serde::{Deserialize, Serialize};

/// Instructions supported by an aggregator program.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub enum AggregatorInstruction {
    /// Aggregate oracle data.
    Aggregate {
        /// Topic for the aggregated data.
        topic: String,
    },
}

impl AggregatorInstruction {
    /// Create an instruction to aggregate oracle data.
    ///
    /// # Arguments
    ///
    /// * `aggregator_program_id` - The public key of the aggregator program
    /// * `payer` - The public key of the payer
    /// * `oracle_report` - The public key of the oracle report account
    /// * `topic` - The topic for the aggregated data
    ///
    /// # Returns
    ///
    /// An instruction that can be included in a transaction
    pub fn aggregate(
        aggregator_program_id: &Pubkey,
        payer: &Pubkey,
        oracle_report: &Pubkey,
        topic: String,
    ) -> Instruction {
        let aggregated_data_key = derive_event_address(&topic, aggregator_program_id).0;
        Instruction::new_with_bincode(
            *aggregator_program_id,
            &AggregatorInstruction::Aggregate { topic },
            vec![
                AccountMeta::new(*payer, true),
                AccountMeta::new_readonly(*oracle_report, false),
                AccountMeta::new(aggregated_data_key, false),
                AccountMeta::new_readonly(system_program::id(), false),
            ],
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_aggregate() {
        let program_id = Pubkey::new_unique();
        let creator = Pubkey::new_unique();
        let oracle_report = Pubkey::new_unique();
        let topic = "test_topic".to_string();

        let expected_aggregated_data_key = derive_event_address(&topic, &program_id).0;

        let instruction =
            AggregatorInstruction::aggregate(&program_id, &creator, &oracle_report, topic);

        // Verify the program ID
        assert_eq!(instruction.program_id, program_id);

        // Verify accounts
        let expected_accounts = vec![
            AccountMeta::new(creator, true),
            AccountMeta::new_readonly(oracle_report, false),
            AccountMeta::new(expected_aggregated_data_key, false),
            AccountMeta::new_readonly(system_program::id(), false),
        ];
        assert_eq!(instruction.accounts, expected_accounts);

        // Deserialize and verify instruction data
        let _: AggregatorInstruction = bincode::deserialize(&instruction.data).unwrap();
    }
}