From bda344617d1dc45c4ce55f5bbccfc55204fc5ea0 Mon Sep 17 00:00:00 2001 From: Georgechisom Date: Sat, 31 Jan 2026 11:50:21 +0100 Subject: [PATCH 1/2] feat: implement time-based operations and scheduling --- bill_payments/src/lib.rs | 484 +++--- bill_payments/src/schedule.rs | 28 + bill_payments/src/test.rs | 242 ++- .../test/testsuit/test_cancel_schedule.1.json | 883 +++++++++++ .../test/testsuit/test_create_bill.1.json | 12 + .../test/testsuit/test_create_schedule.1.json | 740 +++++++++ .../test_execute_due_schedules.1.json | 878 +++++++++++ .../test_execute_missed_schedules.1.json | 991 ++++++++++++ .../test_execute_recurring_schedule.1.json | 957 ++++++++++++ .../test/testsuit/test_get_all_bills.1.json | 36 + .../testsuit/test_get_overdue_bills.1.json | 30 + .../test/testsuit/test_get_schedules.1.json | 1327 ++++++++++++++++ .../testsuit/test_get_total_unpaid.1.json | 18 + .../testsuit/test_get_unpaid_bills.1.json | 30 + .../test/testsuit/test_modify_schedule.1.json | 895 +++++++++++ .../test_multiple_recurring_payments.1.json | 30 + .../test_pay_already_paid_bill.1.json | 6 + .../test/testsuit/test_pay_bill.1.json | 12 + .../test_pay_bill_unauthorized.1.json | 6 + .../testsuit/test_pay_overdue_bill.1.json | 12 + .../test/testsuit/test_recurring_bill.1.json | 24 + .../test_schedule_validation_past_date.1.json | 502 +++++++ .../testsuit/test_short_recurrence.1.json | 18 + insurance/src/lib.rs | 461 +++--- insurance/src/test.rs | 461 +++--- .../test/test_cancel_premium_schedule.1.json | 890 +++++++++++ .../test/test_create_policy.1.json | 12 + .../test/test_create_premium_schedule.1.json | 745 +++++++++ .../test/test_deactivate_policy.1.json | 12 + .../test_execute_due_premium_schedules.1.json | 860 +++++++++++ ...st_execute_missed_premium_schedules.1.json | 896 +++++++++++ ..._execute_recurring_premium_schedule.1.json | 862 +++++++++++ .../test/test_get_active_policies.1.json | 30 + .../test/test_get_premium_schedules.1.json | 1337 +++++++++++++++++ .../test_get_total_monthly_premium.1.json | 12 + .../test/test_modify_premium_schedule.1.json | 902 +++++++++++ .../test_multiple_premium_payments.1.json | 18 + .../test/test_pay_premium.1.json | 18 + .../test/test_pay_premium_unauthorized.1.json | 8 +- remittance_split/src/lib.rs | 203 +++ remittance_split/src/test.rs | 132 +- .../test_cancel_remittance_schedule.1.json | 925 ++++++++++++ .../test_create_remittance_schedule.1.json | 780 ++++++++++ .../test/test_get_remittance_schedules.1.json | 1122 ++++++++++++++ .../test_modify_remittance_schedule.1.json | 949 ++++++++++++ ...test_remittance_schedule_validation.1.json | 536 +++++++ ...est_remittance_schedule_zero_amount.1.json | 536 +++++++ savings_goals/src/lib.rs | 629 ++++---- savings_goals/src/test.rs | 526 ++++--- .../test/test_add_to_goal_increments.1.json | 6 + .../test/test_cancel_savings_schedule.1.json | 947 ++++++++++++ .../test/test_create_goal_unique_ids.1.json | 12 + .../test/test_create_savings_schedule.1.json | 802 ++++++++++ .../test/test_edge_cases_large_amounts.1.json | 12 + .../test/test_exact_goal_completion.1.json | 12 + .../test_execute_due_savings_schedules.1.json | 902 +++++++++++ ...st_execute_missed_savings_schedules.1.json | 959 ++++++++++++ ..._execute_recurring_savings_schedule.1.json | 1044 +++++++++++++ .../test/test_full_withdrawal.1.json | 12 + .../test/test_get_all_goals.1.json | 24 + .../test/test_get_goal_retrieval.1.json | 12 + .../test/test_is_goal_completed.1.json | 12 + .../test/test_lock_unlock_goal.1.json | 24 + .../test/test_modify_savings_schedule.1.json | 971 ++++++++++++ .../test_multiple_goals_management.1.json | 24 + ...st_savings_schedule_goal_completion.1.json | 986 ++++++++++++ .../test/test_set_time_lock.1.json | 654 ++++++++ .../test/test_withdraw_from_goal.1.json | 12 + .../test/test_withdraw_locked.1.json | 8 +- ...hdraw_time_locked_goal_after_unlock.1.json | 1118 ++++++++++++++ ...draw_time_locked_goal_before_unlock.1.json | 1065 +++++++++++++ .../test/test_withdraw_too_much.1.json | 8 +- .../test/test_withdraw_unauthorized.1.json | 8 +- 73 files changed, 30213 insertions(+), 1444 deletions(-) create mode 100644 bill_payments/src/schedule.rs create mode 100644 bill_payments/test_snapshots/test/testsuit/test_cancel_schedule.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_create_schedule.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_execute_due_schedules.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_execute_missed_schedules.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_execute_recurring_schedule.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_get_schedules.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_modify_schedule.1.json create mode 100644 bill_payments/test_snapshots/test/testsuit/test_schedule_validation_past_date.1.json create mode 100644 insurance/test_snapshots/test/test_cancel_premium_schedule.1.json create mode 100644 insurance/test_snapshots/test/test_create_premium_schedule.1.json create mode 100644 insurance/test_snapshots/test/test_execute_due_premium_schedules.1.json create mode 100644 insurance/test_snapshots/test/test_execute_missed_premium_schedules.1.json create mode 100644 insurance/test_snapshots/test/test_execute_recurring_premium_schedule.1.json create mode 100644 insurance/test_snapshots/test/test_get_premium_schedules.1.json create mode 100644 insurance/test_snapshots/test/test_modify_premium_schedule.1.json create mode 100644 remittance_split/test_snapshots/test/test_cancel_remittance_schedule.1.json create mode 100644 remittance_split/test_snapshots/test/test_create_remittance_schedule.1.json create mode 100644 remittance_split/test_snapshots/test/test_get_remittance_schedules.1.json create mode 100644 remittance_split/test_snapshots/test/test_modify_remittance_schedule.1.json create mode 100644 remittance_split/test_snapshots/test/test_remittance_schedule_validation.1.json create mode 100644 remittance_split/test_snapshots/test/test_remittance_schedule_zero_amount.1.json create mode 100644 savings_goals/test_snapshots/test/test_cancel_savings_schedule.1.json create mode 100644 savings_goals/test_snapshots/test/test_create_savings_schedule.1.json create mode 100644 savings_goals/test_snapshots/test/test_execute_due_savings_schedules.1.json create mode 100644 savings_goals/test_snapshots/test/test_execute_missed_savings_schedules.1.json create mode 100644 savings_goals/test_snapshots/test/test_execute_recurring_savings_schedule.1.json create mode 100644 savings_goals/test_snapshots/test/test_modify_savings_schedule.1.json create mode 100644 savings_goals/test_snapshots/test/test_savings_schedule_goal_completion.1.json create mode 100644 savings_goals/test_snapshots/test/test_set_time_lock.1.json create mode 100644 savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_after_unlock.1.json create mode 100644 savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_before_unlock.1.json diff --git a/bill_payments/src/lib.rs b/bill_payments/src/lib.rs index 85573bc..c9cf55f 100644 --- a/bill_payments/src/lib.rs +++ b/bill_payments/src/lib.rs @@ -4,14 +4,13 @@ use soroban_sdk::{ Vec, }; -// Storage TTL constants for active data +mod schedule; +use schedule::{Schedule, ScheduleEvent}; + +// Storage TTL constants const INSTANCE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day const INSTANCE_BUMP_AMOUNT: u32 = 518400; // ~30 days -// Storage TTL constants for archived data (longer retention, less frequent access) -const ARCHIVE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day -const ARCHIVE_BUMP_AMOUNT: u32 = 2592000; // ~180 days (6 months) - /// Bill data structure with owner tracking for access control #[derive(Clone)] #[contracttype] @@ -26,6 +25,7 @@ pub struct Bill { pub paid: bool, pub created_at: u64, pub paid_at: Option, + pub schedule_id: Option, } #[contracterror] @@ -47,38 +47,6 @@ pub enum BillEvent { Paid, } -/// Archived bill - compressed record with essential fields only -#[contracttype] -#[derive(Clone)] -pub struct ArchivedBill { - pub id: u32, - pub owner: Address, - pub name: String, - pub amount: i128, - pub paid_at: u64, - pub archived_at: u64, -} - -/// Storage statistics for monitoring -#[contracttype] -#[derive(Clone)] -pub struct StorageStats { - pub active_bills: u32, - pub archived_bills: u32, - pub total_unpaid_amount: i128, - pub total_archived_amount: i128, - pub last_updated: u64, -} - -/// Events for archival operations -#[contracttype] -#[derive(Clone)] -pub enum ArchiveEvent { - BillsArchived, - BillRestored, - ArchivesCleaned, -} - #[contract] pub struct BillPayments; @@ -148,6 +116,7 @@ impl BillPayments { paid: false, created_at: current_time, paid_at: None, + schedule_id: None, }; let bill_owner = bill.owner.clone(); @@ -229,6 +198,7 @@ impl BillPayments { paid: false, created_at: current_time, paid_at: None, + schedule_id: bill.schedule_id, }; bills.set(next_id, next_bill); env.storage() @@ -379,304 +349,324 @@ impl BillPayments { result } - /// Archive paid bills that were paid before the specified timestamp. - /// Moves paid bills from active storage to archive storage. + /// Extend the TTL of instance storage + fn extend_instance_ttl(env: &Env) { + env.storage() + .instance() + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); + } + + /// Create a schedule for automatic bill payment /// /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Archive bills paid before this timestamp + /// * `owner` - Address of the schedule owner (must authorize) + /// * `bill_id` - ID of the bill to schedule + /// * `next_due` - Next execution timestamp + /// * `interval` - Interval in seconds for recurring schedules (0 for one-time) /// /// # Returns - /// Number of bills archived - pub fn archive_paid_bills(env: Env, caller: Address, before_timestamp: u64) -> u32 { - caller.require_auth(); - Self::extend_instance_ttl(&env); + /// The ID of the created schedule + pub fn create_schedule( + env: Env, + owner: Address, + bill_id: u32, + next_due: u64, + interval: u64, + ) -> Result { + owner.require_auth(); - let mut bills: Map = env + let bills: Map = env .storage() .instance() .get(&symbol_short!("BILLS")) .unwrap_or_else(|| Map::new(&env)); - let mut archived: Map = env + let mut bill = bills.get(bill_id).ok_or(Error::BillNotFound)?; + + if bill.owner != owner { + return Err(Error::Unauthorized); + } + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + return Err(Error::InvalidAmount); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_BILL")) + .get(&symbol_short!("SCHEDULES")) .unwrap_or_else(|| Map::new(&env)); - let current_time = env.ledger().timestamp(); - let mut archived_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); - - for (id, bill) in bills.iter() { - if let Some(paid_at) = bill.paid_at { - if bill.paid && paid_at < before_timestamp { - let archived_bill = ArchivedBill { - id: bill.id, - owner: bill.owner.clone(), - name: bill.name.clone(), - amount: bill.amount, - paid_at, - archived_at: current_time, - }; - archived.set(id, archived_bill); - to_remove.push_back(id); - archived_count += 1; - } - } - } + let next_schedule_id = env + .storage() + .instance() + .get(&symbol_short!("NEXT_SCH")) + .unwrap_or(0u32) + + 1; - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - bills.remove(id); - } - } + let schedule = Schedule { + id: next_schedule_id, + owner: owner.clone(), + next_due, + interval, + recurring: interval > 0, + active: true, + created_at: current_time, + last_executed: None, + missed_count: 0, + }; + bill.schedule_id = Some(next_schedule_id); + + schedules.set(next_schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("BILLS"), &bills); + .set(&symbol_short!("SCHEDULES"), &schedules); env.storage() .instance() - .set(&symbol_short!("ARCH_BILL"), &archived); + .set(&symbol_short!("NEXT_SCH"), &next_schedule_id); - Self::extend_archive_ttl(&env); - Self::update_storage_stats(&env); + let mut bills_mut = bills; + bills_mut.set(bill_id, bill); + env.storage() + .instance() + .set(&symbol_short!("BILLS"), &bills_mut); env.events().publish( - (symbol_short!("bill"), ArchiveEvent::BillsArchived), - (archived_count, caller), + (symbol_short!("schedule"), ScheduleEvent::Created), + (next_schedule_id, owner), ); - archived_count + Ok(next_schedule_id) } - /// Get all archived bills for a specific owner - /// - /// # Arguments - /// * `owner` - Address of the bill owner - /// - /// # Returns - /// Vec of all ArchivedBill structs belonging to the owner - pub fn get_archived_bills(env: Env, owner: Address) -> Vec { - let archived: Map = env + /// Modify an existing schedule + pub fn modify_schedule( + env: Env, + caller: Address, + schedule_id: u32, + next_due: u64, + interval: u64, + ) -> Result<(), Error> { + caller.require_auth(); + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_BILL")) + .get(&symbol_short!("SCHEDULES")) .unwrap_or_else(|| Map::new(&env)); - let mut result = Vec::new(&env); - for (_, bill) in archived.iter() { - if bill.owner == owner { - result.push_back(bill); - } + let mut schedule = schedules.get(schedule_id).ok_or(Error::BillNotFound)?; + + if schedule.owner != caller { + return Err(Error::Unauthorized); } - result - } - /// Get a specific archived bill by ID - /// - /// # Arguments - /// * `bill_id` - ID of the archived bill - /// - /// # Returns - /// ArchivedBill struct or None if not found - pub fn get_archived_bill(env: Env, bill_id: u32) -> Option { - let archived: Map = env - .storage() + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + return Err(Error::InvalidAmount); + } + + schedule.next_due = next_due; + schedule.interval = interval; + schedule.recurring = interval > 0; + + schedules.set(schedule_id, schedule); + env.storage() .instance() - .get(&symbol_short!("ARCH_BILL")) - .unwrap_or_else(|| Map::new(&env)); + .set(&symbol_short!("SCHEDULES"), &schedules); - archived.get(bill_id) + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Modified), + (schedule_id, caller), + ); + + Ok(()) } - /// Restore an archived bill back to active storage - /// - /// # Arguments - /// * `caller` - Address of the caller (must be the bill owner) - /// * `bill_id` - ID of the bill to restore - /// - /// # Returns - /// Ok(()) if restoration was successful - /// - /// # Errors - /// * `BillNotFound` - If bill is not found in archive - /// * `Unauthorized` - If caller is not the bill owner - pub fn restore_bill(env: Env, caller: Address, bill_id: u32) -> Result<(), Error> { + /// Cancel a schedule + pub fn cancel_schedule(env: Env, caller: Address, schedule_id: u32) -> Result<(), Error> { caller.require_auth(); + Self::extend_instance_ttl(&env); - let mut archived: Map = env + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_BILL")) + .get(&symbol_short!("SCHEDULES")) .unwrap_or_else(|| Map::new(&env)); - let archived_bill = archived.get(bill_id).ok_or(Error::BillNotFound)?; + let mut schedule = schedules.get(schedule_id).ok_or(Error::BillNotFound)?; - if archived_bill.owner != caller { + if schedule.owner != caller { return Err(Error::Unauthorized); } - let mut bills: Map = env - .storage() - .instance() - .get(&symbol_short!("BILLS")) - .unwrap_or_else(|| Map::new(&env)); - - let restored_bill = Bill { - id: archived_bill.id, - owner: archived_bill.owner.clone(), - name: archived_bill.name.clone(), - amount: archived_bill.amount, - due_date: env.ledger().timestamp() + 2592000, // Set new due date 30 days from now - recurring: false, - frequency_days: 0, - paid: true, - created_at: archived_bill.paid_at, - paid_at: Some(archived_bill.paid_at), - }; - - bills.set(bill_id, restored_bill); - archived.remove(bill_id); + schedule.active = false; + schedules.set(schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("BILLS"), &bills); - env.storage() - .instance() - .set(&symbol_short!("ARCH_BILL"), &archived); - - Self::update_storage_stats(&env); + .set(&symbol_short!("SCHEDULES"), &schedules); env.events().publish( - (symbol_short!("bill"), ArchiveEvent::BillRestored), - (bill_id, caller), + (symbol_short!("schedule"), ScheduleEvent::Cancelled), + (schedule_id, caller), ); Ok(()) } - /// Permanently delete old archives before specified timestamp - /// - /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Delete archives created before this timestamp - /// - /// # Returns - /// Number of archives deleted - pub fn bulk_cleanup_bills(env: Env, caller: Address, before_timestamp: u64) -> u32 { - caller.require_auth(); + /// Execute due schedules (public, callable by anyone - keeper pattern) + pub fn execute_due_schedules(env: Env) -> Vec { Self::extend_instance_ttl(&env); - let mut archived: Map = env + let current_time = env.ledger().timestamp(); + let mut executed = Vec::new(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_BILL")) + .get(&symbol_short!("SCHEDULES")) .unwrap_or_else(|| Map::new(&env)); - let mut deleted_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); + let mut bills: Map = env + .storage() + .instance() + .get(&symbol_short!("BILLS")) + .unwrap_or_else(|| Map::new(&env)); - for (id, bill) in archived.iter() { - if bill.archived_at < before_timestamp { - to_remove.push_back(id); - deleted_count += 1; + for (schedule_id, mut schedule) in schedules.iter() { + if !schedule.active || schedule.next_due > current_time { + continue; } - } - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - archived.remove(id); + let bill_id = Self::find_bill_by_schedule(&bills, schedule_id); + if let Some(bid) = bill_id { + if let Some(mut bill) = bills.get(bid) { + if !bill.paid { + bill.paid = true; + bill.paid_at = Some(current_time); + + if bill.recurring { + let next_due_date = bill.due_date + (bill.frequency_days as u64 * 86400); + let next_id = env + .storage() + .instance() + .get(&symbol_short!("NEXT_ID")) + .unwrap_or(0u32) + + 1; + + let next_bill = Bill { + id: next_id, + owner: bill.owner.clone(), + name: bill.name.clone(), + amount: bill.amount, + due_date: next_due_date, + recurring: true, + frequency_days: bill.frequency_days, + paid: false, + created_at: current_time, + paid_at: None, + schedule_id: bill.schedule_id, + }; + bills.set(next_id, next_bill); + env.storage() + .instance() + .set(&symbol_short!("NEXT_ID"), &next_id); + } + + bills.set(bid, bill); + + env.events().publish( + (symbol_short!("bill"), BillEvent::Paid), + (bid, schedule.owner.clone()), + ); + } + } } - } - env.storage() - .instance() - .set(&symbol_short!("ARCH_BILL"), &archived); + schedule.last_executed = Some(current_time); - Self::update_storage_stats(&env); + if schedule.recurring && schedule.interval > 0 { + let mut missed = 0u32; + let mut next = schedule.next_due + schedule.interval; + while next <= current_time { + missed += 1; + next += schedule.interval; + } + schedule.missed_count += missed; + schedule.next_due = next; + + if missed > 0 { + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Missed), + (schedule_id, missed), + ); + } + } else { + schedule.active = false; + } - env.events().publish( - (symbol_short!("bill"), ArchiveEvent::ArchivesCleaned), - (deleted_count, caller), - ); + schedules.set(schedule_id, schedule); + executed.push_back(schedule_id); - deleted_count - } + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Executed), + schedule_id, + ); + } - /// Get storage usage statistics - /// - /// # Returns - /// StorageStats struct with current storage metrics - pub fn get_storage_stats(env: Env) -> StorageStats { env.storage() .instance() - .get(&symbol_short!("STOR_STAT")) - .unwrap_or(StorageStats { - active_bills: 0, - archived_bills: 0, - total_unpaid_amount: 0, - total_archived_amount: 0, - last_updated: 0, - }) - } - - /// Extend the TTL of instance storage - fn extend_instance_ttl(env: &Env) { + .set(&symbol_short!("SCHEDULES"), &schedules); env.storage() .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - } + .set(&symbol_short!("BILLS"), &bills); - /// Extend the TTL of archive storage with longer duration - fn extend_archive_ttl(env: &Env) { - env.storage() - .instance() - .extend_ttl(ARCHIVE_LIFETIME_THRESHOLD, ARCHIVE_BUMP_AMOUNT); + executed } - /// Update storage statistics - fn update_storage_stats(env: &Env) { - let bills: Map = env - .storage() - .instance() - .get(&symbol_short!("BILLS")) - .unwrap_or_else(|| Map::new(env)); - - let archived: Map = env + /// Get all schedules for an owner + pub fn get_schedules(env: Env, owner: Address) -> Vec { + let schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_BILL")) - .unwrap_or_else(|| Map::new(env)); + .get(&symbol_short!("SCHEDULES")) + .unwrap_or_else(|| Map::new(&env)); - let mut active_count = 0u32; - let mut unpaid_amount = 0i128; - for (_, bill) in bills.iter() { - active_count += 1; - if !bill.paid { - unpaid_amount = unpaid_amount.saturating_add(bill.amount); + let mut result = Vec::new(&env); + for (_, schedule) in schedules.iter() { + if schedule.owner == owner { + result.push_back(schedule); } } + result + } - let mut archived_count = 0u32; - let mut archived_amount = 0i128; - for (_, bill) in archived.iter() { - archived_count += 1; - archived_amount = archived_amount.saturating_add(bill.amount); - } + /// Get a specific schedule + pub fn get_schedule(env: Env, schedule_id: u32) -> Option { + let schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("SCHEDULES")) + .unwrap_or_else(|| Map::new(&env)); - let stats = StorageStats { - active_bills: active_count, - archived_bills: archived_count, - total_unpaid_amount: unpaid_amount, - total_archived_amount: archived_amount, - last_updated: env.ledger().timestamp(), - }; + schedules.get(schedule_id) + } - env.storage() - .instance() - .set(&symbol_short!("STOR_STAT"), &stats); + fn find_bill_by_schedule(bills: &Map, schedule_id: u32) -> Option { + for (bill_id, bill) in bills.iter() { + if bill.schedule_id == Some(schedule_id) { + return Some(bill_id); + } + } + None } } diff --git a/bill_payments/src/schedule.rs b/bill_payments/src/schedule.rs new file mode 100644 index 0000000..3d7b553 --- /dev/null +++ b/bill_payments/src/schedule.rs @@ -0,0 +1,28 @@ +#![allow(dead_code)] +use soroban_sdk::{contracttype, Address}; + +/// Schedule data structure for time-based operations +#[derive(Clone)] +#[contracttype] +pub struct Schedule { + pub id: u32, + pub owner: Address, + pub next_due: u64, + pub interval: u64, + pub recurring: bool, + pub active: bool, + pub created_at: u64, + pub last_executed: Option, + pub missed_count: u32, +} + +/// Schedule event types +#[contracttype] +#[derive(Clone)] +pub enum ScheduleEvent { + Created, + Executed, + Missed, + Modified, + Cancelled, +} diff --git a/bill_payments/src/test.rs b/bill_payments/src/test.rs index a037bc7..921ff64 100644 --- a/bill_payments/src/test.rs +++ b/bill_payments/src/test.rs @@ -522,263 +522,233 @@ mod testsuit { assert_eq!(next_bill.due_date, 1000000 + 86400); // Exactly 1 day later } - // ============================================ - // Storage Optimization and Archival Tests - // ============================================ - #[test] - fn test_archive_paid_bills() { + fn test_create_schedule() { let env = Env::default(); - set_time(&env, 2_000_000); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - // Create and pay bills - let id1 = client.create_bill( - &owner, - &String::from_str(&env, "Bill1"), - &100, - &1000000, - &false, - &0, - ); - let id2 = client.create_bill( - &owner, - &String::from_str(&env, "Bill2"), - &200, - &1000000, - &false, - &0, - ); - // Create unpaid bill - client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Bill3"), - &300, - &3000000, + &String::from_str(&env, "Electricity"), + &1000, + &2000, &false, &0, ); - client.pay_bill(&owner, &id1); - client.pay_bill(&owner, &id2); - - // Archive paid bills - let archived_count = client.archive_paid_bills(&owner, &3_000_000); - assert_eq!(archived_count, 2); + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &86400); + assert_eq!(schedule_id, 1); - // Verify only unpaid bill remains active - let all_bills = client.get_all_bills(); - assert_eq!(all_bills.len(), 1); - - // Verify archived bills - let archived = client.get_archived_bills(&owner); - assert_eq!(archived.len(), 2); + let schedule = client.get_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.next_due, 3000); + assert_eq!(schedule.interval, 86400); + assert!(schedule.active); } #[test] - fn test_archive_empty_when_no_paid_bills() { + fn test_modify_schedule() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - client.create_bill( - &owner, - &String::from_str(&env, "Unpaid1"), - &100, - &1000000, - &false, - &0, - ); - client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Unpaid2"), - &200, - &1000000, + &String::from_str(&env, "Electricity"), + &1000, + &2000, &false, &0, ); - let archived_count = client.archive_paid_bills(&owner, &2_000_000); - assert_eq!(archived_count, 0); + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &86400); + client.modify_schedule(&owner, &schedule_id, &4000, &172800); - assert_eq!(client.get_all_bills().len(), 2); - assert_eq!(client.get_archived_bills(&owner).len(), 0); + let schedule = client.get_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 172800); } #[test] - fn test_get_archived_bill() { + fn test_cancel_schedule() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - let id = client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Archive"), - &500, - &1000000, + &String::from_str(&env, "Electricity"), + &1000, + &2000, &false, &0, ); - client.pay_bill(&owner, &id); - client.archive_paid_bills(&owner, &2_000_000); - let archived_bill = client.get_archived_bill(&id); - assert!(archived_bill.is_some()); - let bill = archived_bill.unwrap(); - assert_eq!(bill.id, id); - assert_eq!(bill.amount, 500); + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &86400); + client.cancel_schedule(&owner, &schedule_id); + + let schedule = client.get_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); } #[test] - fn test_restore_bill() { + fn test_execute_due_schedules() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - let id = client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Restore"), - &750, - &1000000, + &String::from_str(&env, "Electricity"), + &1000, + &2000, &false, &0, ); - client.pay_bill(&owner, &id); - client.archive_paid_bills(&owner, &2_000_000); - assert!(client.get_bill(&id).is_none()); - assert!(client.get_archived_bill(&id).is_some()); + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &0); + + set_time(&env, 3500); + let executed = client.execute_due_schedules(); - client.restore_bill(&owner, &id); + assert_eq!(executed.len(), 1); + assert_eq!(executed.get(0).unwrap(), schedule_id); - assert!(client.get_bill(&id).is_some()); - assert!(client.get_archived_bill(&id).is_none()); + let bill = client.get_bill(&bill_id).unwrap(); + assert!(bill.paid); } #[test] - fn test_restore_bill_not_found() { + fn test_execute_recurring_schedule() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - let result = client.try_restore_bill(&owner, &999); - assert_eq!(result, Err(Ok(Error::BillNotFound))); + let bill_id = client.create_bill( + &owner, + &String::from_str(&env, "Electricity"), + &1000, + &2000, + &true, + &30, + ); + + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &86400); + + set_time(&env, 3500); + client.execute_due_schedules(); + + let schedule = client.get_schedule(&schedule_id).unwrap(); + assert!(schedule.active); + assert_eq!(schedule.next_due, 3000 + 86400); } #[test] - fn test_restore_bill_unauthorized() { + fn test_execute_missed_schedules() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); - let other = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - let id = client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Auth"), - &100, - &1000000, - &false, - &0, + &String::from_str(&env, "Electricity"), + &1000, + &2000, + &true, + &30, ); - client.pay_bill(&owner, &id); - client.archive_paid_bills(&owner, &2_000_000); - let result = client.try_restore_bill(&other, &id); - assert_eq!(result, Err(Ok(Error::Unauthorized))); + let schedule_id = client.create_schedule(&owner, &bill_id, &3000, &86400); + + set_time(&env, 3000 + 86400 * 3 + 100); + client.execute_due_schedules(); + + let schedule = client.get_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.missed_count, 3); + assert!(schedule.next_due > 3000 + 86400 * 3); } #[test] - fn test_bulk_cleanup_bills() { + fn test_schedule_validation_past_date() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 5000); - let id1 = client.create_bill( - &owner, - &String::from_str(&env, "Old1"), - &100, - &1000, - &false, - &0, - ); - let id2 = client.create_bill( + let bill_id = client.create_bill( &owner, - &String::from_str(&env, "Old2"), - &200, + &String::from_str(&env, "Electricity"), &1000, + &6000, &false, &0, ); - client.pay_bill(&owner, &id1); - client.pay_bill(&owner, &id2); - - client.archive_paid_bills(&owner, &2000); - assert_eq!(client.get_archived_bills(&owner).len(), 2); - let deleted = client.bulk_cleanup_bills(&owner, &1000000); - assert_eq!(deleted, 2); - assert_eq!(client.get_archived_bills(&owner).len(), 0); + let result = client.try_create_schedule(&owner, &bill_id, &3000, &86400); + assert!(result.is_err()); } #[test] - fn test_storage_stats() { + fn test_get_schedules() { let env = Env::default(); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); env.mock_all_auths(); + set_time(&env, 1000); - let stats = client.get_storage_stats(); - assert_eq!(stats.active_bills, 0); - assert_eq!(stats.archived_bills, 0); - - let id1 = client.create_bill( + let bill_id1 = client.create_bill( &owner, - &String::from_str(&env, "B1"), - &100, + &String::from_str(&env, "Electricity"), &1000, + &2000, &false, &0, ); - client.create_bill( + + let bill_id2 = client.create_bill( &owner, - &String::from_str(&env, "B2"), - &200, - &1000, + &String::from_str(&env, "Water"), + &500, + &2000, &false, &0, ); - client.pay_bill(&owner, &id1); - client.archive_paid_bills(&owner, &2000); + client.create_schedule(&owner, &bill_id1, &3000, &86400); + client.create_schedule(&owner, &bill_id2, &4000, &172800); - let stats = client.get_storage_stats(); - assert_eq!(stats.active_bills, 1); - assert_eq!(stats.archived_bills, 1); - assert_eq!(stats.total_unpaid_amount, 200); - assert_eq!(stats.total_archived_amount, 100); + let schedules = client.get_schedules(&owner); + assert_eq!(schedules.len(), 2); } } diff --git a/bill_payments/test_snapshots/test/testsuit/test_cancel_schedule.1.json b/bill_payments/test_snapshots/test/testsuit/test_cancel_schedule.1.json new file mode 100644 index 0000000..3c6f9f7 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_cancel_schedule.1.json @@ -0,0 +1,883 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "cancel_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "cancel_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "cancel_schedule" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_create_bill.1.json b/bill_payments/test_snapshots/test/testsuit/test_create_bill.1.json index 01afa54..6f9b26c 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_create_bill.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_create_bill.1.json @@ -168,6 +168,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -478,6 +484,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_create_schedule.1.json b/bill_payments/test_snapshots/test/testsuit/test_create_schedule.1.json new file mode 100644 index 0000000..5adbe09 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_create_schedule.1.json @@ -0,0 +1,740 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_execute_due_schedules.1.json b/bill_payments/test_snapshots/test/testsuit/test_execute_due_schedules.1.json new file mode 100644 index 0000000..69fdfc3 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_execute_due_schedules.1.json @@ -0,0 +1,878 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Paid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Executed" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_bill" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_execute_missed_schedules.1.json b/bill_payments/test_snapshots/test/testsuit/test_execute_missed_schedules.1.json new file mode 100644 index 0000000..68a68e5 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_execute_missed_schedules.1.json @@ -0,0 +1,991 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": true + }, + { + "u32": 30 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 262300, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2594000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 348600 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": true + }, + { + "u32": 30 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Paid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Missed" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 3 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Executed" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 348600 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_execute_recurring_schedule.1.json b/bill_payments/test_snapshots/test/testsuit/test_execute_recurring_schedule.1.json new file mode 100644 index 0000000..14d047c --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_execute_recurring_schedule.1.json @@ -0,0 +1,957 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": true + }, + { + "u32": 30 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2594000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 89400 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": true + }, + { + "u32": 30 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Paid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Executed" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 89400 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_get_all_bills.1.json b/bill_payments/test_snapshots/test/testsuit/test_get_all_bills.1.json index 8e5bbe9..8706325 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_get_all_bills.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_get_all_bills.1.json @@ -266,6 +266,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -356,6 +362,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -446,6 +458,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -1155,6 +1173,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] }, @@ -1240,6 +1264,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] }, @@ -1325,6 +1355,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_get_overdue_bills.1.json b/bill_payments/test_snapshots/test/testsuit/test_get_overdue_bills.1.json index 479a7df..0a4745f 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_get_overdue_bills.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_get_overdue_bills.1.json @@ -242,6 +242,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -332,6 +338,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -422,6 +434,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -1008,6 +1026,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] }, @@ -1093,6 +1117,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_get_schedules.1.json b/bill_payments/test_snapshots/test/testsuit/test_get_schedules.1.json new file mode 100644 index 0000000..66ce1e4 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_get_schedules.1.json @@ -0,0 +1,1327 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Water" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 2 + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Water" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 2 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Water" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 2 + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedules" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedules" + } + ], + "data": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_get_total_unpaid.1.json b/bill_payments/test_snapshots/test/testsuit/test_get_total_unpaid.1.json index f8452fb..04fd026 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_get_total_unpaid.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_get_total_unpaid.1.json @@ -266,6 +266,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -356,6 +362,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -446,6 +458,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_get_unpaid_bills.1.json b/bill_payments/test_snapshots/test/testsuit/test_get_unpaid_bills.1.json index 48c0df6..3ab0cc0 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_get_unpaid_bills.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_get_unpaid_bills.1.json @@ -266,6 +266,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -356,6 +362,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -446,6 +458,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -1155,6 +1173,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] }, @@ -1240,6 +1264,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_modify_schedule.1.json b/bill_payments/test_snapshots/test/testsuit/test_modify_schedule.1.json new file mode 100644 index 0000000..3245f79 --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_modify_schedule.1.json @@ -0,0 +1,895 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "modify_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SCHEDULES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 2000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "modify_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Modified" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "modify_schedule" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_multiple_recurring_payments.1.json b/bill_payments/test_snapshots/test/testsuit/test_multiple_recurring_payments.1.json index 10acf2b..0467996 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_multiple_recurring_payments.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_multiple_recurring_payments.1.json @@ -215,6 +215,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -307,6 +313,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -397,6 +409,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -861,6 +879,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -1080,6 +1104,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_pay_already_paid_bill.1.json b/bill_payments/test_snapshots/test/testsuit/test_pay_already_paid_bill.1.json index fb50ecf..e92e319 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_pay_already_paid_bill.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_pay_already_paid_bill.1.json @@ -192,6 +192,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_pay_bill.1.json b/bill_payments/test_snapshots/test/testsuit/test_pay_bill.1.json index 18876f5..f5e6f94 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_pay_bill.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_pay_bill.1.json @@ -192,6 +192,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -625,6 +631,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_pay_bill_unauthorized.1.json b/bill_payments/test_snapshots/test/testsuit/test_pay_bill_unauthorized.1.json index 6f2eff2..8302a0f 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_pay_bill_unauthorized.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_pay_bill_unauthorized.1.json @@ -168,6 +168,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_pay_overdue_bill.1.json b/bill_payments/test_snapshots/test/testsuit/test_pay_overdue_bill.1.json index 69b7175..64dc047 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_pay_overdue_bill.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_pay_overdue_bill.1.json @@ -193,6 +193,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -536,6 +542,12 @@ "val": { "bool": false } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_recurring_bill.1.json b/bill_payments/test_snapshots/test/testsuit/test_recurring_bill.1.json index b22e80f..93354f7 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_recurring_bill.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_recurring_bill.1.json @@ -193,6 +193,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -283,6 +289,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -716,6 +728,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -847,6 +865,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/bill_payments/test_snapshots/test/testsuit/test_schedule_validation_past_date.1.json b/bill_payments/test_snapshots/test/testsuit/test_schedule_validation_past_date.1.json new file mode 100644 index 0000000..eda756d --- /dev/null +++ b/bill_payments/test_snapshots/test/testsuit/test_schedule_validation_past_date.1.json @@ -0,0 +1,502 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_bill", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 6000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 5000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "BILLS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "due_date" + }, + "val": { + "u64": 6000 + } + }, + { + "key": { + "symbol": "frequency_days" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Electricity" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "paid" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "paid_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Electricity" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 6000 + }, + { + "bool": false + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "bill" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_bill" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_schedule" + } + ], + "data": { + "error": { + "contract": 3 + } + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 3 + } + } + ], + "data": { + "string": "escalating Ok(ScErrorType::Contract) frame-exit to Err" + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 3 + } + } + ], + "data": { + "vec": [ + { + "string": "contract try_call failed" + }, + { + "symbol": "create_schedule" + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/bill_payments/test_snapshots/test/testsuit/test_short_recurrence.1.json b/bill_payments/test_snapshots/test/testsuit/test_short_recurrence.1.json index 25928e1..00986f4 100644 --- a/bill_payments/test_snapshots/test/testsuit/test_short_recurrence.1.json +++ b/bill_payments/test_snapshots/test/testsuit/test_short_recurrence.1.json @@ -192,6 +192,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -282,6 +288,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -713,6 +725,12 @@ "val": { "bool": true } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/src/lib.rs b/insurance/src/lib.rs index b56c89d..38f893e 100644 --- a/insurance/src/lib.rs +++ b/insurance/src/lib.rs @@ -3,14 +3,10 @@ use soroban_sdk::{ contract, contractimpl, contracttype, symbol_short, Address, Env, Map, String, Vec, }; -// Storage TTL constants for active data +// Storage TTL constants const INSTANCE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day const INSTANCE_BUMP_AMOUNT: u32 = 518400; // ~30 days -// Storage TTL constants for archived data (longer retention, less frequent access) -const ARCHIVE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day -const ARCHIVE_BUMP_AMOUNT: u32 = 2592000; // ~180 days (6 months) - /// Insurance policy data structure with owner tracking for access control #[derive(Clone)] #[contracttype] @@ -23,48 +19,37 @@ pub struct InsurancePolicy { pub coverage_amount: i128, pub active: bool, pub next_payment_date: u64, + pub schedule_id: Option, } -/// Events emitted by the contract for audit trail +/// Schedule for automatic premium payments #[contracttype] #[derive(Clone)] -pub enum InsuranceEvent { - PolicyCreated, - PremiumPaid, - PolicyDeactivated, -} - -/// Archived policy - compressed record with essential fields only -#[contracttype] -#[derive(Clone)] -pub struct ArchivedPolicy { +pub struct PremiumSchedule { pub id: u32, pub owner: Address, - pub name: String, - pub coverage_type: String, - pub total_coverage: i128, - pub deactivated_at: u64, - pub archived_at: u64, -} - -/// Storage statistics for monitoring -#[contracttype] -#[derive(Clone)] -pub struct StorageStats { - pub active_policies: u32, - pub archived_policies: u32, - pub total_active_coverage: i128, - pub total_archived_coverage: i128, - pub last_updated: u64, + pub policy_id: u32, + pub next_due: u64, + pub interval: u64, + pub recurring: bool, + pub active: bool, + pub created_at: u64, + pub last_executed: Option, + pub missed_count: u32, } -/// Events for archival operations +/// Events emitted by the contract for audit trail #[contracttype] #[derive(Clone)] -pub enum ArchiveEvent { - PoliciesArchived, - PolicyRestored, - ArchivesCleaned, +pub enum InsuranceEvent { + PolicyCreated, + PremiumPaid, + PolicyDeactivated, + ScheduleCreated, + ScheduleExecuted, + ScheduleMissed, + ScheduleModified, + ScheduleCancelled, } #[contract] @@ -135,6 +120,7 @@ impl Insurance { coverage_amount, active: true, next_payment_date, + schedule_id: None, }; let policy_owner = policy.owner.clone(); @@ -319,17 +305,22 @@ impl Insurance { true } - /// Archive inactive policies that were deactivated before the specified timestamp. - /// - /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Archive policies deactivated before this timestamp - /// - /// # Returns - /// Number of policies archived - pub fn archive_inactive_policies(env: Env, caller: Address, before_timestamp: u64) -> u32 { - caller.require_auth(); - Self::extend_instance_ttl(&env); + /// Extend the TTL of instance storage + fn extend_instance_ttl(env: &Env) { + env.storage() + .instance() + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); + } + + /// Create a schedule for automatic premium payments + pub fn create_premium_schedule( + env: Env, + owner: Address, + policy_id: u32, + next_due: u64, + interval: u64, + ) -> u32 { + owner.require_auth(); let mut policies: Map = env .storage() @@ -337,286 +328,250 @@ impl Insurance { .get(&symbol_short!("POLICIES")) .unwrap_or_else(|| Map::new(&env)); - let mut archived: Map = env + let mut policy = policies.get(policy_id).expect("Policy not found"); + + if policy.owner != owner { + panic!("Only the policy owner can create schedules"); + } + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_POL")) + .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); - let current_time = env.ledger().timestamp(); - let mut archived_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); - - for (id, policy) in policies.iter() { - // Archive if policy is inactive and next_payment_date is before the specified timestamp - if !policy.active && policy.next_payment_date < before_timestamp { - let archived_policy = ArchivedPolicy { - id: policy.id, - owner: policy.owner.clone(), - name: policy.name.clone(), - coverage_type: policy.coverage_type.clone(), - total_coverage: policy.coverage_amount, - deactivated_at: policy.next_payment_date, - archived_at: current_time, - }; - archived.set(id, archived_policy); - to_remove.push_back(id); - archived_count += 1; - } - } + let next_schedule_id = env + .storage() + .instance() + .get(&symbol_short!("NEXT_PSCH")) + .unwrap_or(0u32) + + 1; - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - policies.remove(id); - } - } + let schedule = PremiumSchedule { + id: next_schedule_id, + owner: owner.clone(), + policy_id, + next_due, + interval, + recurring: interval > 0, + active: true, + created_at: current_time, + last_executed: None, + missed_count: 0, + }; + policy.schedule_id = Some(next_schedule_id); + + schedules.set(next_schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("POLICIES"), &policies); + .set(&symbol_short!("PREM_SCH"), &schedules); env.storage() .instance() - .set(&symbol_short!("ARCH_POL"), &archived); + .set(&symbol_short!("NEXT_PSCH"), &next_schedule_id); - Self::extend_archive_ttl(&env); - Self::update_storage_stats(&env); + policies.set(policy_id, policy); + env.storage() + .instance() + .set(&symbol_short!("POLICIES"), &policies); env.events().publish( - (symbol_short!("insure"), ArchiveEvent::PoliciesArchived), - (archived_count, caller), + (symbol_short!("insure"), InsuranceEvent::ScheduleCreated), + (next_schedule_id, owner), ); - archived_count + next_schedule_id } - /// Get all archived policies for a specific owner - /// - /// # Arguments - /// * `owner` - Address of the policy owner - /// - /// # Returns - /// Vec of all ArchivedPolicy structs belonging to the owner - pub fn get_archived_policies(env: Env, owner: Address) -> Vec { - let archived: Map = env + /// Modify a premium schedule + pub fn modify_premium_schedule( + env: Env, + caller: Address, + schedule_id: u32, + next_due: u64, + interval: u64, + ) -> bool { + caller.require_auth(); + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_POL")) + .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); - let mut result = Vec::new(&env); - for (_, policy) in archived.iter() { - if policy.owner == owner { - result.push_back(policy); - } + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); + + if schedule.owner != caller { + panic!("Only the schedule owner can modify it"); } - result - } - /// Get a specific archived policy by ID - /// - /// # Arguments - /// * `policy_id` - ID of the archived policy - /// - /// # Returns - /// ArchivedPolicy struct or None if not found - pub fn get_archived_policy(env: Env, policy_id: u32) -> Option { - let archived: Map = env - .storage() + schedule.next_due = next_due; + schedule.interval = interval; + schedule.recurring = interval > 0; + + schedules.set(schedule_id, schedule); + env.storage() .instance() - .get(&symbol_short!("ARCH_POL")) - .unwrap_or_else(|| Map::new(&env)); + .set(&symbol_short!("PREM_SCH"), &schedules); - archived.get(policy_id) + env.events().publish( + (symbol_short!("insure"), InsuranceEvent::ScheduleModified), + (schedule_id, caller), + ); + + true } - /// Restore an archived policy back to active storage - /// - /// # Arguments - /// * `caller` - Address of the caller (must be the policy owner) - /// * `policy_id` - ID of the policy to restore - /// - /// # Returns - /// True if restoration was successful - /// - /// # Panics - /// - If caller is not the policy owner - /// - If policy is not found in archive - pub fn restore_policy(env: Env, caller: Address, policy_id: u32) -> bool { + /// Cancel a premium schedule + pub fn cancel_premium_schedule(env: Env, caller: Address, schedule_id: u32) -> bool { caller.require_auth(); + Self::extend_instance_ttl(&env); - let mut archived: Map = env + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_POL")) + .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); - let archived_policy = match archived.get(policy_id) { - Some(p) => p, - None => panic!("Archived policy not found"), - }; + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); - if archived_policy.owner != caller { - panic!("Only the policy owner can restore this policy"); + if schedule.owner != caller { + panic!("Only the schedule owner can cancel it"); } - let mut policies: Map = env - .storage() - .instance() - .get(&symbol_short!("POLICIES")) - .unwrap_or_else(|| Map::new(&env)); - - let restored_policy = InsurancePolicy { - id: archived_policy.id, - owner: archived_policy.owner.clone(), - name: archived_policy.name.clone(), - coverage_type: archived_policy.coverage_type.clone(), - monthly_premium: archived_policy.total_coverage / 12, // Estimate monthly premium - coverage_amount: archived_policy.total_coverage, - active: false, // Restored as inactive, needs reactivation - next_payment_date: env.ledger().timestamp() + (30 * 86400), - }; - - policies.set(policy_id, restored_policy); - archived.remove(policy_id); + schedule.active = false; + schedules.set(schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("POLICIES"), &policies); - env.storage() - .instance() - .set(&symbol_short!("ARCH_POL"), &archived); - - Self::update_storage_stats(&env); + .set(&symbol_short!("PREM_SCH"), &schedules); env.events().publish( - (symbol_short!("insure"), ArchiveEvent::PolicyRestored), - (policy_id, caller), + (symbol_short!("insure"), InsuranceEvent::ScheduleCancelled), + (schedule_id, caller), ); true } - /// Permanently delete old archives before specified timestamp - /// - /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Delete archives created before this timestamp - /// - /// # Returns - /// Number of archives deleted - pub fn bulk_cleanup_policies(env: Env, caller: Address, before_timestamp: u64) -> u32 { - caller.require_auth(); + /// Execute due premium schedules (public, callable by anyone - keeper pattern) + pub fn execute_due_premium_schedules(env: Env) -> Vec { Self::extend_instance_ttl(&env); - let mut archived: Map = env + let current_time = env.ledger().timestamp(); + let mut executed = Vec::new(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_POL")) + .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); - let mut deleted_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); + let mut policies: Map = env + .storage() + .instance() + .get(&symbol_short!("POLICIES")) + .unwrap_or_else(|| Map::new(&env)); - for (id, policy) in archived.iter() { - if policy.archived_at < before_timestamp { - to_remove.push_back(id); - deleted_count += 1; + for (schedule_id, mut schedule) in schedules.iter() { + if !schedule.active || schedule.next_due > current_time { + continue; } - } - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - archived.remove(id); - } - } + if let Some(mut policy) = policies.get(schedule.policy_id) { + if policy.active { + policy.next_payment_date = current_time + (30 * 86400); + policies.set(schedule.policy_id, policy.clone()); - env.storage() - .instance() - .set(&symbol_short!("ARCH_POL"), &archived); + env.events().publish( + (symbol_short!("insure"), InsuranceEvent::PremiumPaid), + (schedule.policy_id, policy.owner), + ); + } + } - Self::update_storage_stats(&env); + schedule.last_executed = Some(current_time); + + if schedule.recurring && schedule.interval > 0 { + let mut missed = 0u32; + let mut next = schedule.next_due + schedule.interval; + while next <= current_time { + missed += 1; + next += schedule.interval; + } + schedule.missed_count += missed; + schedule.next_due = next; + + if missed > 0 { + env.events().publish( + (symbol_short!("insure"), InsuranceEvent::ScheduleMissed), + (schedule_id, missed), + ); + } + } else { + schedule.active = false; + } - env.events().publish( - (symbol_short!("insure"), ArchiveEvent::ArchivesCleaned), - (deleted_count, caller), - ); + schedules.set(schedule_id, schedule); + executed.push_back(schedule_id); - deleted_count - } + env.events().publish( + (symbol_short!("insure"), InsuranceEvent::ScheduleExecuted), + schedule_id, + ); + } - /// Get storage usage statistics - /// - /// # Returns - /// StorageStats struct with current storage metrics - pub fn get_storage_stats(env: Env) -> StorageStats { env.storage() .instance() - .get(&symbol_short!("STOR_STAT")) - .unwrap_or(StorageStats { - active_policies: 0, - archived_policies: 0, - total_active_coverage: 0, - total_archived_coverage: 0, - last_updated: 0, - }) - } - - /// Extend the TTL of instance storage - fn extend_instance_ttl(env: &Env) { + .set(&symbol_short!("PREM_SCH"), &schedules); env.storage() .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - } + .set(&symbol_short!("POLICIES"), &policies); - /// Extend the TTL of archive storage with longer duration - fn extend_archive_ttl(env: &Env) { - env.storage() - .instance() - .extend_ttl(ARCHIVE_LIFETIME_THRESHOLD, ARCHIVE_BUMP_AMOUNT); + executed } - /// Update storage statistics - fn update_storage_stats(env: &Env) { - let policies: Map = env + /// Get all premium schedules for an owner + pub fn get_premium_schedules(env: Env, owner: Address) -> Vec { + let schedules: Map = env .storage() .instance() - .get(&symbol_short!("POLICIES")) - .unwrap_or_else(|| Map::new(env)); - - let archived: Map = env - .storage() - .instance() - .get(&symbol_short!("ARCH_POL")) - .unwrap_or_else(|| Map::new(env)); + .get(&symbol_short!("PREM_SCH")) + .unwrap_or_else(|| Map::new(&env)); - let mut active_count = 0u32; - let mut active_coverage = 0i128; - for (_, policy) in policies.iter() { - if policy.active { - active_count += 1; - active_coverage = active_coverage.saturating_add(policy.coverage_amount); + let mut result = Vec::new(&env); + for (_, schedule) in schedules.iter() { + if schedule.owner == owner { + result.push_back(schedule); } } + result + } - let mut archived_count = 0u32; - let mut archived_coverage = 0i128; - for (_, policy) in archived.iter() { - archived_count += 1; - archived_coverage = archived_coverage.saturating_add(policy.total_coverage); - } - - let stats = StorageStats { - active_policies: active_count, - archived_policies: archived_count, - total_active_coverage: active_coverage, - total_archived_coverage: archived_coverage, - last_updated: env.ledger().timestamp(), - }; - - env.storage() + /// Get a specific premium schedule + pub fn get_premium_schedule(env: Env, schedule_id: u32) -> Option { + let schedules: Map = env + .storage() .instance() - .set(&symbol_short!("STOR_STAT"), &stats); + .get(&symbol_short!("PREM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + schedules.get(schedule_id) } } diff --git a/insurance/src/test.rs b/insurance/src/test.rs index e410b06..3aa1252 100644 --- a/insurance/src/test.rs +++ b/insurance/src/test.rs @@ -2,10 +2,25 @@ use super::*; use soroban_sdk::{ - testutils::{Address as _, Ledger}, + testutils::{Address as AddressTrait, Ledger, LedgerInfo}, Address, Env, String, }; +fn set_time(env: &Env, timestamp: u64) { + let proto = env.ledger().protocol_version(); + + env.ledger().set(LedgerInfo { + protocol_version: proto, + sequence_number: 1, + timestamp, + network_id: [0; 32], + base_reserve: 10, + min_temp_entry_ttl: 1, + min_persistent_entry_ttl: 1, + max_entry_ttl: 100000, + }); +} + #[test] fn test_create_policy() { let env = Env::default(); @@ -269,251 +284,201 @@ fn test_multiple_premium_payments() { ); } -// ============================================ -// Storage Optimization and Archival Tests -// ============================================ - -#[test] -fn test_archive_inactive_policies() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - // Create policies - let id1 = client.create_policy( - &owner, - &String::from_str(&env, "Policy1"), - &String::from_str(&env, "Health"), - &100, - &10000, - ); - let id2 = client.create_policy( - &owner, - &String::from_str(&env, "Policy2"), - &String::from_str(&env, "Life"), - &200, - &20000, - ); - // Keep one active - client.create_policy( - &owner, - &String::from_str(&env, "Policy3"), - &String::from_str(&env, "Auto"), - &150, - &15000, - ); - - // Deactivate policies 1 and 2 - client.deactivate_policy(&owner, &id1); - client.deactivate_policy(&owner, &id2); - - // Archive inactive policies - let archived_count = client.archive_inactive_policies(&owner, &3_000_000_000); - assert_eq!(archived_count, 2); - - // Verify only active policy remains - let active = client.get_active_policies(&owner); - assert_eq!(active.len(), 1); - - // Verify archived policies - let archived = client.get_archived_policies(&owner); - assert_eq!(archived.len(), 2); -} - #[test] -fn test_archive_empty_when_all_active() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - client.create_policy( - &owner, - &String::from_str(&env, "Active1"), - &String::from_str(&env, "Health"), - &100, - &10000, - ); - client.create_policy( - &owner, - &String::from_str(&env, "Active2"), - &String::from_str(&env, "Life"), - &200, - &20000, - ); - - let archived_count = client.archive_inactive_policies(&owner, &3_000_000_000); - assert_eq!(archived_count, 0); - - assert_eq!(client.get_active_policies(&owner).len(), 2); - assert_eq!(client.get_archived_policies(&owner).len(), 0); -} - -#[test] -fn test_get_archived_policy() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - let id = client.create_policy( - &owner, - &String::from_str(&env, "Archive"), - &String::from_str(&env, "Health"), - &100, - &5000, - ); - client.deactivate_policy(&owner, &id); - client.archive_inactive_policies(&owner, &3_000_000_000); - - let archived_policy = client.get_archived_policy(&id); - assert!(archived_policy.is_some()); - let policy = archived_policy.unwrap(); - assert_eq!(policy.id, id); - assert_eq!(policy.total_coverage, 5000); -} - -#[test] -fn test_restore_policy() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - let id = client.create_policy( - &owner, - &String::from_str(&env, "Restore"), - &String::from_str(&env, "Life"), - &150, - &15000, - ); - client.deactivate_policy(&owner, &id); - client.archive_inactive_policies(&owner, &3_000_000_000); - - assert!(client.get_policy(&id).is_none()); - assert!(client.get_archived_policy(&id).is_some()); - - let restored = client.restore_policy(&owner, &id); - assert!(restored); - - assert!(client.get_policy(&id).is_some()); - assert!(client.get_archived_policy(&id).is_none()); -} - -#[test] -#[should_panic(expected = "Archived policy not found")] -fn test_restore_nonexistent_policy() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - client.restore_policy(&owner, &999); -} - -#[test] -#[should_panic(expected = "Only the policy owner can restore this policy")] -fn test_restore_policy_unauthorized() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - let other = Address::generate(&env); - - env.mock_all_auths(); - - let id = client.create_policy( - &owner, - &String::from_str(&env, "Auth"), - &String::from_str(&env, "Health"), - &100, - &10000, - ); - client.deactivate_policy(&owner, &id); - client.archive_inactive_policies(&owner, &3_000_000_000); - - client.restore_policy(&other, &id); -} - -#[test] -fn test_bulk_cleanup_policies() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - let id1 = client.create_policy( - &owner, - &String::from_str(&env, "Old1"), - &String::from_str(&env, "Health"), - &100, - &1000, - ); - let id2 = client.create_policy( - &owner, - &String::from_str(&env, "Old2"), - &String::from_str(&env, "Life"), - &200, - &2000, - ); - client.deactivate_policy(&owner, &id1); - client.deactivate_policy(&owner, &id2); - - client.archive_inactive_policies(&owner, &3_000_000_000); - assert_eq!(client.get_archived_policies(&owner).len(), 2); - - let deleted = client.bulk_cleanup_policies(&owner, &1000000); - assert_eq!(deleted, 2); - assert_eq!(client.get_archived_policies(&owner).len(), 0); -} - -#[test] -fn test_storage_stats() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); - - env.mock_all_auths(); - - let stats = client.get_storage_stats(); - assert_eq!(stats.active_policies, 0); - assert_eq!(stats.archived_policies, 0); - - let id1 = client.create_policy( - &owner, - &String::from_str(&env, "P1"), - &String::from_str(&env, "Health"), - &100, - &10000, - ); - client.create_policy( - &owner, - &String::from_str(&env, "P2"), - &String::from_str(&env, "Life"), - &200, - &20000, - ); - client.deactivate_policy(&owner, &id1); - - client.archive_inactive_policies(&owner, &3_000_000_000); - - let stats = client.get_storage_stats(); - assert_eq!(stats.active_policies, 1); - assert_eq!(stats.archived_policies, 1); - assert_eq!(stats.total_active_coverage, 20000); - assert_eq!(stats.total_archived_coverage, 10000); -} +fn test_create_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + assert_eq!(schedule_id, 1); + + let schedule = client.get_premium_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.next_due, 3000); + assert_eq!(schedule.interval, 2592000); + assert!(schedule.active); + } + + #[test] + fn test_modify_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + client.modify_premium_schedule(&owner, &schedule_id, &4000, &2678400); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 2678400); + } + + #[test] + fn test_cancel_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + client.cancel_premium_schedule(&owner, &schedule_id); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); + } + + #[test] + fn test_execute_due_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &0); + + set_time(&env, 3500); + let executed = client.execute_due_premium_schedules(); + + assert_eq!(executed.len(), 1); + assert_eq!(executed.get(0).unwrap(), schedule_id); + + let policy = client.get_policy(&policy_id).unwrap(); + assert_eq!(policy.next_payment_date, 3500 + 30 * 86400); + } + + #[test] + fn test_execute_recurring_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + + set_time(&env, 3500); + client.execute_due_premium_schedules(); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert!(schedule.active); + assert_eq!(schedule.next_due, 3000 + 2592000); + } + + #[test] + fn test_execute_missed_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + + set_time(&env, 3000 + 2592000 * 3 + 100); + client.execute_due_premium_schedules(); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.missed_count, 3); + assert!(schedule.next_due > 3000 + 2592000 * 3); + } + + #[test] + fn test_get_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id1 = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let policy_id2 = client.create_policy( + &owner, + &String::from_str(&env, "Life Insurance"), + &String::from_str(&env, "life"), + &300, + &100000, + ); + + client.create_premium_schedule(&owner, &policy_id1, &3000, &2592000); + client.create_premium_schedule(&owner, &policy_id2, &4000, &2592000); + + let schedules = client.get_premium_schedules(&owner); + assert_eq!(schedules.len(), 2); + } diff --git a/insurance/test_snapshots/test/test_cancel_premium_schedule.1.json b/insurance/test_snapshots/test/test_cancel_premium_schedule.1.json new file mode 100644 index 0000000..d848b8a --- /dev/null +++ b/insurance/test_snapshots/test/test_cancel_premium_schedule.1.json @@ -0,0 +1,890 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "cancel_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2593000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "cancel_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCancelled" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "cancel_premium_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_create_policy.1.json b/insurance/test_snapshots/test/test_create_policy.1.json index a278682..6dcd997 100644 --- a/insurance/test_snapshots/test/test_create_policy.1.json +++ b/insurance/test_snapshots/test/test_create_policy.1.json @@ -165,6 +165,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -456,6 +462,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_create_premium_schedule.1.json b/insurance/test_snapshots/test/test_create_premium_schedule.1.json new file mode 100644 index 0000000..369a341 --- /dev/null +++ b/insurance/test_snapshots/test/test_create_premium_schedule.1.json @@ -0,0 +1,745 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2593000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_deactivate_policy.1.json b/insurance/test_snapshots/test/test_deactivate_policy.1.json index 9ddf02e..4006b2c 100644 --- a/insurance/test_snapshots/test/test_deactivate_policy.1.json +++ b/insurance/test_snapshots/test/test_deactivate_policy.1.json @@ -187,6 +187,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -601,6 +607,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_execute_due_premium_schedules.1.json b/insurance/test_snapshots/test/test_execute_due_premium_schedules.1.json new file mode 100644 index 0000000..69a19eb --- /dev/null +++ b/insurance/test_snapshots/test/test_execute_due_premium_schedules.1.json @@ -0,0 +1,860 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2595500 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PremiumPaid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_policy" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2595500 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_execute_missed_premium_schedules.1.json b/insurance/test_snapshots/test/test_execute_missed_premium_schedules.1.json new file mode 100644 index 0000000..7699857 --- /dev/null +++ b/insurance/test_snapshots/test/test_execute_missed_premium_schedules.1.json @@ -0,0 +1,896 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 7779100, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 10371100 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 7779100 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 10371000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PremiumPaid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleMissed" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 3 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 7779100 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 10371000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_execute_recurring_premium_schedule.1.json b/insurance/test_snapshots/test/test_execute_recurring_premium_schedule.1.json new file mode 100644 index 0000000..b079d7d --- /dev/null +++ b/insurance/test_snapshots/test/test_execute_recurring_premium_schedule.1.json @@ -0,0 +1,862 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2595500 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 2595000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PremiumPaid" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_premium_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 2595000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_get_active_policies.1.json b/insurance/test_snapshots/test/test_get_active_policies.1.json index 1840dd9..cd8baf1 100644 --- a/insurance/test_snapshots/test/test_get_active_policies.1.json +++ b/insurance/test_snapshots/test/test_get_active_policies.1.json @@ -261,6 +261,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -340,6 +346,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -419,6 +431,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -1111,6 +1129,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] }, @@ -1185,6 +1209,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_get_premium_schedules.1.json b/insurance/test_snapshots/test/test_get_premium_schedules.1.json new file mode 100644 index 0000000..fbac64e --- /dev/null +++ b/insurance/test_snapshots/test/test_get_premium_schedules.1.json @@ -0,0 +1,1337 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Life Insurance" + }, + { + "string": "life" + }, + { + "i128": { + "hi": 0, + "lo": 300 + } + }, + { + "i128": { + "hi": 0, + "lo": 100000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 2 + }, + { + "u64": 4000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2593000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "life" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 300 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Life Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2593000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 2 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Life Insurance" + }, + { + "string": "life" + }, + { + "i128": { + "hi": 0, + "lo": 300 + } + }, + { + "i128": { + "hi": 0, + "lo": 100000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 2 + }, + { + "u64": 4000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedules" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedules" + } + ], + "data": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_get_total_monthly_premium.1.json b/insurance/test_snapshots/test/test_get_total_monthly_premium.1.json index 32b0dbd..0122ba1 100644 --- a/insurance/test_snapshots/test/test_get_total_monthly_premium.1.json +++ b/insurance/test_snapshots/test/test_get_total_monthly_premium.1.json @@ -202,6 +202,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -281,6 +287,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_modify_premium_schedule.1.json b/insurance/test_snapshots/test/test_modify_premium_schedule.1.json new file mode 100644 index 0000000..f69fb33 --- /dev/null +++ b/insurance/test_snapshots/test/test_modify_premium_schedule.1.json @@ -0,0 +1,902 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_policy", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "modify_premium_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 4000 + }, + { + "u64": 2678400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_PSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "POLICIES" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "coverage_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 50000 + } + } + }, + { + "key": { + "symbol": "coverage_type" + }, + "val": { + "string": "health" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "monthly_premium" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Health Insurance" + } + }, + { + "key": { + "symbol": "next_payment_date" + }, + "val": { + "u64": 2593000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "PREM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2678400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Health Insurance" + }, + { + "string": "health" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "i128": { + "hi": 0, + "lo": 50000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "PolicyCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_policy" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + }, + { + "u64": 2592000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "modify_premium_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 4000 + }, + { + "u64": 2678400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "insure" + }, + { + "vec": [ + { + "symbol": "ScheduleModified" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "modify_premium_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_premium_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 2678400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "policy_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/insurance/test_snapshots/test/test_multiple_premium_payments.1.json b/insurance/test_snapshots/test/test_multiple_premium_payments.1.json index ad47354..4de6e40 100644 --- a/insurance/test_snapshots/test/test_multiple_premium_payments.1.json +++ b/insurance/test_snapshots/test/test_multiple_premium_payments.1.json @@ -210,6 +210,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -567,6 +573,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -867,6 +879,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_pay_premium.1.json b/insurance/test_snapshots/test/test_pay_premium.1.json index 6776b75..cf74395 100644 --- a/insurance/test_snapshots/test/test_pay_premium.1.json +++ b/insurance/test_snapshots/test/test_pay_premium.1.json @@ -188,6 +188,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -512,6 +518,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -722,6 +734,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } diff --git a/insurance/test_snapshots/test/test_pay_premium_unauthorized.1.json b/insurance/test_snapshots/test/test_pay_premium_unauthorized.1.json index ef38f5c..1190f73 100644 --- a/insurance/test_snapshots/test/test_pay_premium_unauthorized.1.json +++ b/insurance/test_snapshots/test/test_pay_premium_unauthorized.1.json @@ -165,6 +165,12 @@ "val": { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } + }, + { + "key": { + "symbol": "schedule_id" + }, + "val": "void" } ] } @@ -392,7 +398,7 @@ "data": { "vec": [ { - "string": "caught panic 'Only the policy owner can pay premiums' from contract function 'Symbol(obj#45)'" + "string": "caught panic 'Only the policy owner can pay premiums' from contract function 'Symbol(obj#47)'" }, { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" diff --git a/remittance_split/src/lib.rs b/remittance_split/src/lib.rs index 658145f..656430b 100644 --- a/remittance_split/src/lib.rs +++ b/remittance_split/src/lib.rs @@ -64,6 +64,33 @@ pub struct AuditEntry { pub success: bool, } +/// Schedule for automatic remittance splits +#[contracttype] +#[derive(Clone)] +pub struct RemittanceSchedule { + pub id: u32, + pub owner: Address, + pub amount: i128, + pub next_due: u64, + pub interval: u64, + pub recurring: bool, + pub active: bool, + pub created_at: u64, + pub last_executed: Option, + pub missed_count: u32, +} + +/// Schedule event types +#[contracttype] +#[derive(Clone)] +pub enum ScheduleEvent { + Created, + Executed, + Missed, + Modified, + Cancelled, +} + const SNAPSHOT_VERSION: u32 = 1; const MAX_AUDIT_ENTRIES: u32 = 100; @@ -513,6 +540,182 @@ impl RemittanceSplit { .instance() .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); } + + /// Create a schedule for automatic remittance splits + pub fn create_remittance_schedule( + env: Env, + owner: Address, + amount: i128, + next_due: u64, + interval: u64, + ) -> u32 { + owner.require_auth(); + + if amount <= 0 { + panic!("Amount must be positive"); + } + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("REM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let next_schedule_id = env + .storage() + .instance() + .get(&symbol_short!("NEXT_RSCH")) + .unwrap_or(0u32) + + 1; + + let schedule = RemittanceSchedule { + id: next_schedule_id, + owner: owner.clone(), + amount, + next_due, + interval, + recurring: interval > 0, + active: true, + created_at: current_time, + last_executed: None, + missed_count: 0, + }; + + schedules.set(next_schedule_id, schedule); + env.storage() + .instance() + .set(&symbol_short!("REM_SCH"), &schedules); + env.storage() + .instance() + .set(&symbol_short!("NEXT_RSCH"), &next_schedule_id); + + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Created), + (next_schedule_id, owner), + ); + + next_schedule_id + } + + /// Modify a remittance schedule + pub fn modify_remittance_schedule( + env: Env, + caller: Address, + schedule_id: u32, + amount: i128, + next_due: u64, + interval: u64, + ) -> bool { + caller.require_auth(); + + if amount <= 0 { + panic!("Amount must be positive"); + } + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("REM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); + + if schedule.owner != caller { + panic!("Only the schedule owner can modify it"); + } + + schedule.amount = amount; + schedule.next_due = next_due; + schedule.interval = interval; + schedule.recurring = interval > 0; + + schedules.set(schedule_id, schedule); + env.storage() + .instance() + .set(&symbol_short!("REM_SCH"), &schedules); + + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Modified), + (schedule_id, caller), + ); + + true + } + + /// Cancel a remittance schedule + pub fn cancel_remittance_schedule(env: Env, caller: Address, schedule_id: u32) -> bool { + caller.require_auth(); + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("REM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); + + if schedule.owner != caller { + panic!("Only the schedule owner can cancel it"); + } + + schedule.active = false; + + schedules.set(schedule_id, schedule); + env.storage() + .instance() + .set(&symbol_short!("REM_SCH"), &schedules); + + env.events().publish( + (symbol_short!("schedule"), ScheduleEvent::Cancelled), + (schedule_id, caller), + ); + + true + } + + /// Get all remittance schedules for an owner + pub fn get_remittance_schedules(env: Env, owner: Address) -> Vec { + let schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("REM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let mut result = Vec::new(&env); + for (_, schedule) in schedules.iter() { + if schedule.owner == owner { + result.push_back(schedule); + } + } + result + } + + /// Get a specific remittance schedule + pub fn get_remittance_schedule(env: Env, schedule_id: u32) -> Option { + let schedules: Map = env + .storage() + .instance() + .get(&symbol_short!("REM_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + schedules.get(schedule_id) + } } mod test; diff --git a/remittance_split/src/test.rs b/remittance_split/src/test.rs index b14665f..0237a32 100644 --- a/remittance_split/src/test.rs +++ b/remittance_split/src/test.rs @@ -1,7 +1,22 @@ #![cfg(test)] use super::*; -use soroban_sdk::{testutils::Address as _, Address, Env}; +use soroban_sdk::{testutils::{Address as AddressTrait, Ledger, LedgerInfo}, Address, Env}; + +fn set_time(env: &Env, timestamp: u64) { + let proto = env.ledger().protocol_version(); + + env.ledger().set(LedgerInfo { + protocol_version: proto, + sequence_number: 1, + timestamp, + network_id: [0; 32], + base_reserve: 10, + min_temp_entry_ttl: 1, + min_persistent_entry_ttl: 1, + max_entry_ttl: 100000, + }); +} #[test] fn test_initialize_split() { @@ -195,3 +210,118 @@ fn test_calculate_complex_rounding() { assert_eq!(tiny_amounts.get(0).unwrap(), 0); assert_eq!(tiny_amounts.get(3).unwrap(), 3); } + +#[test] +fn test_create_remittance_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + assert_eq!(schedule_id, 1); + + let schedule = client.get_remittance_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.amount, 10000); + assert_eq!(schedule.next_due, 3000); + assert_eq!(schedule.interval, 86400); + assert!(schedule.active); + } + + #[test] + fn test_modify_remittance_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.modify_remittance_schedule(&owner, &schedule_id, &15000, &4000, &172800); + + let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.amount, 15000); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 172800); + } + + #[test] + fn test_cancel_remittance_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.cancel_remittance_schedule(&owner, &schedule_id); + + let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); + } + + #[test] + fn test_get_remittance_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.create_remittance_schedule(&owner, &5000, &4000, &172800); + + let schedules = client.get_remittance_schedules(&owner); + assert_eq!(schedules.len(), 2); + } + + #[test] + fn test_remittance_schedule_validation() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 5000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let result = client.try_create_remittance_schedule(&owner, &10000, &3000, &86400); + assert!(result.is_err()); + } + + #[test] + fn test_remittance_schedule_zero_amount() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let result = client.try_create_remittance_schedule(&owner, &0, &3000, &86400); + assert!(result.is_err()); + } diff --git a/remittance_split/test_snapshots/test/test_cancel_remittance_schedule.1.json b/remittance_split/test_snapshots/test/test_cancel_remittance_schedule.1.json new file mode 100644 index 0000000..11e76d4 --- /dev/null +++ b/remittance_split/test_snapshots/test/test_cancel_remittance_schedule.1.json @@ -0,0 +1,925 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "cancel_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_RSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "REM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "cancel_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "cancel_remittance_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/remittance_split/test_snapshots/test/test_create_remittance_schedule.1.json b/remittance_split/test_snapshots/test/test_create_remittance_schedule.1.json new file mode 100644 index 0000000..6c1e125 --- /dev/null +++ b/remittance_split/test_snapshots/test/test_create_remittance_schedule.1.json @@ -0,0 +1,780 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_RSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "REM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/remittance_split/test_snapshots/test/test_get_remittance_schedules.1.json b/remittance_split/test_snapshots/test/test_get_remittance_schedules.1.json new file mode 100644 index 0000000..a9f01ba --- /dev/null +++ b/remittance_split/test_snapshots/test/test_get_remittance_schedules.1.json @@ -0,0 +1,1122 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_RSCH" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "REM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + }, + { + "key": { + "u32": 2 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 5000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "u32": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_remittance_schedules" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_remittance_schedules" + } + ], + "data": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 5000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/remittance_split/test_snapshots/test/test_modify_remittance_schedule.1.json b/remittance_split/test_snapshots/test/test_modify_remittance_schedule.1.json new file mode 100644 index 0000000..6d1a578 --- /dev/null +++ b/remittance_split/test_snapshots/test/test_modify_remittance_schedule.1.json @@ -0,0 +1,949 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "modify_remittance_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 15000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_RSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "REM_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 15000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Created" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "modify_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 15000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "schedule" + }, + { + "vec": [ + { + "symbol": "Modified" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "modify_remittance_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_remittance_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 15000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/remittance_split/test_snapshots/test/test_remittance_schedule_validation.1.json b/remittance_split/test_snapshots/test/test_remittance_schedule_validation.1.json new file mode 100644 index 0000000..12cee21 --- /dev/null +++ b/remittance_split/test_snapshots/test/test_remittance_schedule_validation.1.json @@ -0,0 +1,536 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 5000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 5000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "log" + } + ], + "data": { + "vec": [ + { + "string": "caught panic 'Next due date must be in the future' from contract function 'Symbol(obj#47)'" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "string": "caught error from function" + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "contract try_call failed" + }, + { + "symbol": "create_remittance_schedule" + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/remittance_split/test_snapshots/test/test_remittance_schedule_zero_amount.1.json b/remittance_split/test_snapshots/test/test_remittance_schedule_zero_amount.1.json new file mode 100644 index 0000000..12a7430 --- /dev/null +++ b/remittance_split/test_snapshots/test/test_remittance_schedule_zero_amount.1.json @@ -0,0 +1,536 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "init" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "CONFIG" + }, + "val": { + "map": [ + { + "key": { + "symbol": "bills_percent" + }, + "val": { + "u32": 15 + } + }, + { + "key": { + "symbol": "initialized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "insurance_percent" + }, + "val": { + "u32": 5 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "savings_percent" + }, + "val": { + "u32": 30 + } + }, + { + "key": { + "symbol": "spending_percent" + }, + "val": { + "u32": 50 + } + } + ] + } + }, + { + "key": { + "symbol": "NONCES" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + "val": { + "u64": 1 + } + } + ] + } + }, + { + "key": { + "symbol": "SPLIT" + }, + "val": { + "vec": [ + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u64": 0 + }, + { + "u32": 50 + }, + { + "u32": 30 + }, + { + "u32": 15 + }, + { + "u32": 5 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "split" + }, + { + "vec": [ + { + "symbol": "Initialized" + } + ] + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize_split" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_remittance_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 0 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "log" + } + ], + "data": { + "vec": [ + { + "string": "caught panic 'Amount must be positive' from contract function 'Symbol(obj#47)'" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 0 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "string": "caught error from function" + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "contract try_call failed" + }, + { + "symbol": "create_remittance_schedule" + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 0 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/src/lib.rs b/savings_goals/src/lib.rs index 8fb832d..27e8c63 100644 --- a/savings_goals/src/lib.rs +++ b/savings_goals/src/lib.rs @@ -3,14 +3,10 @@ use soroban_sdk::{ contract, contractimpl, contracttype, symbol_short, Address, Env, Map, String, Symbol, Vec, }; -// Storage TTL constants for active data +// Storage TTL constants const INSTANCE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day const INSTANCE_BUMP_AMOUNT: u32 = 518400; // ~30 days -// Storage TTL constants for archived data (longer retention, less frequent access) -const ARCHIVE_LIFETIME_THRESHOLD: u32 = 17280; // ~1 day -const ARCHIVE_BUMP_AMOUNT: u32 = 2592000; // ~180 days (6 months) - /// Savings goal data structure with owner tracking for access control #[contract] pub struct SavingsGoalContract; @@ -25,6 +21,24 @@ pub struct SavingsGoal { pub current_amount: i128, pub target_date: u64, pub locked: bool, + pub unlock_date: Option, +} + +/// Schedule for automatic savings deposits +#[contracttype] +#[derive(Clone)] +pub struct SavingsSchedule { + pub id: u32, + pub owner: Address, + pub goal_id: u32, + pub amount: i128, + pub next_due: u64, + pub interval: u64, + pub recurring: bool, + pub active: bool, + pub created_at: u64, + pub last_executed: Option, + pub missed_count: u32, } /// Events emitted by the contract for audit trail @@ -37,6 +51,11 @@ pub enum SavingsEvent { GoalCompleted, GoalLocked, GoalUnlocked, + ScheduleCreated, + ScheduleExecuted, + ScheduleMissed, + ScheduleModified, + ScheduleCancelled, } /// Snapshot for goals export/import (migration). Checksum is numeric for on-chain verification. @@ -59,38 +78,6 @@ pub struct AuditEntry { pub success: bool, } -/// Archived goal - compressed record with essential fields only -#[contracttype] -#[derive(Clone)] -pub struct ArchivedGoal { - pub id: u32, - pub owner: Address, - pub name: String, - pub target_amount: i128, - pub final_amount: i128, - pub archived_at: u64, -} - -/// Storage statistics for monitoring -#[contracttype] -#[derive(Clone)] -pub struct StorageStats { - pub active_goals: u32, - pub archived_goals: u32, - pub total_active_amount: i128, - pub total_archived_amount: i128, - pub last_updated: u64, -} - -/// Events for archival operations -#[contracttype] -#[derive(Clone)] -pub enum ArchiveEvent { - GoalsArchived, - GoalRestored, - ArchivesCleaned, -} - const SNAPSHOT_VERSION: u32 = 1; const MAX_AUDIT_ENTRIES: u32 = 100; @@ -170,6 +157,7 @@ impl SavingsGoalContract { current_amount: 0, target_date, locked: true, + unlock_date: None, }; goals.set(next_id, goal); @@ -277,6 +265,7 @@ impl SavingsGoalContract { /// - If caller is not the goal owner /// - If goal is not found /// - If goal is locked + /// - If unlock_date is set and not yet reached /// - If amount is not positive /// - If amount exceeds current balance pub fn withdraw_from_goal(env: Env, caller: Address, goal_id: u32, amount: i128) -> i128 { @@ -318,6 +307,15 @@ impl SavingsGoalContract { panic!("Cannot withdraw from a locked goal"); } + // Check time-lock + if let Some(unlock_date) = goal.unlock_date { + let current_time = env.ledger().timestamp(); + if current_time < unlock_date { + Self::append_audit(&env, symbol_short!("withdraw"), &caller, false); + panic!("Goal is time-locked until unlock date"); + } + } + // Check sufficient balance if amount > goal.current_amount { Self::append_audit(&env, symbol_short!("withdraw"), &caller, false); @@ -580,374 +578,387 @@ impl SavingsGoalContract { out } - /// Archive completed goals that were completed before the specified timestamp. - /// Moves completed goals from active storage to archive storage. - /// - /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Archive goals completed before this timestamp - /// - /// # Returns - /// Number of goals archived - pub fn archive_completed_goals(env: Env, caller: Address, before_timestamp: u64) -> u32 { - caller.require_auth(); - Self::extend_instance_ttl(&env); + fn require_nonce(env: &Env, address: &Address, expected: u64) { + let current = Self::get_nonce(env.clone(), address.clone()); + if expected != current { + panic!("Invalid nonce: expected {}, got {}", current, expected); + } + } - let mut goals: Map = env + fn increment_nonce(env: &Env, address: &Address) { + let current = Self::get_nonce(env.clone(), address.clone()); + let next = current.checked_add(1).expect("nonce overflow"); + let mut nonces: Map = env .storage() .instance() - .get(&symbol_short!("GOALS")) - .unwrap_or_else(|| Map::new(&env)); - - let mut archived: Map = env - .storage() + .get(&symbol_short!("NONCES")) + .unwrap_or_else(|| Map::new(env)); + nonces.set(address.clone(), next); + env.storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) - .unwrap_or_else(|| Map::new(&env)); + .set(&symbol_short!("NONCES"), &nonces); + } - let current_time = env.ledger().timestamp(); - let mut archived_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); - - for (id, goal) in goals.iter() { - // Archive if goal is completed and target_date is before the specified timestamp - if goal.current_amount >= goal.target_amount && goal.target_date < before_timestamp { - let archived_goal = ArchivedGoal { - id: goal.id, - owner: goal.owner.clone(), - name: goal.name.clone(), - target_amount: goal.target_amount, - final_amount: goal.current_amount, - archived_at: current_time, - }; - archived.set(id, archived_goal); - to_remove.push_back(id); - archived_count += 1; + fn compute_goals_checksum(version: u32, next_id: u32, goals: &Vec) -> u64 { + let mut c = version as u64 + next_id as u64; + for i in 0..goals.len() { + if let Some(g) = goals.get(i) { + c = c + .wrapping_add(g.id as u64) + .wrapping_add(g.target_amount as u64) + .wrapping_add(g.current_amount as u64); } } + c.wrapping_mul(31) + } - // Remove archived goals from active storage - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - goals.remove(id); + fn append_audit(env: &Env, operation: Symbol, caller: &Address, success: bool) { + let timestamp = env.ledger().timestamp(); + let mut log: Vec = env + .storage() + .instance() + .get(&symbol_short!("AUDIT")) + .unwrap_or_else(|| Vec::new(env)); + if log.len() >= MAX_AUDIT_ENTRIES { + let mut new_log = Vec::new(env); + for i in 1..log.len() { + if let Some(entry) = log.get(i) { + new_log.push_back(entry); + } } + log = new_log; } + log.push_back(AuditEntry { + operation, + caller: caller.clone(), + timestamp, + success, + }); + env.storage().instance().set(&symbol_short!("AUDIT"), &log); + } + /// Extend the TTL of instance storage + fn extend_instance_ttl(env: &Env) { env.storage() .instance() - .set(&symbol_short!("GOALS"), &goals); - env.storage() - .instance() - .set(&symbol_short!("ARCH_GOAL"), &archived); - - // Extend archive TTL with longer duration - Self::extend_archive_ttl(&env); - - // Update storage stats - Self::update_storage_stats(&env); - - Self::append_audit(&env, symbol_short!("archive"), &caller, true); - env.events().publish( - (symbol_short!("savings"), ArchiveEvent::GoalsArchived), - (archived_count, caller), - ); - - archived_count + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); } - /// Get all archived goals for a specific owner - /// - /// # Arguments - /// * `owner` - Address of the goal owner - /// - /// # Returns - /// Vec of all ArchivedGoal structs belonging to the owner - pub fn get_archived_goals(env: Env, owner: Address) -> Vec { - let archived: Map = env + /// Set time-lock on a goal + pub fn set_time_lock(env: Env, caller: Address, goal_id: u32, unlock_date: u64) -> bool { + caller.require_auth(); + Self::extend_instance_ttl(&env); + + let mut goals: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) + .get(&symbol_short!("GOALS")) .unwrap_or_else(|| Map::new(&env)); - let mut result = Vec::new(&env); - for (_, goal) in archived.iter() { - if goal.owner == owner { - result.push_back(goal); + let mut goal = match goals.get(goal_id) { + Some(g) => g, + None => { + Self::append_audit(&env, symbol_short!("timelock"), &caller, false); + panic!("Goal not found"); } + }; + + if goal.owner != caller { + Self::append_audit(&env, symbol_short!("timelock"), &caller, false); + panic!("Only the goal owner can set time-lock"); } - result - } - /// Get a specific archived goal by ID - /// - /// # Arguments - /// * `goal_id` - ID of the archived goal - /// - /// # Returns - /// ArchivedGoal struct or None if not found - pub fn get_archived_goal(env: Env, goal_id: u32) -> Option { - let archived: Map = env - .storage() + let current_time = env.ledger().timestamp(); + if unlock_date <= current_time { + Self::append_audit(&env, symbol_short!("timelock"), &caller, false); + panic!("Unlock date must be in the future"); + } + + goal.unlock_date = Some(unlock_date); + goals.set(goal_id, goal); + env.storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) - .unwrap_or_else(|| Map::new(&env)); + .set(&symbol_short!("GOALS"), &goals); - archived.get(goal_id) + Self::append_audit(&env, symbol_short!("timelock"), &caller, true); + true } - /// Restore an archived goal back to active storage - /// - /// # Arguments - /// * `caller` - Address of the caller (must be the goal owner) - /// * `goal_id` - ID of the goal to restore - /// - /// # Returns - /// True if restoration was successful - /// - /// # Panics - /// - If caller is not the goal owner - /// - If goal is not found in archive - pub fn restore_goal(env: Env, caller: Address, goal_id: u32) -> bool { - caller.require_auth(); - Self::extend_instance_ttl(&env); + /// Create a schedule for automatic savings deposits + pub fn create_savings_schedule( + env: Env, + owner: Address, + goal_id: u32, + amount: i128, + next_due: u64, + interval: u64, + ) -> u32 { + owner.require_auth(); - let mut archived: Map = env + if amount <= 0 { + panic!("Amount must be positive"); + } + + let goals: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) + .get(&symbol_short!("GOALS")) .unwrap_or_else(|| Map::new(&env)); - let archived_goal = match archived.get(goal_id) { - Some(g) => g, - None => { - Self::append_audit(&env, symbol_short!("restore"), &caller, false); - panic!("Archived goal not found"); - } - }; + let goal = goals.get(goal_id).expect("Goal not found"); - if archived_goal.owner != caller { - Self::append_audit(&env, symbol_short!("restore"), &caller, false); - panic!("Only the goal owner can restore this goal"); + if goal.owner != owner { + panic!("Only the goal owner can create schedules"); } - let mut goals: Map = env + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + + Self::extend_instance_ttl(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("GOALS")) + .get(&symbol_short!("SAV_SCH")) .unwrap_or_else(|| Map::new(&env)); - // Restore as a new active goal - let restored_goal = SavingsGoal { - id: archived_goal.id, - owner: archived_goal.owner.clone(), - name: archived_goal.name.clone(), - target_amount: archived_goal.target_amount, - current_amount: archived_goal.final_amount, - target_date: env.ledger().timestamp() + 31536000, // Set new target 1 year from now - locked: true, - }; + let next_schedule_id = env + .storage() + .instance() + .get(&symbol_short!("NEXT_SSCH")) + .unwrap_or(0u32) + + 1; - goals.set(goal_id, restored_goal); - archived.remove(goal_id); + let schedule = SavingsSchedule { + id: next_schedule_id, + owner: owner.clone(), + goal_id, + amount, + next_due, + interval, + recurring: interval > 0, + active: true, + created_at: current_time, + last_executed: None, + missed_count: 0, + }; + schedules.set(next_schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("GOALS"), &goals); + .set(&symbol_short!("SAV_SCH"), &schedules); env.storage() .instance() - .set(&symbol_short!("ARCH_GOAL"), &archived); - - // Update storage stats - Self::update_storage_stats(&env); + .set(&symbol_short!("NEXT_SSCH"), &next_schedule_id); - Self::append_audit(&env, symbol_short!("restore"), &caller, true); env.events().publish( - (symbol_short!("savings"), ArchiveEvent::GoalRestored), - (goal_id, caller), + (symbol_short!("savings"), SavingsEvent::ScheduleCreated), + (next_schedule_id, owner), ); - true + next_schedule_id } - /// Permanently delete old archives before specified timestamp - /// - /// # Arguments - /// * `caller` - Address of the caller (must authorize) - /// * `before_timestamp` - Delete archives created before this timestamp - /// - /// # Returns - /// Number of archives deleted - pub fn cleanup_old_archives(env: Env, caller: Address, before_timestamp: u64) -> u32 { + /// Modify a savings schedule + pub fn modify_savings_schedule( + env: Env, + caller: Address, + schedule_id: u32, + amount: i128, + next_due: u64, + interval: u64, + ) -> bool { caller.require_auth(); + + if amount <= 0 { + panic!("Amount must be positive"); + } + + let current_time = env.ledger().timestamp(); + if next_due <= current_time { + panic!("Next due date must be in the future"); + } + Self::extend_instance_ttl(&env); - let mut archived: Map = env + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) + .get(&symbol_short!("SAV_SCH")) .unwrap_or_else(|| Map::new(&env)); - let mut deleted_count = 0u32; - let mut to_remove: Vec = Vec::new(&env); + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); - for (id, goal) in archived.iter() { - if goal.archived_at < before_timestamp { - to_remove.push_back(id); - deleted_count += 1; - } + if schedule.owner != caller { + panic!("Only the schedule owner can modify it"); } - for i in 0..to_remove.len() { - if let Some(id) = to_remove.get(i) { - archived.remove(id); - } - } + schedule.amount = amount; + schedule.next_due = next_due; + schedule.interval = interval; + schedule.recurring = interval > 0; + schedules.set(schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("ARCH_GOAL"), &archived); - - // Update storage stats - Self::update_storage_stats(&env); + .set(&symbol_short!("SAV_SCH"), &schedules); - Self::append_audit(&env, symbol_short!("cleanup"), &caller, true); env.events().publish( - (symbol_short!("savings"), ArchiveEvent::ArchivesCleaned), - (deleted_count, caller), + (symbol_short!("savings"), SavingsEvent::ScheduleModified), + (schedule_id, caller), ); - deleted_count + true } - /// Get storage usage statistics - /// - /// # Returns - /// StorageStats struct with current storage metrics - pub fn get_storage_stats(env: Env) -> StorageStats { - env.storage() - .instance() - .get(&symbol_short!("STOR_STAT")) - .unwrap_or(StorageStats { - active_goals: 0, - archived_goals: 0, - total_active_amount: 0, - total_archived_amount: 0, - last_updated: 0, - }) - } + /// Cancel a savings schedule + pub fn cancel_savings_schedule(env: Env, caller: Address, schedule_id: u32) -> bool { + caller.require_auth(); - fn require_nonce(env: &Env, address: &Address, expected: u64) { - let current = Self::get_nonce(env.clone(), address.clone()); - if expected != current { - panic!("Invalid nonce: expected {}, got {}", current, expected); - } - } + Self::extend_instance_ttl(&env); - fn increment_nonce(env: &Env, address: &Address) { - let current = Self::get_nonce(env.clone(), address.clone()); - let next = current.checked_add(1).expect("nonce overflow"); - let mut nonces: Map = env + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("NONCES")) - .unwrap_or_else(|| Map::new(env)); - nonces.set(address.clone(), next); + .get(&symbol_short!("SAV_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let mut schedule = schedules.get(schedule_id).expect("Schedule not found"); + + if schedule.owner != caller { + panic!("Only the schedule owner can cancel it"); + } + + schedule.active = false; + + schedules.set(schedule_id, schedule); env.storage() .instance() - .set(&symbol_short!("NONCES"), &nonces); - } + .set(&symbol_short!("SAV_SCH"), &schedules); - fn compute_goals_checksum(version: u32, next_id: u32, goals: &Vec) -> u64 { - let mut c = version as u64 + next_id as u64; - for i in 0..goals.len() { - if let Some(g) = goals.get(i) { - c = c - .wrapping_add(g.id as u64) - .wrapping_add(g.target_amount as u64) - .wrapping_add(g.current_amount as u64); - } - } - c.wrapping_mul(31) + env.events().publish( + (symbol_short!("savings"), SavingsEvent::ScheduleCancelled), + (schedule_id, caller), + ); + + true } - fn append_audit(env: &Env, operation: Symbol, caller: &Address, success: bool) { - let timestamp = env.ledger().timestamp(); - let mut log: Vec = env + /// Execute due savings schedules (public, callable by anyone - keeper pattern) + pub fn execute_due_savings_schedules(env: Env) -> Vec { + Self::extend_instance_ttl(&env); + + let current_time = env.ledger().timestamp(); + let mut executed = Vec::new(&env); + + let mut schedules: Map = env .storage() .instance() - .get(&symbol_short!("AUDIT")) - .unwrap_or_else(|| Vec::new(env)); - if log.len() >= MAX_AUDIT_ENTRIES { - let mut new_log = Vec::new(env); - for i in 1..log.len() { - if let Some(entry) = log.get(i) { - new_log.push_back(entry); + .get(&symbol_short!("SAV_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + let mut goals: Map = env + .storage() + .instance() + .get(&symbol_short!("GOALS")) + .unwrap_or_else(|| Map::new(&env)); + + for (schedule_id, mut schedule) in schedules.iter() { + if !schedule.active || schedule.next_due > current_time { + continue; + } + + if let Some(mut goal) = goals.get(schedule.goal_id) { + goal.current_amount = goal + .current_amount + .checked_add(schedule.amount) + .expect("overflow"); + + let is_completed = goal.current_amount >= goal.target_amount; + goals.set(schedule.goal_id, goal.clone()); + + env.events().publish( + (symbol_short!("savings"), SavingsEvent::FundsAdded), + (schedule.goal_id, goal.owner.clone(), schedule.amount), + ); + + if is_completed { + env.events().publish( + (symbol_short!("savings"), SavingsEvent::GoalCompleted), + (schedule.goal_id, goal.owner), + ); } } - log = new_log; + + schedule.last_executed = Some(current_time); + + if schedule.recurring && schedule.interval > 0 { + let mut missed = 0u32; + let mut next = schedule.next_due + schedule.interval; + while next <= current_time { + missed += 1; + next += schedule.interval; + } + schedule.missed_count += missed; + schedule.next_due = next; + + if missed > 0 { + env.events().publish( + (symbol_short!("savings"), SavingsEvent::ScheduleMissed), + (schedule_id, missed), + ); + } + } else { + schedule.active = false; + } + + schedules.set(schedule_id, schedule); + executed.push_back(schedule_id); + + env.events().publish( + (symbol_short!("savings"), SavingsEvent::ScheduleExecuted), + schedule_id, + ); } - log.push_back(AuditEntry { - operation, - caller: caller.clone(), - timestamp, - success, - }); - env.storage().instance().set(&symbol_short!("AUDIT"), &log); - } - /// Extend the TTL of instance storage - fn extend_instance_ttl(env: &Env) { env.storage() .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - } - - /// Extend the TTL of archive storage with longer duration - fn extend_archive_ttl(env: &Env) { + .set(&symbol_short!("SAV_SCH"), &schedules); env.storage() .instance() - .extend_ttl(ARCHIVE_LIFETIME_THRESHOLD, ARCHIVE_BUMP_AMOUNT); - } + .set(&symbol_short!("GOALS"), &goals); - /// Update storage statistics - fn update_storage_stats(env: &Env) { - let goals: Map = env - .storage() - .instance() - .get(&symbol_short!("GOALS")) - .unwrap_or_else(|| Map::new(env)); + executed + } - let archived: Map = env + /// Get all savings schedules for an owner + pub fn get_savings_schedules(env: Env, owner: Address) -> Vec { + let schedules: Map = env .storage() .instance() - .get(&symbol_short!("ARCH_GOAL")) - .unwrap_or_else(|| Map::new(env)); - - let mut active_count = 0u32; - let mut active_amount = 0i128; - for (_, goal) in goals.iter() { - active_count += 1; - active_amount = active_amount.saturating_add(goal.current_amount); - } + .get(&symbol_short!("SAV_SCH")) + .unwrap_or_else(|| Map::new(&env)); - let mut archived_count = 0u32; - let mut archived_amount = 0i128; - for (_, goal) in archived.iter() { - archived_count += 1; - archived_amount = archived_amount.saturating_add(goal.final_amount); + let mut result = Vec::new(&env); + for (_, schedule) in schedules.iter() { + if schedule.owner == owner { + result.push_back(schedule); + } } + result + } - let stats = StorageStats { - active_goals: active_count, - archived_goals: archived_count, - total_active_amount: active_amount, - total_archived_amount: archived_amount, - last_updated: env.ledger().timestamp(), - }; - - env.storage() + /// Get a specific savings schedule + pub fn get_savings_schedule(env: Env, schedule_id: u32) -> Option { + let schedules: Map = env + .storage() .instance() - .set(&symbol_short!("STOR_STAT"), &stats); + .get(&symbol_short!("SAV_SCH")) + .unwrap_or_else(|| Map::new(&env)); + + schedules.get(schedule_id) } } diff --git a/savings_goals/src/test.rs b/savings_goals/src/test.rs index 2eb304a..e73f946 100644 --- a/savings_goals/src/test.rs +++ b/savings_goals/src/test.rs @@ -1,5 +1,20 @@ use super::*; -use soroban_sdk::{testutils::Address as _, Address, Env, String}; +use soroban_sdk::{testutils::{Address as AddressTrait, Ledger, LedgerInfo}, Address, Env, String}; + +fn set_time(env: &Env, timestamp: u64) { + let proto = env.ledger().protocol_version(); + + env.ledger().set(LedgerInfo { + protocol_version: proto, + sequence_number: 1, + timestamp, + network_id: [0; 32], + base_reserve: 10, + min_temp_entry_ttl: 1, + min_persistent_entry_ttl: 1, + max_entry_ttl: 100000, + }); +} #[test] fn test_create_goal_unique_ids() { @@ -329,248 +344,267 @@ fn test_exact_goal_completion() { assert_eq!(goal.current_amount, 1000); } -// ============================================ -// Storage Optimization and Archival Tests -// ============================================ - -#[test] -fn test_archive_completed_goals() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - // Create goals with past target dates - let id1 = client.create_goal(&user, &String::from_str(&env, "Goal1"), &1000, &1000000); - let id2 = client.create_goal(&user, &String::from_str(&env, "Goal2"), &500, &1000000); - // Create a goal with future target date - let id3 = client.create_goal(&user, &String::from_str(&env, "Goal3"), &2000, &3000000000); - - // Complete goals 1 and 2 - client.add_to_goal(&user, &id1, &1000); - client.add_to_goal(&user, &id2, &500); - client.add_to_goal(&user, &id3, &1000); // Only partially funded - - // Archive completed goals with target date before timestamp 2000000 - let archived_count = client.archive_completed_goals(&user, &2000000); - assert_eq!(archived_count, 2); - - // Verify active goals only has the incomplete one - let active = client.get_all_goals(&user); - assert_eq!(active.len(), 1); - assert_eq!(active.get(0).unwrap().id, id3); - - // Verify archived goals - let archived = client.get_archived_goals(&user); - assert_eq!(archived.len(), 2); -} - -#[test] -fn test_archive_empty_when_no_completed_goals() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - // Create incomplete goals - client.create_goal(&user, &String::from_str(&env, "Goal1"), &1000, &1000000); - client.create_goal(&user, &String::from_str(&env, "Goal2"), &500, &1000000); - - // Try to archive - should archive nothing - let archived_count = client.archive_completed_goals(&user, &2000000); - assert_eq!(archived_count, 0); - - // Verify all goals still active - let active = client.get_all_goals(&user); - assert_eq!(active.len(), 2); - - let archived = client.get_archived_goals(&user); - assert_eq!(archived.len(), 0); -} - -#[test] -fn test_get_archived_goal() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - let id = client.create_goal(&user, &String::from_str(&env, "Archive"), &1000, &1000000); - client.add_to_goal(&user, &id, &1000); - - client.archive_completed_goals(&user, &2000000); - - // Get specific archived goal - let archived_goal = client.get_archived_goal(&id); - assert!(archived_goal.is_some()); - let goal = archived_goal.unwrap(); - assert_eq!(goal.id, id); - assert_eq!(goal.final_amount, 1000); -} - -#[test] -fn test_restore_goal() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - let id = client.create_goal(&user, &String::from_str(&env, "Restore"), &1000, &1000000); - client.add_to_goal(&user, &id, &1500); - - // Archive the goal - client.archive_completed_goals(&user, &2000000); - assert!(client.get_goal(&id).is_none()); - assert!(client.get_archived_goal(&id).is_some()); - - // Restore the goal - let restored = client.restore_goal(&user, &id); - assert!(restored); - - // Verify goal is back in active storage - let goal = client.get_goal(&id); - assert!(goal.is_some()); - let goal = goal.unwrap(); - assert_eq!(goal.current_amount, 1500); - - // Verify goal is no longer in archive - assert!(client.get_archived_goal(&id).is_none()); -} - -#[test] -#[should_panic(expected = "Archived goal not found")] -fn test_restore_nonexistent_goal() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - client.restore_goal(&user, &999); -} - -#[test] -#[should_panic(expected = "Only the goal owner can restore this goal")] -fn test_restore_unauthorized() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - let other = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - let id = client.create_goal(&user, &String::from_str(&env, "Auth"), &1000, &1000000); - client.add_to_goal(&user, &id, &1000); - client.archive_completed_goals(&user, &2000000); - - // Try to restore as different user - client.restore_goal(&other, &id); -} - -#[test] -fn test_cleanup_old_archives() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - // Create and complete multiple goals - let id1 = client.create_goal(&user, &String::from_str(&env, "Old1"), &100, &1000); - let id2 = client.create_goal(&user, &String::from_str(&env, "Old2"), &200, &1000); - client.add_to_goal(&user, &id1, &100); - client.add_to_goal(&user, &id2, &200); - - // Archive all - client.archive_completed_goals(&user, &2000); - - // Verify 2 archived - assert_eq!(client.get_archived_goals(&user).len(), 2); - - // Cleanup archives older than far future timestamp (should delete all since archived_at is current time which is 0 in test) - let deleted = client.cleanup_old_archives(&user, &1000000); - assert_eq!(deleted, 2); - - // Verify archives are gone - assert_eq!(client.get_archived_goals(&user).len(), 0); -} - -#[test] -fn test_storage_stats() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - // Initial stats - let stats = client.get_storage_stats(); - assert_eq!(stats.active_goals, 0); - assert_eq!(stats.archived_goals, 0); - - // Create goals and add funds - let id1 = client.create_goal(&user, &String::from_str(&env, "G1"), &1000, &1000); - let id2 = client.create_goal(&user, &String::from_str(&env, "G2"), &500, &1000); - client.add_to_goal(&user, &id1, &1000); - client.add_to_goal(&user, &id2, &500); - - // Archive one - client.archive_completed_goals(&user, &2000); - - // Check updated stats - let stats = client.get_storage_stats(); - assert_eq!(stats.active_goals, 0); - assert_eq!(stats.archived_goals, 2); - assert_eq!(stats.total_archived_amount, 1500); -} - -#[test] -fn test_archive_preserves_owner_separation() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user1 = Address::generate(&env); - let user2 = Address::generate(&env); - - client.init(); - env.mock_all_auths(); - - // Create goals for different users - let id1 = client.create_goal(&user1, &String::from_str(&env, "U1G1"), &1000, &1000); - let id2 = client.create_goal(&user2, &String::from_str(&env, "U2G1"), &500, &1000); - client.add_to_goal(&user1, &id1, &1000); - client.add_to_goal(&user2, &id2, &500); - - // Archive all - client.archive_completed_goals(&user1, &2000); - - // User1 should only see their archived goals - let user1_archived = client.get_archived_goals(&user1); - assert_eq!(user1_archived.len(), 1); - assert_eq!(user1_archived.get(0).unwrap().owner, user1); - - // User2 should only see their archived goals - let user2_archived = client.get_archived_goals(&user2); - assert_eq!(user2_archived.len(), 1); - assert_eq!(user2_archived.get(0).unwrap().owner, user2); -} + #[test] + fn test_set_time_lock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + client.set_time_lock(&owner, &goal_id, &10000); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.unlock_date, Some(10000)); + } + + #[test] + fn test_withdraw_time_locked_goal_before_unlock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + client.add_to_goal(&owner, &goal_id, &5000); + client.unlock_goal(&owner, &goal_id); + client.set_time_lock(&owner, &goal_id, &10000); + + let result = client.try_withdraw_from_goal(&owner, &goal_id, &1000); + assert!(result.is_err()); + } + + #[test] + fn test_withdraw_time_locked_goal_after_unlock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + client.add_to_goal(&owner, &goal_id, &5000); + client.unlock_goal(&owner, &goal_id); + client.set_time_lock(&owner, &goal_id, &3000); + + set_time(&env, 3500); + let new_amount = client.withdraw_from_goal(&owner, &goal_id, &1000); + assert_eq!(new_amount, 4000); + } + + #[test] + fn test_create_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + assert_eq!(schedule_id, 1); + + let schedule = client.get_savings_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.amount, 500); + assert_eq!(schedule.next_due, 3000); + assert!(schedule.active); + } + + #[test] + fn test_modify_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + client.modify_savings_schedule(&owner, &schedule_id, &1000, &4000, &172800); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.amount, 1000); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 172800); + } + + #[test] + fn test_cancel_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + client.cancel_savings_schedule(&owner, &schedule_id); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); + } + + #[test] + fn test_execute_due_savings_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &0); + + set_time(&env, 3500); + let executed = client.execute_due_savings_schedules(); + + assert_eq!(executed.len(), 1); + assert_eq!(executed.get(0).unwrap(), schedule_id); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 500); + } + + #[test] + fn test_execute_recurring_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + + set_time(&env, 3500); + client.execute_due_savings_schedules(); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert!(schedule.active); + assert_eq!(schedule.next_due, 3000 + 86400); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 500); + } + + #[test] + fn test_execute_missed_savings_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &10000, + &5000, + ); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + + set_time(&env, 3000 + 86400 * 3 + 100); + client.execute_due_savings_schedules(); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.missed_count, 3); + assert!(schedule.next_due > 3000 + 86400 * 3); + } + + #[test] + fn test_savings_schedule_goal_completion() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal( + &owner, + &String::from_str(&env, "Education"), + &1000, + &5000, + ); + + client.create_savings_schedule(&owner, &goal_id, &1000, &3000, &0); + + set_time(&env, 3500); + client.execute_due_savings_schedules(); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 1000); + assert!(client.is_goal_completed(&goal_id)); + } diff --git a/savings_goals/test_snapshots/test/test_add_to_goal_increments.1.json b/savings_goals/test_snapshots/test/test_add_to_goal_increments.1.json index 2d87b4c..35d07f1 100644 --- a/savings_goals/test_snapshots/test/test_add_to_goal_increments.1.json +++ b/savings_goals/test_snapshots/test/test_add_to_goal_increments.1.json @@ -314,6 +314,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_cancel_savings_schedule.1.json b/savings_goals/test_snapshots/test/test_cancel_savings_schedule.1.json new file mode 100644 index 0000000..6c5a6f5 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_cancel_savings_schedule.1.json @@ -0,0 +1,947 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "cancel_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "cancel_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCancelled" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "cancel_savings_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_create_goal_unique_ids.1.json b/savings_goals/test_snapshots/test/test_create_goal_unique_ids.1.json index 40c91d4..9d22084 100644 --- a/savings_goals/test_snapshots/test/test_create_goal_unique_ids.1.json +++ b/savings_goals/test_snapshots/test/test_create_goal_unique_ids.1.json @@ -317,6 +317,12 @@ "val": { "u64": 1735689600 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -388,6 +394,12 @@ "val": { "u64": 1735689600 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_create_savings_schedule.1.json b/savings_goals/test_snapshots/test/test_create_savings_schedule.1.json new file mode 100644 index 0000000..8dd9d37 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_create_savings_schedule.1.json @@ -0,0 +1,802 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_edge_cases_large_amounts.1.json b/savings_goals/test_snapshots/test/test_edge_cases_large_amounts.1.json index 5ba86d6..413ceb0 100644 --- a/savings_goals/test_snapshots/test/test_edge_cases_large_amounts.1.json +++ b/savings_goals/test_snapshots/test/test_edge_cases_large_amounts.1.json @@ -315,6 +315,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -783,6 +789,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_exact_goal_completion.1.json b/savings_goals/test_snapshots/test/test_exact_goal_completion.1.json index 6a7cacd..bdef01a 100644 --- a/savings_goals/test_snapshots/test/test_exact_goal_completion.1.json +++ b/savings_goals/test_snapshots/test/test_exact_goal_completion.1.json @@ -381,6 +381,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1119,6 +1125,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_execute_due_savings_schedules.1.json b/savings_goals/test_snapshots/test/test_execute_due_savings_schedules.1.json new file mode 100644 index 0000000..bae44c8 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_execute_due_savings_schedules.1.json @@ -0,0 +1,902 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_execute_missed_savings_schedules.1.json b/savings_goals/test_snapshots/test/test_execute_missed_savings_schedules.1.json new file mode 100644 index 0000000..a0d7f0f --- /dev/null +++ b/savings_goals/test_snapshots/test/test_execute_missed_savings_schedules.1.json @@ -0,0 +1,959 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 262300, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 348600 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleMissed" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 3 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 262300 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 348600 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_execute_recurring_savings_schedule.1.json b/savings_goals/test_snapshots/test/test_execute_recurring_savings_schedule.1.json new file mode 100644 index 0000000..cf5e70c --- /dev/null +++ b/savings_goals/test_snapshots/test/test_execute_recurring_savings_schedule.1.json @@ -0,0 +1,1044 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 89400 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 89400 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_full_withdrawal.1.json b/savings_goals/test_snapshots/test/test_full_withdrawal.1.json index ae92b8a..2b558a5 100644 --- a/savings_goals/test_snapshots/test/test_full_withdrawal.1.json +++ b/savings_goals/test_snapshots/test/test_full_withdrawal.1.json @@ -438,6 +438,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1167,6 +1173,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_get_all_goals.1.json b/savings_goals/test_snapshots/test/test_get_all_goals.1.json index 0bcadb7..b0e469b 100644 --- a/savings_goals/test_snapshots/test/test_get_all_goals.1.json +++ b/savings_goals/test_snapshots/test/test_get_all_goals.1.json @@ -318,6 +318,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -389,6 +395,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -853,6 +865,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] }, @@ -919,6 +937,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_get_goal_retrieval.1.json b/savings_goals/test_snapshots/test/test_get_goal_retrieval.1.json index 562a3d3..e3aa96b 100644 --- a/savings_goals/test_snapshots/test/test_get_goal_retrieval.1.json +++ b/savings_goals/test_snapshots/test/test_get_goal_retrieval.1.json @@ -251,6 +251,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -581,6 +587,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_is_goal_completed.1.json b/savings_goals/test_snapshots/test/test_is_goal_completed.1.json index 822cc8f..37f9490 100644 --- a/savings_goals/test_snapshots/test/test_is_goal_completed.1.json +++ b/savings_goals/test_snapshots/test/test_is_goal_completed.1.json @@ -382,6 +382,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -966,6 +972,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_lock_unlock_goal.1.json b/savings_goals/test_snapshots/test/test_lock_unlock_goal.1.json index 0a9c621..012fce0 100644 --- a/savings_goals/test_snapshots/test/test_lock_unlock_goal.1.json +++ b/savings_goals/test_snapshots/test/test_lock_unlock_goal.1.json @@ -369,6 +369,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -765,6 +771,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -967,6 +979,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1169,6 +1187,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_modify_savings_schedule.1.json b/savings_goals/test_snapshots/test/test_modify_savings_schedule.1.json new file mode 100644 index 0000000..b9c3f06 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_modify_savings_schedule.1.json @@ -0,0 +1,971 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "modify_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "u64": 3000 + }, + { + "u64": 86400 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "modify_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 4000 + }, + { + "u64": 172800 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleModified" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "modify_savings_schedule" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_savings_schedule" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 172800 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": "void" + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 4000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_multiple_goals_management.1.json b/savings_goals/test_snapshots/test/test_multiple_goals_management.1.json index c21e9d0..01a5336 100644 --- a/savings_goals/test_snapshots/test/test_multiple_goals_management.1.json +++ b/savings_goals/test_snapshots/test/test_multiple_goals_management.1.json @@ -447,6 +447,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -518,6 +524,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1256,6 +1268,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1368,6 +1386,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_savings_schedule_goal_completion.1.json b/savings_goals/test_snapshots/test/test_savings_schedule_goal_completion.1.json new file mode 100644 index 0000000..b87a4db --- /dev/null +++ b/savings_goals/test_snapshots/test/test_savings_schedule_goal_completion.1.json @@ -0,0 +1,986 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_savings_schedule", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "NEXT_SSCH" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "SAV_SCH" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "goal_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "last_executed" + }, + "val": { + "u64": 3500 + } + }, + { + "key": { + "symbol": "missed_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "next_due" + }, + "val": { + "u64": 3000 + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "recurring" + }, + "val": { + "bool": false + } + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "u64": 3000 + }, + { + "u64": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_savings_schedule" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCompleted" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "ScheduleExecuted" + } + ] + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "execute_due_savings_schedules" + } + ], + "data": { + "vec": [ + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "is_goal_completed" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "is_goal_completed" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_set_time_lock.1.json b/savings_goals/test_snapshots/test/test_set_time_lock.1.json new file mode 100644 index 0000000..7b98da0 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_set_time_lock.1.json @@ -0,0 +1,654 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_time_lock", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 10000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "timelock" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": { + "u64": 10000 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 10000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_goal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": { + "u64": 10000 + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_withdraw_from_goal.1.json b/savings_goals/test_snapshots/test/test_withdraw_from_goal.1.json index 226169e..829c2d6 100644 --- a/savings_goals/test_snapshots/test/test_withdraw_from_goal.1.json +++ b/savings_goals/test_snapshots/test/test_withdraw_from_goal.1.json @@ -437,6 +437,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -1166,6 +1172,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } diff --git a/savings_goals/test_snapshots/test/test_withdraw_locked.1.json b/savings_goals/test_snapshots/test/test_withdraw_locked.1.json index ad85458..382f52b 100644 --- a/savings_goals/test_snapshots/test/test_withdraw_locked.1.json +++ b/savings_goals/test_snapshots/test/test_withdraw_locked.1.json @@ -315,6 +315,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -733,7 +739,7 @@ "data": { "vec": [ { - "string": "caught panic 'Cannot withdraw from a locked goal' from contract function 'Symbol(obj#103)'" + "string": "caught panic 'Cannot withdraw from a locked goal' from contract function 'Symbol(obj#109)'" }, { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" diff --git a/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_after_unlock.1.json b/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_after_unlock.1.json new file mode 100644 index 0000000..1982916 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_after_unlock.1.json @@ -0,0 +1,1118 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "add_to_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "unlock_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_time_lock", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "withdraw_from_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 3500, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "add" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "unlock" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "timelock" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "withdraw" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 3500 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 4000 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": { + "u64": 3000 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "add_to_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "add_to_goal" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 5000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "unlock_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalUnlocked" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "unlock_goal" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 3000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "withdraw_from_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsWithdrawn" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "withdraw_from_goal" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 4000 + } + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_before_unlock.1.json b/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_before_unlock.1.json new file mode 100644 index 0000000..e328356 --- /dev/null +++ b/savings_goals/test_snapshots/test/test_withdraw_time_locked_goal_before_unlock.1.json @@ -0,0 +1,1065 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "add_to_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "unlock_goal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_time_lock", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 10000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 1, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 1, + "min_temp_entry_ttl": 1, + "max_entry_ttl": 100000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "AUDIT" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "create" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "add" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "unlock" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "caller" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "operation" + }, + "val": { + "symbol": "timelock" + } + }, + { + "key": { + "symbol": "success" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "timestamp" + }, + "val": { + "u64": 1000 + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "GOALS" + }, + "val": { + "map": [ + { + "key": { + "u32": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "current_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 5000 + } + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Education" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "target_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "target_date" + }, + "val": { + "u64": 5000 + } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": { + "u64": 10000 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "NEXT_ID" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 100000 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 100000 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "Education" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + }, + { + "u64": 5000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalCreated" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_goal" + } + ], + "data": { + "u32": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "add_to_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "FundsAdded" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 5000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "add_to_goal" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 5000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "unlock_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "savings" + }, + { + "vec": [ + { + "symbol": "GoalUnlocked" + } + ] + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "unlock_goal" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "u64": 10000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "set_time_lock" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "withdraw_from_goal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "log" + } + ], + "data": { + "vec": [ + { + "string": "caught panic 'Goal is time-locked until unlock date' from contract function 'Symbol(obj#217)'" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "string": "caught error from function" + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "wasm_vm": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "contract try_call failed" + }, + { + "symbol": "withdraw_from_goal" + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 1 + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/savings_goals/test_snapshots/test/test_withdraw_too_much.1.json b/savings_goals/test_snapshots/test/test_withdraw_too_much.1.json index 19f48ed..207bd95 100644 --- a/savings_goals/test_snapshots/test/test_withdraw_too_much.1.json +++ b/savings_goals/test_snapshots/test/test_withdraw_too_much.1.json @@ -373,6 +373,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -914,7 +920,7 @@ "data": { "vec": [ { - "string": "caught panic 'Insufficient balance' from contract function 'Symbol(obj#159)'" + "string": "caught panic 'Insufficient balance' from contract function 'Symbol(obj#169)'" }, { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" diff --git a/savings_goals/test_snapshots/test/test_withdraw_unauthorized.1.json b/savings_goals/test_snapshots/test/test_withdraw_unauthorized.1.json index 9721576..9f26d23 100644 --- a/savings_goals/test_snapshots/test/test_withdraw_unauthorized.1.json +++ b/savings_goals/test_snapshots/test/test_withdraw_unauthorized.1.json @@ -373,6 +373,12 @@ "val": { "u64": 2000000000 } + }, + { + "key": { + "symbol": "unlock_date" + }, + "val": "void" } ] } @@ -914,7 +920,7 @@ "data": { "vec": [ { - "string": "caught panic 'Only the goal owner can withdraw funds' from contract function 'Symbol(obj#161)'" + "string": "caught panic 'Only the goal owner can withdraw funds' from contract function 'Symbol(obj#171)'" }, { "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" From ccf4c9ff8009797703569f7398aafca4c4279a74 Mon Sep 17 00:00:00 2001 From: Georgechisom Date: Sat, 31 Jan 2026 12:23:26 +0100 Subject: [PATCH 2/2] chore: apply cargo fmt --- bill_payments/src/lib.rs | 3 +- insurance/src/test.rs | 392 +++++++++++----------- remittance_split/src/test.rs | 223 ++++++------- remittance_split/tests/gas_bench.rs | 8 +- reporting/src/lib.rs | 37 +-- reporting/src/tests.rs | 47 +-- savings_goals/src/test.rs | 483 +++++++++++++--------------- 7 files changed, 570 insertions(+), 623 deletions(-) diff --git a/bill_payments/src/lib.rs b/bill_payments/src/lib.rs index c9cf55f..2fb6472 100644 --- a/bill_payments/src/lib.rs +++ b/bill_payments/src/lib.rs @@ -554,7 +554,8 @@ impl BillPayments { bill.paid_at = Some(current_time); if bill.recurring { - let next_due_date = bill.due_date + (bill.frequency_days as u64 * 86400); + let next_due_date = + bill.due_date + (bill.frequency_days as u64 * 86400); let next_id = env .storage() .instance() diff --git a/insurance/src/test.rs b/insurance/src/test.rs index 3aa1252..dc25e0a 100644 --- a/insurance/src/test.rs +++ b/insurance/src/test.rs @@ -286,199 +286,199 @@ fn test_multiple_premium_payments() { #[test] fn test_create_premium_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - assert_eq!(schedule_id, 1); - - let schedule = client.get_premium_schedule(&schedule_id); - assert!(schedule.is_some()); - let schedule = schedule.unwrap(); - assert_eq!(schedule.next_due, 3000); - assert_eq!(schedule.interval, 2592000); - assert!(schedule.active); - } - - #[test] - fn test_modify_premium_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - client.modify_premium_schedule(&owner, &schedule_id, &4000, &2678400); - - let schedule = client.get_premium_schedule(&schedule_id).unwrap(); - assert_eq!(schedule.next_due, 4000); - assert_eq!(schedule.interval, 2678400); - } - - #[test] - fn test_cancel_premium_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - client.cancel_premium_schedule(&owner, &schedule_id); - - let schedule = client.get_premium_schedule(&schedule_id).unwrap(); - assert!(!schedule.active); - } - - #[test] - fn test_execute_due_premium_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &0); - - set_time(&env, 3500); - let executed = client.execute_due_premium_schedules(); - - assert_eq!(executed.len(), 1); - assert_eq!(executed.get(0).unwrap(), schedule_id); - - let policy = client.get_policy(&policy_id).unwrap(); - assert_eq!(policy.next_payment_date, 3500 + 30 * 86400); - } - - #[test] - fn test_execute_recurring_premium_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - - set_time(&env, 3500); - client.execute_due_premium_schedules(); - - let schedule = client.get_premium_schedule(&schedule_id).unwrap(); - assert!(schedule.active); - assert_eq!(schedule.next_due, 3000 + 2592000); - } - - #[test] - fn test_execute_missed_premium_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - - set_time(&env, 3000 + 2592000 * 3 + 100); - client.execute_due_premium_schedules(); - - let schedule = client.get_premium_schedule(&schedule_id).unwrap(); - assert_eq!(schedule.missed_count, 3); - assert!(schedule.next_due > 3000 + 2592000 * 3); - } - - #[test] - fn test_get_premium_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let policy_id1 = client.create_policy( - &owner, - &String::from_str(&env, "Health Insurance"), - &String::from_str(&env, "health"), - &500, - &50000, - ); - - let policy_id2 = client.create_policy( - &owner, - &String::from_str(&env, "Life Insurance"), - &String::from_str(&env, "life"), - &300, - &100000, - ); - - client.create_premium_schedule(&owner, &policy_id1, &3000, &2592000); - client.create_premium_schedule(&owner, &policy_id2, &4000, &2592000); - - let schedules = client.get_premium_schedules(&owner); - assert_eq!(schedules.len(), 2); - } + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + assert_eq!(schedule_id, 1); + + let schedule = client.get_premium_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.next_due, 3000); + assert_eq!(schedule.interval, 2592000); + assert!(schedule.active); +} + +#[test] +fn test_modify_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + client.modify_premium_schedule(&owner, &schedule_id, &4000, &2678400); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 2678400); +} + +#[test] +fn test_cancel_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + client.cancel_premium_schedule(&owner, &schedule_id); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); +} + +#[test] +fn test_execute_due_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &0); + + set_time(&env, 3500); + let executed = client.execute_due_premium_schedules(); + + assert_eq!(executed.len(), 1); + assert_eq!(executed.get(0).unwrap(), schedule_id); + + let policy = client.get_policy(&policy_id).unwrap(); + assert_eq!(policy.next_payment_date, 3500 + 30 * 86400); +} + +#[test] +fn test_execute_recurring_premium_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + + set_time(&env, 3500); + client.execute_due_premium_schedules(); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert!(schedule.active); + assert_eq!(schedule.next_due, 3000 + 2592000); +} + +#[test] +fn test_execute_missed_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); + + set_time(&env, 3000 + 2592000 * 3 + 100); + client.execute_due_premium_schedules(); + + let schedule = client.get_premium_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.missed_count, 3); + assert!(schedule.next_due > 3000 + 2592000 * 3); +} + +#[test] +fn test_get_premium_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, Insurance); + let client = InsuranceClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let policy_id1 = client.create_policy( + &owner, + &String::from_str(&env, "Health Insurance"), + &String::from_str(&env, "health"), + &500, + &50000, + ); + + let policy_id2 = client.create_policy( + &owner, + &String::from_str(&env, "Life Insurance"), + &String::from_str(&env, "life"), + &300, + &100000, + ); + + client.create_premium_schedule(&owner, &policy_id1, &3000, &2592000); + client.create_premium_schedule(&owner, &policy_id2, &4000, &2592000); + + let schedules = client.get_premium_schedules(&owner); + assert_eq!(schedules.len(), 2); +} diff --git a/remittance_split/src/test.rs b/remittance_split/src/test.rs index 0237a32..5ebd283 100644 --- a/remittance_split/src/test.rs +++ b/remittance_split/src/test.rs @@ -1,7 +1,10 @@ #![cfg(test)] use super::*; -use soroban_sdk::{testutils::{Address as AddressTrait, Ledger, LedgerInfo}, Address, Env}; +use soroban_sdk::{ + testutils::{Address as AddressTrait, Ledger, LedgerInfo}, + Address, Env, +}; fn set_time(env: &Env, timestamp: u64) { let proto = env.ledger().protocol_version(); @@ -213,115 +216,115 @@ fn test_calculate_complex_rounding() { #[test] fn test_create_remittance_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - client.initialize_split(&owner, &0, &50, &30, &15, &5); + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); - let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); - assert_eq!(schedule_id, 1); - - let schedule = client.get_remittance_schedule(&schedule_id); - assert!(schedule.is_some()); - let schedule = schedule.unwrap(); - assert_eq!(schedule.amount, 10000); - assert_eq!(schedule.next_due, 3000); - assert_eq!(schedule.interval, 86400); - assert!(schedule.active); - } - - #[test] - fn test_modify_remittance_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - client.initialize_split(&owner, &0, &50, &30, &15, &5); - - let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); - client.modify_remittance_schedule(&owner, &schedule_id, &15000, &4000, &172800); - - let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); - assert_eq!(schedule.amount, 15000); - assert_eq!(schedule.next_due, 4000); - assert_eq!(schedule.interval, 172800); - } - - #[test] - fn test_cancel_remittance_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - client.initialize_split(&owner, &0, &50, &30, &15, &5); - - let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); - client.cancel_remittance_schedule(&owner, &schedule_id); - - let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); - assert!(!schedule.active); - } - - #[test] - fn test_get_remittance_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - client.initialize_split(&owner, &0, &50, &30, &15, &5); - - client.create_remittance_schedule(&owner, &10000, &3000, &86400); - client.create_remittance_schedule(&owner, &5000, &4000, &172800); - - let schedules = client.get_remittance_schedules(&owner); - assert_eq!(schedules.len(), 2); - } - - #[test] - fn test_remittance_schedule_validation() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 5000); - - client.initialize_split(&owner, &0, &50, &30, &15, &5); - - let result = client.try_create_remittance_schedule(&owner, &10000, &3000, &86400); - assert!(result.is_err()); - } - - #[test] - fn test_remittance_schedule_zero_amount() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + assert_eq!(schedule_id, 1); + + let schedule = client.get_remittance_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.amount, 10000); + assert_eq!(schedule.next_due, 3000); + assert_eq!(schedule.interval, 86400); + assert!(schedule.active); +} - env.mock_all_auths(); - set_time(&env, 1000); +#[test] +fn test_modify_remittance_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); - client.initialize_split(&owner, &0, &50, &30, &15, &5); - - let result = client.try_create_remittance_schedule(&owner, &0, &3000, &86400); - assert!(result.is_err()); - } + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.modify_remittance_schedule(&owner, &schedule_id, &15000, &4000, &172800); + + let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.amount, 15000); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 172800); +} + +#[test] +fn test_cancel_remittance_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let schedule_id = client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.cancel_remittance_schedule(&owner, &schedule_id); + + let schedule = client.get_remittance_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); +} + +#[test] +fn test_get_remittance_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + client.create_remittance_schedule(&owner, &10000, &3000, &86400); + client.create_remittance_schedule(&owner, &5000, &4000, &172800); + + let schedules = client.get_remittance_schedules(&owner); + assert_eq!(schedules.len(), 2); +} + +#[test] +fn test_remittance_schedule_validation() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 5000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let result = client.try_create_remittance_schedule(&owner, &10000, &3000, &86400); + assert!(result.is_err()); +} + +#[test] +fn test_remittance_schedule_zero_amount() { + let env = Env::default(); + let contract_id = env.register_contract(None, RemittanceSplit); + let client = RemittanceSplitClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + client.initialize_split(&owner, &0, &50, &30, &15, &5); + + let result = client.try_create_remittance_schedule(&owner, &0, &3000, &86400); + assert!(result.is_err()); +} diff --git a/remittance_split/tests/gas_bench.rs b/remittance_split/tests/gas_bench.rs index 22184ed..580bc1a 100644 --- a/remittance_split/tests/gas_bench.rs +++ b/remittance_split/tests/gas_bench.rs @@ -59,7 +59,13 @@ fn bench_distribute_usdc_worst_case() { let nonce = 0u64; let (cpu, mem, distributed) = measure(&env, || { - client.distribute_usdc(&token_contract.address(), &payer, &nonce, &accounts, &amount) + client.distribute_usdc( + &token_contract.address(), + &payer, + &nonce, + &accounts, + &amount, + ) }); assert!(distributed); diff --git a/reporting/src/lib.rs b/reporting/src/lib.rs index 6403ed1..795eacd 100644 --- a/reporting/src/lib.rs +++ b/reporting/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] use soroban_sdk::{ - contract, contractclient, contractimpl, contracttype, symbol_short, Address, Env, Map, - Vec, + contract, contractclient, contractimpl, contracttype, symbol_short, Address, Env, Map, Vec, }; // Storage TTL constants for active data @@ -254,7 +253,9 @@ impl ReportingContract { } Self::extend_instance_ttl(&env); - env.storage().instance().set(&symbol_short!("ADMIN"), &admin); + env.storage() + .instance() + .set(&symbol_short!("ADMIN"), &admin); true } @@ -506,11 +507,7 @@ impl ReportingContract { } /// Calculate financial health score - pub fn calculate_health_score( - env: Env, - user: Address, - _total_remittance: i128, - ) -> HealthScore { + pub fn calculate_health_score(env: Env, user: Address, _total_remittance: i128) -> HealthScore { let addresses: ContractAddresses = env .storage() .instance() @@ -557,11 +554,7 @@ impl ReportingContract { // Insurance score (0-20 points) let insurance_client = InsuranceClient::new(&env, &addresses.insurance); let policies = insurance_client.get_active_policies(&user); - let insurance_score = if !policies.is_empty() { - 20 - } else { - 0 - }; + let insurance_score = if !policies.is_empty() { 20 } else { 0 }; let total_score = savings_score + bills_score + insurance_score; @@ -581,13 +574,21 @@ impl ReportingContract { period_start: u64, period_end: u64, ) -> FinancialHealthReport { - let health_score = Self::calculate_health_score(env.clone(), user.clone(), total_remittance); - let remittance_summary = - Self::get_remittance_summary(env.clone(), user.clone(), total_remittance, period_start, period_end); - let savings_report = Self::get_savings_report(env.clone(), user.clone(), period_start, period_end); + let health_score = + Self::calculate_health_score(env.clone(), user.clone(), total_remittance); + let remittance_summary = Self::get_remittance_summary( + env.clone(), + user.clone(), + total_remittance, + period_start, + period_end, + ); + let savings_report = + Self::get_savings_report(env.clone(), user.clone(), period_start, period_end); let bill_compliance = Self::get_bill_compliance_report(env.clone(), user.clone(), period_start, period_end); - let insurance_report = Self::get_insurance_report(env.clone(), user, period_start, period_end); + let insurance_report = + Self::get_insurance_report(env.clone(), user, period_start, period_end); let generated_at = env.ledger().timestamp(); diff --git a/reporting/src/tests.rs b/reporting/src/tests.rs index 6b99a99..823c763 100644 --- a/reporting/src/tests.rs +++ b/reporting/src/tests.rs @@ -74,7 +74,9 @@ mod savings_goals { mod bill_payments { use crate::{Bill, BillPaymentsTrait}; - use soroban_sdk::{contract, contractimpl, testutils::Address as _, Address, Env, String as SorobanString, Vec}; + use soroban_sdk::{ + contract, contractimpl, testutils::Address as _, Address, Env, String as SorobanString, Vec, + }; #[contract] pub struct BillPayments; @@ -489,12 +491,8 @@ fn test_get_financial_health_report() { let period_start = 1704067200u64; let period_end = 1706745600u64; - let report = client.get_financial_health_report( - &user, - &total_remittance, - &period_start, - &period_end, - ); + let report = + client.get_financial_health_report(&user, &total_remittance, &period_start, &period_end); assert_eq!(report.health_score.score, 87); assert_eq!(report.remittance_summary.total_received, 10000); @@ -568,12 +566,8 @@ fn test_store_and_retrieve_report() { let period_start = 1704067200u64; let period_end = 1706745600u64; - let report = client.get_financial_health_report( - &user, - &total_remittance, - &period_start, - &period_end, - ); + let report = + client.get_financial_health_report(&user, &total_remittance, &period_start, &period_end); let period_key = 202401u64; // January 2024 @@ -583,7 +577,10 @@ fn test_store_and_retrieve_report() { let retrieved = client.get_stored_report(&user, &period_key); assert!(retrieved.is_some()); let retrieved_report = retrieved.unwrap(); - assert_eq!(retrieved_report.health_score.score, report.health_score.score); + assert_eq!( + retrieved_report.health_score.score, + report.health_score.score + ); assert_eq!( retrieved_report.remittance_summary.total_received, report.remittance_summary.total_received @@ -686,12 +683,8 @@ fn test_archive_old_reports() { let period_start = 1704067200u64; let period_end = 1706745600u64; - let report = client.get_financial_health_report( - &user, - &total_remittance, - &period_start, - &period_end, - ); + let report = + client.get_financial_health_report(&user, &total_remittance, &period_start, &period_end); let period_key = 202401u64; client.store_report(&user, &report, &period_key); @@ -751,12 +744,7 @@ fn test_cleanup_old_reports() { ); // Generate and store a report - let report = client.get_financial_health_report( - &user, - &10000, - &1704067200, - &1706745600, - ); + let report = client.get_financial_health_report(&user, &10000, &1704067200, &1706745600); client.store_report(&user, &report, &202401); // Archive the report @@ -802,12 +790,7 @@ fn test_storage_stats() { assert_eq!(stats.archived_reports, 0); // Store a report - let report = client.get_financial_health_report( - &user, - &10000, - &1704067200, - &1706745600, - ); + let report = client.get_financial_health_report(&user, &10000, &1704067200, &1706745600); client.store_report(&user, &report, &202401); // Archive and check stats diff --git a/savings_goals/src/test.rs b/savings_goals/src/test.rs index e73f946..4abd6af 100644 --- a/savings_goals/src/test.rs +++ b/savings_goals/src/test.rs @@ -1,5 +1,8 @@ use super::*; -use soroban_sdk::{testutils::{Address as AddressTrait, Ledger, LedgerInfo}, Address, Env, String}; +use soroban_sdk::{ + testutils::{Address as AddressTrait, Ledger, LedgerInfo}, + Address, Env, String, +}; fn set_time(env: &Env, timestamp: u64) { let proto = env.ledger().protocol_version(); @@ -344,267 +347,217 @@ fn test_exact_goal_completion() { assert_eq!(goal.current_amount, 1000); } - #[test] - fn test_set_time_lock() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - client.set_time_lock(&owner, &goal_id, &10000); - - let goal = client.get_goal(&goal_id).unwrap(); - assert_eq!(goal.unlock_date, Some(10000)); - } - - #[test] - fn test_withdraw_time_locked_goal_before_unlock() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - client.add_to_goal(&owner, &goal_id, &5000); - client.unlock_goal(&owner, &goal_id); - client.set_time_lock(&owner, &goal_id, &10000); - - let result = client.try_withdraw_from_goal(&owner, &goal_id, &1000); - assert!(result.is_err()); - } - - #[test] - fn test_withdraw_time_locked_goal_after_unlock() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - client.add_to_goal(&owner, &goal_id, &5000); - client.unlock_goal(&owner, &goal_id); - client.set_time_lock(&owner, &goal_id, &3000); - - set_time(&env, 3500); - let new_amount = client.withdraw_from_goal(&owner, &goal_id, &1000); - assert_eq!(new_amount, 4000); - } - - #[test] - fn test_create_savings_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - assert_eq!(schedule_id, 1); - - let schedule = client.get_savings_schedule(&schedule_id); - assert!(schedule.is_some()); - let schedule = schedule.unwrap(); - assert_eq!(schedule.amount, 500); - assert_eq!(schedule.next_due, 3000); - assert!(schedule.active); - } - - #[test] - fn test_modify_savings_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - client.modify_savings_schedule(&owner, &schedule_id, &1000, &4000, &172800); - - let schedule = client.get_savings_schedule(&schedule_id).unwrap(); - assert_eq!(schedule.amount, 1000); - assert_eq!(schedule.next_due, 4000); - assert_eq!(schedule.interval, 172800); - } - - #[test] - fn test_cancel_savings_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - client.cancel_savings_schedule(&owner, &schedule_id); - - let schedule = client.get_savings_schedule(&schedule_id).unwrap(); - assert!(!schedule.active); - } - - #[test] - fn test_execute_due_savings_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &0); - - set_time(&env, 3500); - let executed = client.execute_due_savings_schedules(); - - assert_eq!(executed.len(), 1); - assert_eq!(executed.get(0).unwrap(), schedule_id); - - let goal = client.get_goal(&goal_id).unwrap(); - assert_eq!(goal.current_amount, 500); - } - - #[test] - fn test_execute_recurring_savings_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - - set_time(&env, 3500); - client.execute_due_savings_schedules(); - - let schedule = client.get_savings_schedule(&schedule_id).unwrap(); - assert!(schedule.active); - assert_eq!(schedule.next_due, 3000 + 86400); - - let goal = client.get_goal(&goal_id).unwrap(); - assert_eq!(goal.current_amount, 500); - } - - #[test] - fn test_execute_missed_savings_schedules() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &10000, - &5000, - ); - - let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - - set_time(&env, 3000 + 86400 * 3 + 100); - client.execute_due_savings_schedules(); - - let schedule = client.get_savings_schedule(&schedule_id).unwrap(); - assert_eq!(schedule.missed_count, 3); - assert!(schedule.next_due > 3000 + 86400 * 3); - } - - #[test] - fn test_savings_schedule_goal_completion() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); - - let goal_id = client.create_goal( - &owner, - &String::from_str(&env, "Education"), - &1000, - &5000, - ); - - client.create_savings_schedule(&owner, &goal_id, &1000, &3000, &0); - - set_time(&env, 3500); - client.execute_due_savings_schedules(); - - let goal = client.get_goal(&goal_id).unwrap(); - assert_eq!(goal.current_amount, 1000); - assert!(client.is_goal_completed(&goal_id)); - } +#[test] +fn test_set_time_lock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + client.set_time_lock(&owner, &goal_id, &10000); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.unlock_date, Some(10000)); +} + +#[test] +fn test_withdraw_time_locked_goal_before_unlock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + client.add_to_goal(&owner, &goal_id, &5000); + client.unlock_goal(&owner, &goal_id); + client.set_time_lock(&owner, &goal_id, &10000); + + let result = client.try_withdraw_from_goal(&owner, &goal_id, &1000); + assert!(result.is_err()); +} + +#[test] +fn test_withdraw_time_locked_goal_after_unlock() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + client.add_to_goal(&owner, &goal_id, &5000); + client.unlock_goal(&owner, &goal_id); + client.set_time_lock(&owner, &goal_id, &3000); + + set_time(&env, 3500); + let new_amount = client.withdraw_from_goal(&owner, &goal_id, &1000); + assert_eq!(new_amount, 4000); +} + +#[test] +fn test_create_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + assert_eq!(schedule_id, 1); + + let schedule = client.get_savings_schedule(&schedule_id); + assert!(schedule.is_some()); + let schedule = schedule.unwrap(); + assert_eq!(schedule.amount, 500); + assert_eq!(schedule.next_due, 3000); + assert!(schedule.active); +} + +#[test] +fn test_modify_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + client.modify_savings_schedule(&owner, &schedule_id, &1000, &4000, &172800); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.amount, 1000); + assert_eq!(schedule.next_due, 4000); + assert_eq!(schedule.interval, 172800); +} + +#[test] +fn test_cancel_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + client.cancel_savings_schedule(&owner, &schedule_id); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert!(!schedule.active); +} + +#[test] +fn test_execute_due_savings_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &0); + + set_time(&env, 3500); + let executed = client.execute_due_savings_schedules(); + + assert_eq!(executed.len(), 1); + assert_eq!(executed.get(0).unwrap(), schedule_id); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 500); +} + +#[test] +fn test_execute_recurring_savings_schedule() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + + set_time(&env, 3500); + client.execute_due_savings_schedules(); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert!(schedule.active); + assert_eq!(schedule.next_due, 3000 + 86400); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 500); +} + +#[test] +fn test_execute_missed_savings_schedules() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); + + let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); + + set_time(&env, 3000 + 86400 * 3 + 100); + client.execute_due_savings_schedules(); + + let schedule = client.get_savings_schedule(&schedule_id).unwrap(); + assert_eq!(schedule.missed_count, 3); + assert!(schedule.next_due > 3000 + 86400 * 3); +} + +#[test] +fn test_savings_schedule_goal_completion() { + let env = Env::default(); + let contract_id = env.register_contract(None, SavingsGoalContract); + let client = SavingsGoalContractClient::new(&env, &contract_id); + let owner = ::generate(&env); + + env.mock_all_auths(); + set_time(&env, 1000); + + let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &1000, &5000); + + client.create_savings_schedule(&owner, &goal_id, &1000, &3000, &0); + + set_time(&env, 3500); + client.execute_due_savings_schedules(); + + let goal = client.get_goal(&goal_id).unwrap(); + assert_eq!(goal.current_amount, 1000); + assert!(client.is_goal_completed(&goal_id)); +}