Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
712 changes: 712 additions & 0 deletions BACKEND_ARCHITECTURE.md

Large diffs are not rendered by default.

895 changes: 895 additions & 0 deletions DEPLOYMENT_TROUBLESHOOTING.md

Large diffs are not rendered by default.

825 changes: 825 additions & 0 deletions NOTIFICATION_EXPIRATION_GUIDE.md

Large diffs are not rendered by default.

14 changes: 4 additions & 10 deletions contract/contracts/hello-world/src/autoshare_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ pub fn initialize_admin(env: Env, admin: Address) {

// Initialize empty supported tokens list in instance storage
let empty_tokens: Vec<Address> = Vec::new(&env);
env.storage().instance().set(&INSTANCE_TOKENS, &empty_tokens);
env.storage()
.instance()
.set(&INSTANCE_TOKENS, &empty_tokens);
}
}

Expand Down Expand Up @@ -336,8 +338,6 @@ pub fn pause(env: Env, admin: Address) -> Result<(), Error> {
}

env.storage().instance().set(&INSTANCE_PAUSED, &true);
ContractPaused {}.publish(&env);
env.storage().persistent().set(&pause_key, &true);
ContractPaused {
category: NotificationCategory::Admin,
priority: NotificationPriority::High,
Expand All @@ -361,8 +361,6 @@ pub fn unpause(env: Env, admin: Address) -> Result<(), Error> {
}

env.storage().instance().set(&INSTANCE_PAUSED, &false);
ContractUnpaused {}.publish(&env);
env.storage().persistent().set(&pause_key, &false);
ContractUnpaused {
category: NotificationCategory::Admin,
priority: NotificationPriority::High,
Expand Down Expand Up @@ -468,10 +466,7 @@ pub fn set_usage_fee(env: Env, fee: u32, admin: Address) -> Result<(), Error> {
}

pub fn get_usage_fee(env: Env) -> u32 {
env.storage()
.instance()
.get(&INSTANCE_FEE)
.unwrap_or(10u32)
env.storage().instance().get(&INSTANCE_FEE).unwrap_or(10u32)
}

// ============================================================================
Expand Down Expand Up @@ -1166,4 +1161,3 @@ pub fn extend_notification_expiry(

Ok(())
}

1 change: 0 additions & 1 deletion contract/contracts/hello-world/src/base/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,3 @@ pub struct NotificationExtended {
pub priority: NotificationPriority,
pub new_expires_at: u64,
}

12 changes: 9 additions & 3 deletions contract/contracts/hello-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ impl AutoShareContract {
) -> bool {
preferences_logic::is_category_enabled(env, recipient, category)
}
}

// ============================================================================
// Scheduled Notification Management
Expand Down Expand Up @@ -387,8 +386,13 @@ impl AutoShareContract {
caller: Address,
extension_seconds: u64,
) {
autoshare_logic::extend_notification_expiry(env, notification_id, caller, extension_seconds)
.unwrap();
autoshare_logic::extend_notification_expiry(
env,
notification_id,
caller,
extension_seconds,
)
.unwrap();
}
}

Expand All @@ -407,6 +411,8 @@ mod storage_optimization_test;
#[cfg(test)]
#[path = "tests/preferences_test.rs"]
mod preferences_test;

