From c15baaef0fbda0b5c6b66b2e21c826f29dc15a2d Mon Sep 17 00:00:00 2001 From: smartdev Date: Sat, 21 Mar 2026 18:54:51 +0100 Subject: [PATCH 1/4] test: add sample Jest test to verify CI pipeline --- src/__tests__/app.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/__tests__/app.test.ts diff --git a/src/__tests__/app.test.ts b/src/__tests__/app.test.ts new file mode 100644 index 0000000..5ed0903 --- /dev/null +++ b/src/__tests__/app.test.ts @@ -0,0 +1,18 @@ +describe('App', () => { + describe('Basic Tests', () => { + it('should pass basic assertion', () => { + expect(1 + 1).toBe(2); + }); + + it('should handle string operations', () => { + const name = 'SubTrackr'; + expect(name).toContain('Sub'); + }); + + it('should work with arrays', () => { + const subs = ['Netflix', 'Spotify', 'Gym']; + expect(subs).toHaveLength(3); + expect(subs).toContain('Netflix'); + }); + }); +}); From 4da2043a98ecac8ffead85043868218de50d8c65 Mon Sep 17 00:00:00 2001 From: smartdev Date: Sat, 21 Mar 2026 19:02:36 +0100 Subject: [PATCH 2/4] fix: resolve lint errors and Rust test compilation issues - Apply prettier formatting to all TypeScript files - Remove unused imports and variables (shadows, formatCurrency, etc.) - Fix Rust tests to use SubTrackrContractClient::new instead of SubTrackrContract::new - Format Rust code with cargo fmt --- App.tsx | 44 +- contracts/src/lib.rs | 32 +- .../test/test_cancel_subscription.1.json | 1166 +++++++++++++++++ .../test_create_plan_and_subscribe.1.json | 1159 ++++++++++++++++ src/components/common/Button.tsx | 15 +- src/components/common/Card.tsx | 11 +- .../common/FloatingActionButton.tsx | 28 +- .../subscription/SubscriptionCard.tsx | 42 +- src/navigation/AppNavigator.tsx | 21 +- src/screens/AddSubscriptionScreen.tsx | 148 ++- src/screens/CryptoPaymentScreen.tsx | 66 +- src/screens/HomeScreen.tsx | 273 ++-- src/screens/WalletConnectScreen.tsx | 40 +- src/services/walletService.ts | 33 +- src/store/subscriptionStore.ts | 78 +- src/store/walletStore.ts | 50 +- src/utils/constants.ts | 20 +- src/utils/dummyData.ts | 20 +- src/utils/formatting.ts | 10 +- 19 files changed, 2756 insertions(+), 500 deletions(-) create mode 100644 contracts/test_snapshots/test/test_cancel_subscription.1.json create mode 100644 contracts/test_snapshots/test/test_create_plan_and_subscribe.1.json diff --git a/App.tsx b/App.tsx index e297c8e..ed4a9a8 100644 --- a/App.tsx +++ b/App.tsx @@ -3,25 +3,21 @@ import { StatusBar } from 'expo-status-bar'; import { AppNavigator } from './src/navigation/AppNavigator'; // Import WalletConnect compatibility layer -import "@walletconnect/react-native-compat"; +import '@walletconnect/react-native-compat'; -import { - createAppKit, - defaultConfig, - AppKit, -} from "@reown/appkit-ethers-react-native"; +import { createAppKit, defaultConfig, AppKit } from '@reown/appkit-ethers-react-native'; // Get projectId from environment variable -const projectId = process.env.WALLET_CONNECT_PROJECT_ID || "YOUR_PROJECT_ID"; +const projectId = process.env.WALLET_CONNECT_PROJECT_ID || 'YOUR_PROJECT_ID'; // Create metadata const metadata = { - name: "SubTrackr", - description: "Subscription Management with Crypto Payments", - url: "https://subtrackr.app", - icons: ["https://subtrackr.app/icon.png"], + name: 'SubTrackr', + description: 'Subscription Management with Crypto Payments', + url: 'https://subtrackr.app', + icons: ['https://subtrackr.app/icon.png'], redirect: { - native: "subtrackr://", + native: 'subtrackr://', }, }; @@ -30,26 +26,26 @@ const config = defaultConfig({ metadata }); // Define supported chains const mainnet = { chainId: 1, - name: "Ethereum", - currency: "ETH", - explorerUrl: "https://etherscan.io", - rpcUrl: "https://cloudflare-eth.com", + name: 'Ethereum', + currency: 'ETH', + explorerUrl: 'https://etherscan.io', + rpcUrl: 'https://cloudflare-eth.com', }; const polygon = { chainId: 137, - name: "Polygon", - currency: "MATIC", - explorerUrl: "https://polygonscan.com", - rpcUrl: "https://polygon-rpc.com", + name: 'Polygon', + currency: 'MATIC', + explorerUrl: 'https://polygonscan.com', + rpcUrl: 'https://polygon-rpc.com', }; const arbitrum = { chainId: 42161, - name: "Arbitrum", - currency: "ETH", - explorerUrl: "https://arbiscan.io", - rpcUrl: "https://arb1.arbitrum.io/rpc", + name: 'Arbitrum', + currency: 'ETH', + explorerUrl: 'https://arbiscan.io', + rpcUrl: 'https://arb1.arbitrum.io/rpc', }; const chains = [mainnet, polygon, arbitrum]; diff --git a/contracts/src/lib.rs b/contracts/src/lib.rs index 89e8858..ef8944a 100644 --- a/contracts/src/lib.rs +++ b/contracts/src/lib.rs @@ -6,10 +6,10 @@ use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, String, Ve #[contracttype] #[derive(Clone, Debug, PartialEq)] pub enum Interval { - Weekly, // 604800s - Monthly, // 2592000s (30 days) - Quarterly, // 7776000s (90 days) - Yearly, // 31536000s (365 days) + Weekly, // 604800s + Monthly, // 2592000s (30 days) + Quarterly, // 7776000s (90 days) + Yearly, // 31536000s (365 days) } impl Interval { @@ -39,8 +39,8 @@ pub struct Plan { pub id: u64, pub merchant: Address, pub name: String, - pub price: i128, // price per interval in stroops (XLM smallest unit) - pub token: Address, // token address (native XLM or Stellar asset) + pub price: i128, // price per interval in stroops (XLM smallest unit) + pub token: Address, // token address (native XLM or Stellar asset) pub interval: Interval, pub active: bool, pub subscriber_count: u32, @@ -120,12 +120,8 @@ impl SubTrackrContract { created_at: env.ledger().timestamp(), }; - env.storage() - .persistent() - .set(&DataKey::Plan(count), &plan); - env.storage() - .instance() - .set(&DataKey::PlanCount, &count); + env.storage().persistent().set(&DataKey::Plan(count), &plan); + env.storage().instance().set(&DataKey::PlanCount, &count); // Track merchant's plans let mut merchant_plans: Vec = env @@ -229,13 +225,9 @@ impl SubTrackrContract { .get(&DataKey::Subscription(subscription_id)) .expect("Subscription not found"); + assert!(sub.subscriber == subscriber, "Only subscriber can cancel"); assert!( - sub.subscriber == subscriber, - "Only subscriber can cancel" - ); - assert!( - sub.status == SubscriptionStatus::Active - || sub.status == SubscriptionStatus::Paused, + sub.status == SubscriptionStatus::Active || sub.status == SubscriptionStatus::Paused, "Subscription not active" ); @@ -412,7 +404,7 @@ mod test { fn test_create_plan_and_subscribe() { let env = Env::default(); let contract_id = env.register_contract(None, SubTrackrContract); - let client = SubTrackrContract::new(&env, &contract_id); + let client = SubTrackrContractClient::new(&env, &contract_id); let admin = Address::generate(&env); let merchant = Address::generate(&env); @@ -453,7 +445,7 @@ mod test { fn test_cancel_subscription() { let env = Env::default(); let contract_id = env.register_contract(None, SubTrackrContract); - let client = SubTrackrContract::new(&env, &contract_id); + let client = SubTrackrContractClient::new(&env, &contract_id); let admin = Address::generate(&env); let merchant = Address::generate(&env); diff --git a/contracts/test_snapshots/test/test_cancel_subscription.1.json b/contracts/test_snapshots/test/test_cancel_subscription.1.json new file mode 100644 index 0000000..02349b5 --- /dev/null +++ b/contracts/test_snapshots/test/test_cancel_subscription.1.json @@ -0,0 +1,1166 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_plan", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "Basic" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "subscribe", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "cancel_subscription", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "MerchantPlans" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "MerchantPlans" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "u64": 1 + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Plan" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Plan" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + }, + { + "key": { + "symbol": "merchant" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Basic" + } + }, + { + "key": { + "symbol": "price" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "subscriber_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Subscription" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Subscription" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "last_charged_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "next_charge_at" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "plan_id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "started_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "subscriber" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "total_paid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UserSubscriptions" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UserSubscriptions" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "u64": 1 + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "PlanCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "SubscriptionCount" + } + ] + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_plan" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "Basic" + }, + { + "i128": { + "hi": 0, + "lo": 500 + } + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_plan" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "subscribe" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "subscribe" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "cancel_subscription" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "cancel_subscription" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_subscription" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_subscription" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "last_charged_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "next_charge_at" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "plan_id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "started_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "subscriber" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "total_paid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_plan" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_plan" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + }, + { + "key": { + "symbol": "merchant" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Basic" + } + }, + { + "key": { + "symbol": "price" + }, + "val": { + "i128": { + "hi": 0, + "lo": 500 + } + } + }, + { + "key": { + "symbol": "subscriber_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/test_snapshots/test/test_create_plan_and_subscribe.1.json b/contracts/test_snapshots/test/test_create_plan_and_subscribe.1.json new file mode 100644 index 0000000..761689f --- /dev/null +++ b/contracts/test_snapshots/test/test_create_plan_and_subscribe.1.json @@ -0,0 +1,1159 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_plan", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "Pro Plan" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "subscribe", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 21, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "MerchantPlans" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "MerchantPlans" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "u64": 1 + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Plan" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Plan" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + }, + { + "key": { + "symbol": "merchant" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Pro Plan" + } + }, + { + "key": { + "symbol": "price" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "subscriber_count" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Subscription" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Subscription" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "last_charged_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "next_charge_at" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "plan_id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "started_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Active" + } + ] + } + }, + { + "key": { + "symbol": "subscriber" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "total_paid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UserSubscriptions" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UserSubscriptions" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "u64": 1 + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "PlanCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "SubscriptionCount" + } + ] + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "initialize" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_plan" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "Pro Plan" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_plan" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_plan_count" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_plan_count" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_plan" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_plan" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "active" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "interval" + }, + "val": { + "vec": [ + { + "symbol": "Monthly" + } + ] + } + }, + { + "key": { + "symbol": "merchant" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "Pro Plan" + } + }, + { + "key": { + "symbol": "price" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "subscriber_count" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "subscribe" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "subscribe" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_subscription" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_subscription" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "last_charged_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "next_charge_at" + }, + "val": { + "u64": 2592000 + } + }, + { + "key": { + "symbol": "plan_id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "started_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Active" + } + ] + } + }, + { + "key": { + "symbol": "subscriber" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "total_paid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_user_subscriptions" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_user_subscriptions" + } + ], + "data": { + "vec": [ + { + "u64": 1 + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/src/components/common/Button.tsx b/src/components/common/Button.tsx index 7f2e18c..bff8932 100644 --- a/src/components/common/Button.tsx +++ b/src/components/common/Button.tsx @@ -41,8 +41,7 @@ export const Button: React.FC = ({ style={buttonStyle} onPress={onPress} disabled={disabled || loading} - activeOpacity={0.8} - > + activeOpacity={0.8}> {loading ? ( = ({ } }; - const cardStyle = [ - styles.card, - styles[variant], - getPaddingStyle(), - style, - ]; + const cardStyle = [styles.card, styles[variant], getPaddingStyle(), style]; return {children}; }; @@ -45,7 +40,7 @@ const styles = StyleSheet.create({ backgroundColor: colors.surface, borderRadius: borderRadius.lg, }, - + // Variants default: { borderWidth: 1, @@ -58,7 +53,7 @@ const styles = StyleSheet.create({ borderWidth: 2, borderColor: colors.border, }, - + // Padding variants paddingNone: {}, paddingSmall: { diff --git a/src/components/common/FloatingActionButton.tsx b/src/components/common/FloatingActionButton.tsx index 2d7d1df..e97cfd3 100644 --- a/src/components/common/FloatingActionButton.tsx +++ b/src/components/common/FloatingActionButton.tsx @@ -17,26 +17,12 @@ export const FloatingActionButton: React.FC = ({ style, size = 'medium', }) => { - const buttonStyle = [ - styles.button, - styles[size], - style, - ]; + const buttonStyle = [styles.button, styles[size], style]; return ( - - - {icon} - - {title && ( - - {title} - - )} + + {icon} + {title && {title}} ); }; @@ -50,7 +36,7 @@ const styles = StyleSheet.create({ justifyContent: 'center', ...shadows.lg, }, - + // Sizes small: { width: 48, @@ -70,7 +56,7 @@ const styles = StyleSheet.create({ bottom: spacing.lg, right: spacing.lg, }, - + // Icon styles icon: { color: colors.text, @@ -85,7 +71,7 @@ const styles = StyleSheet.create({ largeIcon: { fontSize: 28, }, - + // Title styles title: { color: colors.text, diff --git a/src/components/subscription/SubscriptionCard.tsx b/src/components/subscription/SubscriptionCard.tsx index 868ce9a..5eebc4c 100644 --- a/src/components/subscription/SubscriptionCard.tsx +++ b/src/components/subscription/SubscriptionCard.tsx @@ -2,7 +2,12 @@ import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Alert } from 'react-native'; import { colors, spacing, typography, borderRadius, shadows } from '../../utils/constants'; import { Subscription, SubscriptionCategory } from '../../types/subscription'; -import { formatCurrency, formatCategory, formatBillingCycle, formatRelativeDate } from '../../utils/formatting'; +import { + formatCurrency, + formatCategory, + formatBillingCycle, + formatRelativeDate, +} from '../../utils/formatting'; export interface SubscriptionCardProps { subscription: Subscription; @@ -69,13 +74,12 @@ export const SubscriptionCard: React.FC = ({ onPress(subscription)} - activeOpacity={0.8} - > + activeOpacity={0.8}> {getCategoryIcon(subscription.category)} - + {subscription.name} @@ -84,9 +88,14 @@ export const SubscriptionCard: React.FC = ({ {formatCategory(subscription.category)} - + - + {subscription.isCryptoEnabled && ( โ‚ฟ @@ -94,17 +103,21 @@ export const SubscriptionCard: React.FC = ({ )} - + {formatCurrency(subscription.price, subscription.currency)} - + /{formatBillingCycle(subscription.billingCycle)} - + Next billing: @@ -112,22 +125,19 @@ export const SubscriptionCard: React.FC = ({ - + {subscription.description && ( {subscription.description} )} - + {onToggleStatus && ( - - {subscription.isActive ? 'Pause' : 'Activate'} - + activeOpacity={0.7}> + {subscription.isActive ? 'Pause' : 'Activate'} )} diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index fe1a891..c6ae09f 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -15,23 +15,19 @@ const Stack = createNativeStackNavigator(); const HomeStack = () => ( - - + - - @@ -49,8 +45,7 @@ const TabNavigator = () => ( tabBarActiveTintColor: colors.primary, tabBarInactiveTintColor: colors.textSecondary, headerShown: false, - }} - > + }}> { const navigation = useNavigation>(); const { addSubscription, isLoading } = useSubscriptionStore(); - + const [formData, setFormData] = useState({ name: '', description: '', @@ -37,22 +35,29 @@ const AddSubscriptionScreen: React.FC = () => { cryptoToken: undefined, cryptoAmount: undefined, }); - - const [selectedCategory, setSelectedCategory] = useState(SubscriptionCategory.OTHER); - const [selectedBillingCycle, setSelectedBillingCycle] = useState(BillingCycle.MONTHLY); + + const [selectedCategory, setSelectedCategory] = useState( + SubscriptionCategory.OTHER + ); + const [selectedBillingCycle, setSelectedBillingCycle] = useState( + BillingCycle.MONTHLY + ); const handleCategorySelect = (category: SubscriptionCategory) => { setSelectedCategory(category); - setFormData(prev => ({ ...prev, category })); + setFormData((prev) => ({ ...prev, category })); }; const handleBillingCycleSelect = (cycle: BillingCycle) => { setSelectedBillingCycle(cycle); - setFormData(prev => ({ ...prev, billingCycle: cycle })); + setFormData((prev) => ({ ...prev, billingCycle: cycle })); }; - const handleInputChange = (field: keyof SubscriptionFormData, value: string | number | boolean) => { - setFormData(prev => ({ ...prev, [field]: value })); + const handleInputChange = ( + field: keyof SubscriptionFormData, + value: string | number | boolean + ) => { + setFormData((prev) => ({ ...prev, [field]: value })); }; const handleSubmit = async () => { @@ -60,7 +65,7 @@ const AddSubscriptionScreen: React.FC = () => { Alert.alert('Error', 'Please enter a subscription name'); return; } - + if (formData.price <= 0) { Alert.alert('Error', 'Please enter a valid price'); return; @@ -68,25 +73,23 @@ const AddSubscriptionScreen: React.FC = () => { try { await addSubscription(formData); - + if (formData.isCryptoEnabled) { Alert.alert( - 'Success!', + 'Success!', 'Subscription added successfully! Would you like to set up crypto payments now?', [ { text: 'Later', onPress: () => navigation.goBack() }, - { - text: 'Setup Crypto', - onPress: () => navigation.navigate('CryptoPayment', { subscriptionId: 'new' }) + { + text: 'Setup Crypto', + onPress: () => navigation.navigate('CryptoPayment', { subscriptionId: 'new' }), }, ] ); } else { - Alert.alert( - 'Success', - 'Subscription added successfully!', - [{ text: 'OK', onPress: () => navigation.goBack() }] - ); + Alert.alert('Success', 'Subscription added successfully!', [ + { text: 'OK', onPress: () => navigation.goBack() }, + ]); } } catch (error) { Alert.alert('Error', 'Failed to add subscription. Please try again.'); @@ -94,15 +97,15 @@ const AddSubscriptionScreen: React.FC = () => { }; const handleCancel = () => { - if (formData.name.trim() || (formData.description && formData.description.trim()) || formData.price > 0) { - Alert.alert( - 'Discard Changes', - 'Are you sure you want to discard your changes?', - [ - { text: 'Cancel', style: 'cancel' }, - { text: 'Discard', style: 'destructive', onPress: () => navigation.goBack() }, - ] - ); + if ( + formData.name.trim() || + (formData.description && formData.description.trim()) || + formData.price > 0 + ) { + Alert.alert('Discard Changes', 'Are you sure you want to discard your changes?', [ + { text: 'Cancel', style: 'cancel' }, + { text: 'Discard', style: 'destructive', onPress: () => navigation.goBack() }, + ]); } else { navigation.goBack(); } @@ -110,10 +113,9 @@ const AddSubscriptionScreen: React.FC = () => { return ( - + behavior={Platform.OS === 'ios' ? 'padding' : 'height'}> @@ -125,7 +127,7 @@ const AddSubscriptionScreen: React.FC = () => { Track your new subscription - + Basic Information @@ -140,7 +142,7 @@ const AddSubscriptionScreen: React.FC = () => { autoFocus /> - + Description (Optional) { /> - + Category @@ -164,21 +166,21 @@ const AddSubscriptionScreen: React.FC = () => { key={category} style={[ styles.categoryItem, - selectedCategory === category && styles.categoryItemSelected + selectedCategory === category && styles.categoryItemSelected, ]} - onPress={() => handleCategorySelect(category)} - > - + onPress={() => handleCategorySelect(category)}> + {category.charAt(0).toUpperCase() + category.slice(1)} ))} - + Billing Details @@ -198,7 +200,7 @@ const AddSubscriptionScreen: React.FC = () => { /> - + Billing Cycle @@ -207,14 +209,14 @@ const AddSubscriptionScreen: React.FC = () => { key={cycle} style={[ styles.billingCycleItem, - selectedBillingCycle === cycle && styles.billingCycleItemSelected + selectedBillingCycle === cycle && styles.billingCycleItemSelected, ]} - onPress={() => handleBillingCycleSelect(cycle)} - > - + onPress={() => handleBillingCycleSelect(cycle)}> + {cycle.charAt(0).toUpperCase() + cycle.slice(1)} @@ -222,22 +224,24 @@ const AddSubscriptionScreen: React.FC = () => { - + Crypto Options handleInputChange('isCryptoEnabled', !formData.isCryptoEnabled)} - > - - + onPress={() => handleInputChange('isCryptoEnabled', !formData.isCryptoEnabled)}> + + Enable crypto payments @@ -245,7 +249,7 @@ const AddSubscriptionScreen: React.FC = () => { - +