diff --git a/bill_payments/src/lib.rs b/bill_payments/src/lib.rs index ac7981c..fd310d9 100644 --- a/bill_payments/src/lib.rs +++ b/bill_payments/src/lib.rs @@ -83,6 +83,7 @@ pub enum Error { #[derive(Clone)] #[contracttype] #[derive(Clone)] +#[contracttype] pub struct ArchivedBill { pub id: u32, pub owner: Address, diff --git a/indexer/examples/query-examples.ts b/indexer/examples/query-examples.ts index ae9697e..6bed71a 100644 --- a/indexer/examples/query-examples.ts +++ b/indexer/examples/query-examples.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + /** * Example queries demonstrating the indexer API * Run with: ts-node examples/query-examples.ts diff --git a/indexer/src/api.ts b/indexer/src/api.ts index cbd58fc..f8763f2 100644 --- a/indexer/src/api.ts +++ b/indexer/src/api.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import Database from 'better-sqlite3'; import { QueryService } from './db/queries'; diff --git a/indexer/src/db/queries.ts b/indexer/src/db/queries.ts index 50f5f31..66d70cb 100644 --- a/indexer/src/db/queries.ts +++ b/indexer/src/db/queries.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import Database from 'better-sqlite3'; import { SavingsGoal, Bill, InsurancePolicy, RemittanceSplit } from '../types'; diff --git a/indexer/src/db/schema.ts b/indexer/src/db/schema.ts index 9c6d226..054ff1d 100644 --- a/indexer/src/db/schema.ts +++ b/indexer/src/db/schema.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import Database from 'better-sqlite3'; export function initializeDatabase(dbPath: string): Database.Database { diff --git a/indexer/src/eventProcessor.ts b/indexer/src/eventProcessor.ts index aa8a344..a79fe50 100644 --- a/indexer/src/eventProcessor.ts +++ b/indexer/src/eventProcessor.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import Database from 'better-sqlite3'; import { xdr } from '@stellar/stellar-sdk'; diff --git a/indexer/src/index.ts b/indexer/src/index.ts index edd1c2d..4503506 100644 --- a/indexer/src/index.ts +++ b/indexer/src/index.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import dotenv from 'dotenv'; import { initializeDatabase } from './db/schema'; import { Indexer } from './indexer'; diff --git a/indexer/src/indexer.ts b/indexer/src/indexer.ts index 5ab8fe2..cd99aff 100644 --- a/indexer/src/indexer.ts +++ b/indexer/src/indexer.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import { Server, SorobanRpc } from '@stellar/stellar-sdk'; import Database from 'better-sqlite3'; import { EventProcessor } from './eventProcessor'; diff --git a/indexer/src/types.ts b/indexer/src/types.ts index 5ba48f8..e01f93c 100644 --- a/indexer/src/types.ts +++ b/indexer/src/types.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + // Database entity types export interface SavingsGoal { id: number; diff --git a/indexer/tests/eventProcessor.test.ts b/indexer/tests/eventProcessor.test.ts index e3957f2..85ec612 100644 --- a/indexer/tests/eventProcessor.test.ts +++ b/indexer/tests/eventProcessor.test.ts @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Remitwise + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + /** * Unit tests for EventProcessor * Run with: npm test diff --git a/insurance/src/lib.rs b/insurance/src/lib.rs index ecdb15d..3c6d903 100644 --- a/insurance/src/lib.rs +++ b/insurance/src/lib.rs @@ -570,6 +570,106 @@ impl Insurance { ); } + // ----------------------------------------------------------------------- + // Tag management + // ----------------------------------------------------------------------- + + fn validate_tags(tags: &Vec) { + if tags.is_empty() { + panic!("Tags cannot be empty"); + } + for tag in tags.iter() { + if tag.len() == 0 || tag.len() > 32 { + panic!("Tag must be between 1 and 32 characters"); + } + } + } + + pub fn add_tags_to_policy( + env: Env, + caller: Address, + policy_id: u32, + tags: Vec, + ) { + caller.require_auth(); + Self::validate_tags(&tags); + Self::extend_instance_ttl(&env); + + let mut policies: Map = env + .storage() + .instance() + .get(&symbol_short!("POLICIES")) + .unwrap_or_else(|| Map::new(&env)); + + let mut policy = policies.get(policy_id).expect("Policy not found"); + + if policy.owner != caller { + panic!("Only the policy owner can add tags"); + } + + for tag in tags.iter() { + policy.tags.push_back(tag); + } + + policies.set(policy_id, policy); + env.storage() + .instance() + .set(&symbol_short!("POLICIES"), &policies); + + env.events().publish( + (symbol_short!("insure"), symbol_short!("tags_add")), + (policy_id, caller, tags), + ); + } + + pub fn remove_tags_from_policy( + env: Env, + caller: Address, + policy_id: u32, + tags: Vec, + ) { + caller.require_auth(); + Self::validate_tags(&tags); + Self::extend_instance_ttl(&env); + + let mut policies: Map = env + .storage() + .instance() + .get(&symbol_short!("POLICIES")) + .unwrap_or_else(|| Map::new(&env)); + + let mut policy = policies.get(policy_id).expect("Policy not found"); + + if policy.owner != caller { + panic!("Only the policy owner can remove tags"); + } + + let mut new_tags = Vec::new(&env); + for existing_tag in policy.tags.iter() { + let mut should_keep = true; + for remove_tag in tags.iter() { + if existing_tag == remove_tag { + should_keep = false; + break; + } + } + if should_keep { + new_tags.push_back(existing_tag); + } + } + + policy.tags = new_tags; + policies.set(policy_id, policy); + env.storage() + .instance() + .set(&symbol_short!("POLICIES"), &policies); + + env.events().publish( + (symbol_short!("insure"), symbol_short!("tags_rem")), + (policy_id, caller, tags), + ); + } + // ----------------------------------------------------------------------- // Core policy operations (unchanged) // -----------------------------------------------------------------------