#[cfg(test)]
mod tests {
#[path = "../tests/autoshare_test.rs"]
mod autoshare_test;
Expand Down
8 changes: 5 additions & 3 deletions contract/contracts/hello-world/src/preferences_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
/// Preferences are stored in persistent storage keyed by recipient address.
use crate::base::errors::Error;
use crate::base::preferences::{
CategoryPreference, ChannelPreference, DeliveryChannel, NotificationCategory,
RecipientPreferences, default_categories, default_channels, load_preferences, save_preferences,
default_categories, default_channels, load_preferences, save_preferences, CategoryPreference,
ChannelPreference, DeliveryChannel, NotificationCategory, RecipientPreferences,
};
use soroban_sdk::{Address, Env, Vec};

Expand Down Expand Up @@ -76,7 +76,9 @@ pub fn set_channel_preference(
}

if !found {
prefs.channels.push_back(ChannelPreference { channel, enabled });
prefs
.channels
.push_back(ChannelPreference { channel, enabled });
}

prefs.updated_at = env.ledger().timestamp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,3 @@ fn test_cannot_extend_by_zero_seconds() {
// Must panic
client.extend_notification_expiry(&id, &creator, &0);
}

27 changes: 14 additions & 13 deletions contract/contracts/hello-world/src/tests/preferences_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod preferences_tests {
};
use crate::test_utils::setup_test_env;
use crate::{AutoShareContract, AutoShareContractClient};
use soroban_sdk::{testutils::Address as _, Address, Env, Vec};
use soroban_sdk::{testutils::Address as _, Address, Env, IntoVal, Vec};

// ============================================================================
// Default preferences
Expand All @@ -23,13 +23,21 @@ mod preferences_tests {
// All three channels enabled by default
assert_eq!(prefs.channels.len(), 3);
for ch in prefs.channels.iter() {
assert!(ch.enabled, "Channel {:?} should be enabled by default", ch.channel);
assert!(
ch.enabled,
"Channel {:?} should be enabled by default",
ch.channel
);
}

// All five categories enabled by default
assert_eq!(prefs.categories.len(), 5);
for cat in prefs.categories.iter() {
assert!(cat.enabled, "Category {:?} should be enabled by default", cat.category);
assert!(
cat.enabled,
"Category {:?} should be enabled by default",
cat.category
);
}

assert_eq!(prefs.recipient, recipient);
Expand Down Expand Up @@ -113,8 +121,7 @@ mod preferences_tests {
let recipient = test_env.users.get(0).unwrap();

{
let client =
AutoShareContractClient::new(&test_env.env, &test_env.autoshare_contract);
let client = AutoShareContractClient::new(&test_env.env, &test_env.autoshare_contract);
let mut channels = Vec::new(&test_env.env);
channels.push_back(ChannelPreference {
channel: DeliveryChannel::Wallet,
Expand Down Expand Up @@ -155,8 +162,7 @@ mod preferences_tests {
}

// New client instance ("page refresh")
let client2 =
AutoShareContractClient::new(&test_env.env, &test_env.autoshare_contract);
let client2 = AutoShareContractClient::new(&test_env.env, &test_env.autoshare_contract);
let prefs = client2.get_preferences(&recipient);

// Wallet should be disabled
Expand Down Expand Up @@ -334,12 +340,7 @@ mod preferences_tests {
invoke: &soroban_sdk::testutils::MockAuthInvoke {
contract: &contract_id,
fn_name: "set_channel_preference",
args: (
victim.clone(),
DeliveryChannel::Wallet,
false,
)
.into_val(&env),
args: (victim.clone(), DeliveryChannel::Wallet, false).into_val(&env),
sub_invokes: &[],
},
}]);
Expand Down
18 changes: 11 additions & 7 deletions contract/contracts/hello-world/src/tests/revocation_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ fn test_revoke_notification_emits_event() {
set_now(&test_env.env, 2_000);
client.revoke_notification(&id, &creator);

let topics = topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
let topics =
topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
// [0] name, [1] notification_id, [2] revoked_by, [3] category, [4] priority.
assert_eq!(topics.len(), 5);

Expand Down Expand Up @@ -327,12 +328,14 @@ fn test_revoke_event_has_high_priority() {
set_now(&test_env.env, 2_000);
client.revoke_notification(&id, &creator);

let topics = topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
let topics =
topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
// Last topic is priority
let priority_topic = topics.last().unwrap();
let priority = crate::base::events::NotificationPriority::try_from_val(&test_env.env, &priority_topic)
.expect("priority should be extractable");

let priority =
crate::base::events::NotificationPriority::try_from_val(&test_env.env, &priority_topic)
.expect("priority should be extractable");

assert_eq!(priority, crate::base::events::NotificationPriority::High);
}

Expand All @@ -349,12 +352,13 @@ fn test_revoke_event_has_notification_category() {
set_now(&test_env.env, 2_000);
client.revoke_notification(&id, &creator);

let topics = topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
let topics =
topics_of(&test_env.env, "notification_revoked").expect("revocation event must be emitted");
// Second to last topic is category
let n = topics.len();
let category_topic = topics.get(n - 2).unwrap();
let category = NotificationCategory::try_from_val(&test_env.env, &category_topic)
.expect("category should be extractable");

assert_eq!(category, NotificationCategory::Notification);
}
Loading