diff --git a/.eslintrc.json b/.eslintrc.json index 21b031f..ad2bef1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,8 +1,5 @@ { - "extends": [ - "expo", - "plugin:@typescript-eslint/recommended" - ], + "extends": ["expo", "plugin:@typescript-eslint/recommended"], "plugins": ["@typescript-eslint", "prettier"], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/.github/BRANCH_PROTECTION.md b/.github/BRANCH_PROTECTION.md index 51a5782..2f9fc5b 100644 --- a/.github/BRANCH_PROTECTION.md +++ b/.github/BRANCH_PROTECTION.md @@ -3,16 +3,19 @@ To enforce the CI/CD pipeline quality gates, configure branch protection rules in your GitHub repository: ## Settings Location + Go to: Repository Settings → Branches → Add rule ## Required Settings for `main` branch: ### Branch name pattern + ``` main ``` ### ✅ Required checks (enable ALL): + - [ ] **typescript-lint** - ESLint and Prettier checks - [ ] **typescript-typecheck** - TypeScript type validation - [ ] **typescript-tests** - Jest test suite @@ -23,6 +26,7 @@ main - [ ] **rust-build** - Rust contract compilation ### Additional protections: + - [x] Require pull request before merging - [x] Require at least 1 approval (recommended) - [x] Dismiss stale reviews @@ -31,6 +35,7 @@ main - [x] Do not allow bypassing the above settings ## Settings Location for `dev` branch (optional): + Similar settings, but you may allow force pushes for rapid development. --- @@ -38,6 +43,7 @@ Similar settings, but you may allow force pushes for rapid development. ## Verification After setting up, verify by: + 1. Creating a test PR 2. Intentionally break a lint rule 3. Verify the PR cannot be merged until fixed diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6580962..2a2aedd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,7 @@ ## Pull Request Checklist ### Quality Gates (All must pass before merge) + - [ ] **Lint**: Code passes ESLint and Prettier checks - [ ] **Type Check**: TypeScript compilation succeeds - [ ] **Tests**: All tests pass @@ -11,12 +12,14 @@ - [ ] **Rust Build**: Smart contracts compile successfully ### Additional Requirements + - [ ] New code has appropriate TypeScript types - [ ] No hardcoded secrets or credentials - [ ] New features have corresponding tests - [ ] Documentation updated if needed ### Reviewers + - At least 1 approval required for merge - All CI checks must be green diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae94be8..48ccbc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: env: NODE_VERSION: '20' - RUST_VERSION: '1.77' + RUST_VERSION: 'stable' jobs: # ───────────────────────────────────────────────────────── @@ -108,7 +108,7 @@ jobs: - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: - version: ${{ env.RUST_VERSION }} + toolchain: ${{ env.RUST_VERSION }} components: rustfmt - name: Check Rust formatting @@ -124,7 +124,7 @@ jobs: - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: - version: ${{ env.RUST_VERSION }} + toolchain: ${{ env.RUST_VERSION }} components: clippy - name: Cache Rust dependencies @@ -146,7 +146,7 @@ jobs: - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: - version: ${{ env.RUST_VERSION }} + toolchain: ${{ env.RUST_VERSION }} - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 @@ -167,7 +167,7 @@ jobs: - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: - version: ${{ env.RUST_VERSION }} + toolchain: ${{ env.RUST_VERSION }} - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 @@ -185,7 +185,17 @@ jobs: name: Merge Protection Check runs-on: ubuntu-latest if: github.event_name == 'pull_request' - needs: [typescript-lint, typescript-typecheck, typescript-tests, typescript-build, rust-format, rust-clippy, rust-tests, rust-build] + needs: + [ + typescript-lint, + typescript-typecheck, + typescript-tests, + typescript-build, + rust-format, + rust-clippy, + rust-tests, + rust-build, + ] steps: - name: All checks passed run: echo "All quality gates passed!" @@ -197,7 +207,17 @@ jobs: name: CI Complete runs-on: ubuntu-latest if: always() - needs: [typescript-lint, typescript-typecheck, typescript-tests, typescript-build, rust-format, rust-clippy, rust-tests, rust-build] + needs: + [ + typescript-lint, + typescript-typecheck, + typescript-tests, + typescript-build, + rust-format, + rust-clippy, + rust-tests, + rust-build, + ] steps: - name: Check for failures run: | diff --git a/.prettierignore b/.prettierignore index 3b34e4a..ee9c236 100644 --- a/.prettierignore +++ b/.prettierignore @@ -16,3 +16,5 @@ builds/ .env .DS_Store coverage/ +contracts/target/ +contracts/test_snapshots/ 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/BUILD_FIX_GUIDE.md b/BUILD_FIX_GUIDE.md index 9537cee..9f200c0 100644 --- a/BUILD_FIX_GUIDE.md +++ b/BUILD_FIX_GUIDE.md @@ -7,12 +7,14 @@ Your build is failing due to **React Native dependency version mismatches** with ## 🔍 **Root Cause Analysis** ### **Error Details** + ``` > Task :react-native-gesture-handler:compileDebugKotlin FAILED > Task :react-native-screens:compileDebugKotlin FAILED ``` ### **Why This Happens** + - **Expo SDK 53** uses **React Native 0.79.5** - **React Native Gesture Handler** and **Screens** have version compatibility issues - **Kotlin compilation** fails due to missing abstract method implementations @@ -20,6 +22,7 @@ Your build is failing due to **React Native dependency version mismatches** with ## 🛠️ **SOLUTION OPTIONS** ### **Option 1: Use the Fix Script (Recommended)** + ```bash # Make script executable chmod +x fix-build.sh @@ -29,6 +32,7 @@ chmod +x fix-build.sh ``` ### **Option 2: Manual Fix** + ```bash # Step 1: Clean everything rm -rf node_modules/ @@ -56,6 +60,7 @@ cd .. ``` ### **Option 3: Downgrade React Native (Alternative)** + If the above doesn't work, you can try using React Native 0.78.x: ```bash @@ -71,6 +76,7 @@ npx expo prebuild --platform android --clean ## 🔧 **WHAT THE FIX SCRIPT DOES** ### **Step-by-Step Process** + 1. **🧹 Complete Cleanup**: Removes all build artifacts and dependencies 2. **📦 Dependency Reset**: Reinstalls all packages with compatible versions 3. **🔄 Cache Clear**: Clears Expo cache and fixes dependency conflicts @@ -79,6 +85,7 @@ npx expo prebuild --platform android --clean 6. **📱 APK Output**: Creates `builds/subtrackr.apk` ### **Files Modified** + - `package.json` - Updated with compatible versions - `package.json.backup` - Backup of original configuration - `builds/` - New output directory for APK @@ -86,6 +93,7 @@ npx expo prebuild --platform android --clean ## 🚀 **AFTER THE FIX** ### **Successful Build Output** + ``` 📱 APK Details: Name: subtrackr.apk @@ -95,6 +103,7 @@ npx expo prebuild --platform android --clean ``` ### **Next Steps** + 1. **Test APK**: Install on device to verify functionality 2. **Future Builds**: Use `./build.sh` for regular builds 3. **Hackathon**: Share `builds/subtrackr.apk` with judges @@ -104,24 +113,28 @@ npx expo prebuild --platform android --clean ### **If Fix Script Fails** #### **1. Check Java Version** + ```bash java -version # Should be Java 11 or 17 ``` #### **2. Verify Android SDK** + ```bash echo $ANDROID_HOME # Should point to Android SDK location ``` #### **3. Check Node.js Version** + ```bash node --version # Should be Node 16+ for Expo SDK 53 ``` #### **4. Clear Gradle Cache** + ```bash cd android ./gradlew clean @@ -132,17 +145,20 @@ cd .. ### **Common Error Messages** #### **"Permission Denied"** + ```bash chmod +x fix-build.sh ./fix-build.sh ``` #### **"Command Not Found: expo"** + ```bash npm install -g @expo/cli ``` #### **"Android SDK Not Found"** + ```bash export ANDROID_HOME=$HOME/Library/Android/sdk # macOS export PATH=$PATH:$ANDROID_HOME/platform-tools @@ -151,6 +167,7 @@ export PATH=$PATH:$ANDROID_HOME/platform-tools ## 📱 **BUILD VERIFICATION** ### **APK Testing Checklist** + - [ ] **Installation**: APK installs without errors - [ ] **Launch**: App opens without crashes - [ ] **Navigation**: All screens work properly @@ -158,6 +175,7 @@ export PATH=$PATH:$ANDROID_HOME/platform-tools - [ ] **Performance**: App responds smoothly ### **Device Compatibility** + - **Android Version**: 5.0+ (API 21+) - **Architecture**: ARM64, x86_64 - **Screen Sizes**: All standard Android sizes @@ -165,12 +183,14 @@ export PATH=$PATH:$ANDROID_HOME/platform-tools ## 🎯 **HACKATHON READY** ### **What You'll Have** + - ✅ **Working APK**: `builds/subtrackr.apk` - ✅ **Professional Build**: Industry-standard process - ✅ **Easy Distribution**: Ready to share with judges - ✅ **Technical Excellence**: Demonstrates build expertise ### **Judging Impact** + - **Problem Solving**: Shows ability to resolve technical issues - **Technical Depth**: Understanding of React Native build systems - **Professional Quality**: Production-ready build process @@ -179,6 +199,7 @@ export PATH=$PATH:$ANDROID_HOME/platform-tools ## 🎉 **SUCCESS!** After running the fix script, you'll have: + - **🔧 Resolved build issues** with Kotlin compilation - **📱 Working Android APK** ready for submission - **🚀 Professional build system** for future development @@ -187,14 +208,17 @@ After running the fix script, you'll have: ## 🆘 **NEED HELP?** ### **Run the Fix Script** + ```bash ./fix-build.sh ``` ### **Check the Logs** + The script provides detailed output for each step. ### **Manual Steps** + Follow the manual fix guide if you prefer step-by-step control. --- diff --git a/JS_BUNDLE_FIX.md b/JS_BUNDLE_FIX.md index c88d12a..7f5338e 100644 --- a/JS_BUNDLE_FIX.md +++ b/JS_BUNDLE_FIX.md @@ -3,9 +3,10 @@ ## 🚨 **ERROR IDENTIFIED:** Your APK is showing this error on physical device: + ``` -"Unable to load script. Make sure you're either running Metro -(run 'npx react-native start') or that your bundle +"Unable to load script. Make sure you're either running Metro +(run 'npx react-native start') or that your bundle 'index.android.bundle' is packaged correctly for release." ``` @@ -14,6 +15,7 @@ Your APK is showing this error on physical device: The **debug APK** you built is missing the JavaScript bundle (`index.android.bundle`) that contains your app's code. ### **Why This Happens:** + - **Debug builds** expect Metro bundler to be running on your computer - **Release builds** need JS code bundled inside the APK - **Physical device testing** requires bundled JS code @@ -21,6 +23,7 @@ The **debug APK** you built is missing the JavaScript bundle (`index.android.bun ## 🛠️ **SOLUTION: Build Release APK with Bundled JS** ### **Option 1: Use Release Build Script (Recommended)** + ```bash # Make executable and run chmod +x build-release.sh @@ -28,6 +31,7 @@ chmod +x build-release.sh ``` ### **Option 2: Manual Fix** + ```bash # Step 1: Ensure clean prebuild npx expo prebuild --platform android --clean @@ -57,12 +61,14 @@ cp android/app/build/outputs/apk/release/*.apk builds/subtrackr-release.apk ## 📱 **WHAT YOU'LL GET:** ### **Release APK Features:** + - ✅ **Bundled JavaScript**: All your app code is inside the APK - ✅ **Offline Working**: No need for Metro bundler - ✅ **Physical Device Ready**: Works on any Android device - ✅ **Hackathon Ready**: Professional, distributable APK ### **Expected Output:** + ``` 📱 Release APK Details: Name: subtrackr-release.apk @@ -75,11 +81,13 @@ cp android/app/build/outputs/apk/release/*.apk builds/subtrackr-release.apk ## 🔧 **DIFFERENCE BETWEEN BUILD TYPES:** ### **Debug Build (What You Had):** + - ❌ **No JS Bundle**: Expects Metro bundler - ❌ **Development Only**: Won't work on physical devices - ❌ **Requires Computer**: Needs development server running ### **Release Build (What You Need):** + - ✅ **JS Bundle Included**: All code packaged inside APK - ✅ **Production Ready**: Works on any device - ✅ **Standalone**: No external dependencies @@ -87,12 +95,14 @@ cp android/app/build/outputs/apk/release/*.apk builds/subtrackr-release.apk ## 🚀 **AFTER BUILDING RELEASE APK:** ### **Installation Steps:** + 1. **Transfer APK**: Copy `builds/subtrackr-release.apk` to your device 2. **Enable Unknown Sources**: Allow installation from unknown sources 3. **Install APK**: Tap the APK file to install 4. **Launch App**: App should work without any errors ### **Testing Checklist:** + - [ ] **Installation**: APK installs without errors - [ ] **Launch**: App opens without red box errors - [ ] **Navigation**: All screens work properly @@ -102,11 +112,13 @@ cp android/app/build/outputs/apk/release/*.apk builds/subtrackr-release.apk ## 🎯 **HACKATHON IMPACT:** ### **Professional Quality:** + - **Working APK**: Judges can actually test your app - **No Errors**: Clean, professional user experience - **Offline Capable**: Demonstrates production readiness ### **Technical Excellence:** + - **Build System**: Shows understanding of React Native builds - **Problem Solving**: Demonstrates ability to resolve complex issues - **User Experience**: Judges get working app, not error screens @@ -114,6 +126,7 @@ cp android/app/build/outputs/apk/release/*.apk builds/subtrackr-release.apk ## 🆘 **TROUBLESHOOTING:** ### **If Bundle Command Fails:** + ```bash # Check if react-native CLI is available npx react-native --version @@ -123,6 +136,7 @@ npm install -g @react-native-community/cli ``` ### **If Release Build Fails:** + ```bash # Check Android build tools cd android @@ -134,6 +148,7 @@ cd .. ``` ### **If APK Still Shows Errors:** + ```bash # Verify bundle was created ls -la android/app/src/main/assets/ @@ -144,6 +159,7 @@ ls -la android/app/src/main/assets/ ## 🎉 **SUCCESS GUARANTEED!** After building the release APK: + - ✅ **No More Red Box Errors** - ✅ **App Works on Physical Device** - ✅ **Ready for Hackathon Submission** @@ -152,11 +168,13 @@ After building the release APK: ## 🚀 **READY TO FIX!** ### **Quick Fix Command:** + ```bash ./build-release.sh ``` ### **Manual Fix Commands:** + ```bash npx expo prebuild --platform android --clean mkdir -p android/app/src/main/assets diff --git a/README.md b/README.md index ba151d9..4b9aba8 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,27 @@ SubTrackr is a mobile application for managing recurring payments and subscripti ## Features **Subscription Management** + - Track all subscriptions (Web2 and Web3 services) in one place - Smart categorization by type (streaming, productivity, infrastructure, etc.) - Quick-add presets for popular services or manual entry - Bulk actions: pause, cancel, or modify multiple subscriptions **On-Chain Recurring Payments** + - Authorize recurring XLM and Stellar token payments via Soroban contracts - Automatic billing cycle execution with configurable intervals - Multi-token support (XLM, USDC on Stellar, custom Stellar assets) - Transparent on-chain payment history **Smart Notifications** + - Billing reminders with advance warnings before charges - Price change alerts and spending insights - AI-powered savings suggestions **Wallet Integration** + - Native Freighter wallet connection for Stellar transactions - Social login support via Web3Auth - Real-time balance and transaction monitoring @@ -49,14 +53,14 @@ SubTrackr/ ## Tech Stack -| Layer | Technology | -|---|---| -| Mobile App | React Native, Expo, TypeScript | -| State | Zustand | -| Wallet | Freighter Wallet, Stellar SDK | -| Auth | Web3Auth (social login) | -| Smart Contracts | Soroban (Rust) on Stellar | -| Payments | XLM, Stellar tokens | +| Layer | Technology | +| --------------- | ------------------------------ | +| Mobile App | React Native, Expo, TypeScript | +| State | Zustand | +| Wallet | Freighter Wallet, Stellar SDK | +| Auth | Web3Auth (social login) | +| Smart Contracts | Soroban (Rust) on Stellar | +| Payments | XLM, Stellar tokens | ## Getting Started @@ -84,11 +88,11 @@ soroban contract deploy --wasm target/wasm32-unknown-unknown/release/subtrackr.w ### Environment Variables -| Variable | Description | -|---|---| -| `STELLAR_NETWORK` | `testnet` or `public` | -| `CONTRACT_ID` | Deployed Soroban subscription contract ID | -| `WEB3AUTH_CLIENT_ID` | Web3Auth client ID for social login | +| Variable | Description | +| -------------------- | ----------------------------------------- | +| `STELLAR_NETWORK` | `testnet` or `public` | +| `CONTRACT_ID` | Deployed Soroban subscription contract ID | +| `WEB3AUTH_CLIENT_ID` | Web3Auth client ID for social login | ## Contributing diff --git a/babel.config.js b/babel.config.js index 5c85f81..66d1c7d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,6 +1,6 @@ module.exports = function (api) { api.cache(true); return { - presets: [["babel-preset-expo", { unstable_transformImportMeta: true }]], + presets: [['babel-preset-expo', { unstable_transformImportMeta: true }]], }; }; 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/jest.config.js b/jest.config.js index 19562cc..f5a6564 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,11 +4,7 @@ module.exports = { 'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg|@walletconnect/.*)', ], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - collectCoverageFrom: [ - 'src/**/*.{ts,tsx}', - '!src/**/*.d.ts', - '!src/**/index.ts', - ], + collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.d.ts', '!src/**/index.ts'], testMatch: ['**/__tests__/**/*.(test|spec).[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'], moduleNameMapper: { '^@/(.*)$': '/src/$1', diff --git a/package-fixed.json b/package-fixed.json index 0519ecb..e69de29 100644 --- a/package-fixed.json +++ b/package-fixed.json @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/README.md b/src/README.md index cda1d9e..b464e04 100644 --- a/src/README.md +++ b/src/README.md @@ -7,6 +7,7 @@ This directory contains the complete source code for the SubTrackr application, ## 🏗️ Architecture Overview ### Component Hierarchy + 1. **Screens** (`/screens`) - Main app screens and user interfaces 2. **Components** (`/components`) - Reusable UI components organized by domain 3. **Navigation** (`/navigation`) - App navigation configuration and routing @@ -19,6 +20,7 @@ This directory contains the complete source code for the SubTrackr application, ## 🎨 Design System ### Color Palette + - **Primary**: `#6366f1` (Indigo) - Main brand color - **Secondary**: `#8b5cf6` (Purple) - Secondary actions - **Accent**: `#06b6d4` (Cyan) - Crypto/Web3 elements @@ -30,6 +32,7 @@ This directory contains the complete source code for the SubTrackr application, - **Text**: `#f8fafc` (Slate 50) - Primary text color ### Typography Scale + - **H1**: 32px - Main titles - **H2**: 24px - Section headers - **H3**: 20px - Subsection headers @@ -38,6 +41,7 @@ This directory contains the complete source code for the SubTrackr application, - **Small**: 12px - Fine print ### Spacing System + - **xs**: 4px - Minimal spacing - **sm**: 8px - Small spacing - **md**: 16px - Medium spacing @@ -48,6 +52,7 @@ This directory contains the complete source code for the SubTrackr application, ## 🔧 Implementation Status ### ✅ Completed + - [x] Project folder structure - [x] Design system constants - [x] TypeScript type definitions @@ -58,12 +63,14 @@ This directory contains the complete source code for the SubTrackr application, - [x] Utility functions ### 🚧 In Progress + - [ ] Service layer implementation - [ ] Custom React hooks - [ ] Advanced UI components - [ ] Web3 integration ### 📋 To Do + - [ ] Firebase integration - [ ] Push notifications - [ ] Analytics dashboard @@ -74,16 +81,19 @@ This directory contains the complete source code for the SubTrackr application, ## 🚀 Getting Started ### Prerequisites + - Node.js 16+ - React Native / Expo - TypeScript knowledge ### Development Setup + 1. Navigate to the project root 2. Install dependencies: `npm install` 3. Start the development server: `npm start` ### Code Style + - Use TypeScript for all new code - Follow the established component patterns - Use the design system constants for styling @@ -93,28 +103,25 @@ This directory contains the complete source code for the SubTrackr application, ## 📱 Component Usage Examples ### Using the Button Component + ```tsx import { Button } from '../components/common/Button'; -