# Project Mycelium - USD Credits System Implementation Plan ## Overview Transform the Project Mycelium from TFP-based system to a clean USD credits system with OpenRouter-style UX. This is a direct implementation for a development environment with no existing users. **Goal**: Create an intuitive marketplace where 1 Credit = $1 USD with seamless auto top-up and one-click purchasing. ## Architecture Approach This implementation leverages the existing builder pattern system and service architecture found in the codebase. All new components follow established patterns for consistency. ## Part 1: Core Currency System Changes ### 1.1 Update Currency Service **File**: `projectmycelium/src/services/currency.rs` **Changes**: ```rust // MODIFY: Line 25 in CurrencyService::new() impl CurrencyService { pub fn new() -> Self { let mock_data = MockDataService::new(); let mut service = Self { mock_data, exchange_rates_cache: HashMap::default(), last_update: Utc::now(), default_display_currency: "USD".to_string(), }; // Set USD Credits as base currency with 1:1 rate service.exchange_rates_cache.insert("USD".to_string(), dec!(1.0)); service.update_exchange_rates(); service } } ``` ### 1.2 Update Mock Data Service **File**: `projectmycelium/src/services/mock_data.rs` **Changes**: ```rust // MODIFY: Update base currency definition Currency { code: "USD".to_string(), name: "USD Credits".to_string(), symbol: "$".to_string(), currency_type: CurrencyType::Points, exchange_rate_to_base: dec!(1.0), is_base_currency: true, decimal_places: 2, is_active: true, provider_config: Some(ExchangeRateProvider::Static(dec!(1.0))), last_updated: Utc::now(), } ``` ## Part 2: Auto Top-up System Implementation ### 2.1 Add Auto Top-up Models **File**: `projectmycelium/src/services/user_persistence.rs` **Add to UserPersistentData** (around line 71): ```rust // ADD: Auto top-up settings #[serde(default)] pub auto_topup_settings: Option, ``` **Add new struct**: ```rust // ADD: After line 71 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AutoTopUpSettings { pub enabled: bool, pub threshold_amount: Decimal, pub topup_amount: Decimal, pub payment_method_id: String, pub daily_limit: Option, pub monthly_limit: Option, pub created_at: DateTime, pub updated_at: DateTime, } impl AutoTopUpSettings { pub fn builder() -> crate::models::builders::AutoTopUpSettingsBuilder { crate::models::builders::AutoTopUpSettingsBuilder::new() } } ``` ### 2.2 Add Auto Top-up Builder **File**: `projectmycelium/src/models/builders.rs` **Add at the end of the file**: ```rust // ============================================================================= // AUTO TOP-UP BUILDERS // ============================================================================= #[derive(Default)] pub struct AutoTopUpSettingsBuilder { enabled: Option, threshold_amount: Option, topup_amount: Option, payment_method_id: Option, daily_limit: Option, monthly_limit: Option, } impl AutoTopUpSettingsBuilder { pub fn new() -> Self { Self::default() } pub fn enabled(mut self, enabled: bool) -> Self { self.enabled = Some(enabled); self } pub fn threshold_amount(mut self, amount: Decimal) -> Self { self.threshold_amount = Some(amount); self } pub fn topup_amount(mut self, amount: Decimal) -> Self { self.topup_amount = Some(amount); self } pub fn payment_method_id(mut self, id: impl Into) -> Self { self.payment_method_id = Some(id.into()); self } pub fn daily_limit(mut self, limit: Decimal) -> Self { self.daily_limit = Some(limit); self } pub fn monthly_limit(mut self, limit: Decimal) -> Self { self.monthly_limit = Some(limit); self } pub fn build(self) -> Result { Ok(crate::services::user_persistence::AutoTopUpSettings { enabled: self.enabled.unwrap_or(false), threshold_amount: self.threshold_amount.unwrap_or(dec!(10.0)), topup_amount: self.topup_amount.unwrap_or(dec!(25.0)), payment_method_id: self.payment_method_id.ok_or("payment_method_id is required")?, daily_limit: self.daily_limit, monthly_limit: self.monthly_limit, created_at: Utc::now(), updated_at: Utc::now(), }) } } ``` ### 2.3 Create Auto Top-up Service **Create**: `projectmycelium/src/services/auto_topup.rs` ```rust //! Auto top-up service for automatic credit purchasing //! Follows the established builder pattern for consistent API design use crate::models::user::Transaction; use crate::services::currency::CurrencyService; use crate::services::user_persistence::{UserPersistence, AutoTopUpSettings}; use actix_session::Session; use rust_decimal::Decimal; use rust_decimal_macros::dec; use chrono::Utc; use uuid::Uuid; #[derive(Clone)] pub struct AutoTopUpService { currency_service: CurrencyService, } #[derive(Default)] pub struct AutoTopUpServiceBuilder { currency_service: Option, } impl AutoTopUpServiceBuilder { pub fn new() -> Self { Self::default() } pub fn currency_service(mut self, service: CurrencyService) -> Self { self.currency_service = Some(service); self } pub fn build(self) -> Result { let currency_service = self.currency_service .unwrap_or_else(|| CurrencyService::builder().build().unwrap()); Ok(AutoTopUpService { currency_service, }) } } impl AutoTopUpService { pub fn builder() -> AutoTopUpServiceBuilder { AutoTopUpServiceBuilder::new() } pub async fn check_and_trigger_topup( &self, session: &Session, required_amount: Decimal, ) -> Result { let user_email = session.get::("user_email") .map_err(|e| format!("Failed to get user email: {}", e))? .ok_or("User not authenticated")?; let mut persistent_data = UserPersistence::load_user_data(&user_email) .unwrap_or_default(); // Check if auto top-up is enabled let auto_topup_settings = match &persistent_data.auto_topup_settings { Some(settings) if settings.enabled => settings.clone(), _ => return Ok(false), // Auto top-up not enabled }; // Check if balance is below threshold if persistent_data.wallet_balance >= auto_topup_settings.threshold_amount { return Ok(false); // Balance is sufficient } // Execute auto top-up let transaction_id = Uuid::new_v4().to_string(); persistent_data.wallet_balance += auto_topup_settings.topup_amount; // Create transaction record let transaction = Transaction { id: transaction_id.clone(), user_id: user_email.clone(), transaction_type: crate::models::user::TransactionType::AutoTopUp { triggered_by_purchase: None, threshold_amount: auto_topup_settings.threshold_amount, amount_usd: auto_topup_settings.topup_amount, payment_method: auto_topup_settings.payment_method_id.clone(), }, amount: auto_topup_settings.topup_amount, timestamp: Utc::now(), status: crate::models::user::TransactionStatus::Completed, }; persistent_data.transactions.push(transaction); // Save updated data UserPersistence::save_user_data(&persistent_data) .map_err(|e| format!("Failed to save user data: {}", e))?; Ok(true) } pub fn configure_auto_topup( &self, session: &Session, settings: AutoTopUpSettings, ) -> Result<(), String> { let user_email = session.get::("user_email") .map_err(|e| format!("Failed to get user email: {}", e))? .ok_or("User not authenticated")?; let mut persistent_data = UserPersistence::load_user_data(&user_email) .unwrap_or_default(); persistent_data.auto_topup_settings = Some(settings); UserPersistence::save_user_data(&persistent_data) .map_err(|e| format!("Failed to save user data: {}", e))?; Ok(()) } } impl Default for AutoTopUpService { fn default() -> Self { Self::builder().build().unwrap() } } ``` ### 2.4 Update Services Module **File**: `projectmycelium/src/services/mod.rs` **Add**: ```rust pub mod auto_topup; ``` ### 2.5 Update Transaction Types **File**: `projectmycelium/src/models/user.rs` **Add to TransactionType enum** (around line 1181): ```rust // ADD: New auto top-up transaction type AutoTopUp { triggered_by_purchase: Option, threshold_amount: Decimal, amount_usd: Decimal, payment_method: String }, ``` ## Part 3: Wallet UI Updates ### 3.1 Update Wallet Template **File**: `projectmycelium/src/views/wallet/index.html` **Replace lines 34-35** (page title): ```html

USD Credits Wallet

``` **Replace lines 46-51** (wallet balance display): ```html

{% if wallet_balance %} ${{ wallet_balance | format_decimal(precision=2) }} {% else %} $0.00 {% endif %}

USD Credits ``` **Remove lines 57-72** (USD equivalent card - no longer needed) **Replace lines 114-121** (quick amount buttons): ```html
Direct USD credits purchase ``` **Add after line 127** (auto top-up section): ```html
Auto Top-up (OpenRouter Style)

Automatically purchase credits when your balance gets low

$
$
$
``` **Update JavaScript section** (replace lines 404-439): ```javascript // Update currency selector (remove TFP and EUR options) function updateTopupAmounts() { const currency = document.getElementById('topupCurrency').value; const symbol = '$'; const currencySymbol = document.getElementById('currencySymbol'); const quickAmountButtons = document.getElementById('quickAmountButtons'); const conversionNote = document.getElementById('conversionNote'); currencySymbol.textContent = symbol; // Always show USD amounts quickAmountButtons.innerHTML = ` `; conversionNote.textContent = 'Direct USD credits purchase'; } // Auto top-up settings functions async function saveAutoTopupSettings() { const enabled = document.getElementById('autoTopupEnabled').checked; const thresholdAmount = parseFloat(document.getElementById('thresholdAmount').value); const topupAmount = parseFloat(document.getElementById('topupAmount').value); const paymentMethod = document.getElementById('paymentMethod').value; const dailyLimit = document.getElementById('dailyLimit').value ? parseFloat(document.getElementById('dailyLimit').value) : null; try { const response = await fetch('/api/wallet/auto-topup/configure', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled, threshold_amount: thresholdAmount, topup_amount: topupAmount, payment_method_id: paymentMethod, daily_limit: dailyLimit, monthly_limit: null }) }); const result = await response.json(); if (result.success) { alert('Auto top-up settings saved successfully!'); } else { alert('Failed to save settings: ' + result.message); } } catch (error) { console.error('Auto top-up settings error:', error); alert('Failed to save settings. Please try again.'); } } // Load auto top-up settings on page load async function loadAutoTopupSettings() { try { const response = await fetch('/api/wallet/auto-topup/status'); const result = await response.json(); if (result.settings) { document.getElementById('autoTopupEnabled').checked = result.settings.enabled; document.getElementById('thresholdAmount').value = result.settings.threshold_amount; document.getElementById('topupAmount').value = result.settings.topup_amount; document.getElementById('paymentMethod').value = result.settings.payment_method_id; if (result.settings.daily_limit) { document.getElementById('dailyLimit').value = result.settings.daily_limit; } } } catch (error) { console.error('Failed to load auto top-up settings:', error); } } ``` **Add to DOMContentLoaded event** (around line 498): ```javascript document.addEventListener('DOMContentLoaded', function() { updateTopupAmounts(); loadAutoTopupSettings(); // Load auto top-up settings // ... existing code }); ``` ## Part 4: Buy Now Implementation ### 4.1 Create Buy Now JavaScript **Create**: `projectmycelium/src/static/js/buy-now.js` ```javascript // Buy Now functionality with auto top-up integration class BuyNowManager { constructor() { this.initializeEventHandlers(); } initializeEventHandlers() { document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.buy-now-btn').forEach(button => { button.addEventListener('click', (e) => this.handleBuyNow(e)); }); }); } async handleBuyNow(event) { const button = event.target.closest('.buy-now-btn'); const productId = button.dataset.productId; const productName = button.dataset.productName; const unitPrice = parseFloat(button.dataset.unitPrice); const currency = button.dataset.currency; const category = button.dataset.category || 'general'; // Disable button during processing button.disabled = true; const originalText = button.innerHTML; button.innerHTML = 'Processing...'; try { // Check affordability first const affordabilityResponse = await fetch(`/api/wallet/check-affordability?amount=${unitPrice}`); const affordabilityResult = await affordabilityResponse.json(); if (!affordabilityResult.can_afford) { // Trigger auto top-up if configured const autoTopUpResult = await this.handleInsufficientBalance(affordabilityResult.shortfall_info); if (!autoTopUpResult.success) { this.showError('Insufficient balance and auto top-up failed'); return; } } // Proceed with instant purchase const purchaseResponse = await fetch('/api/wallet/instant-purchase', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ product_id: productId, product_name: productName, product_category: category, quantity: 1, unit_price_tfp: unitPrice, // Note: backend still expects this field name provider_id: 'marketplace', provider_name: 'Project Mycelium' }) }); const purchaseResult = await purchaseResponse.json(); if (purchaseResult.success) { this.showSuccess(`Successfully purchased ${productName}!`); // Update navbar balance if (window.loadNavbarData) { window.loadNavbarData(); } } else { this.showError(purchaseResult.message); } } catch (error) { console.error('Buy Now error:', error); this.showError('Purchase failed. Please try again.'); } finally { // Re-enable button button.disabled = false; button.innerHTML = originalText; } } async handleInsufficientBalance(shortfallInfo) { // Check if auto top-up is configured try { const autoTopUpResponse = await fetch('/api/wallet/auto-topup/status'); const autoTopUpStatus = await autoTopUpResponse.json(); if (autoTopUpStatus.enabled) { // Trigger auto top-up const topUpResponse = await fetch('/api/wallet/auto-topup/trigger', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ required_amount: shortfallInfo.shortfall }) }); return await topUpResponse.json(); } else { // Prompt user to configure auto top-up or manually top up const userChoice = confirm( `Insufficient balance. You need $${shortfallInfo.shortfall.toFixed(2)} more. ` + `Would you like to go to the wallet to add credits?` ); if (userChoice) { window.location.href = '/dashboard/wallet?action=topup'; } return { success: false }; } } catch (error) { console.error('Auto top-up check failed:', error); return { success: false }; } } showSuccess(message) { // Use existing notification system or create toast if (window.showNotification) { window.showNotification(message, 'success'); } else { alert(message); } } showError(message) { if (window.showNotification) { window.showNotification(message, 'error'); } else { alert(message); } } } // Initialize Buy Now manager new BuyNowManager(); ``` ### 4.2 Update Marketplace Templates **File**: `projectmycelium/src/views/marketplace/compute_resources.html` **Add after line 200** (in the action buttons section): ```html
``` **File**: `projectmycelium/src/views/marketplace/applications.html` **Update lines 145-151** (enhance the existing button group with Buy Now): ```html
View Details
``` **File**: `projectmycelium/src/views/marketplace/services.html` **Add Buy Now buttons** (find the existing Add to Cart buttons and enhance with Buy Now): ```html
``` **File**: `projectmycelium/src/views/marketplace/three_nodes.html` **Add Buy Now buttons** (find the existing Add to Cart buttons and enhance with Buy Now): ```html
``` **File**: `projectmycelium/src/views/marketplace/gateways.html` **Add Buy Now buttons** (find the existing Add to Cart buttons and enhance with Buy Now): ```html
``` ### 4.3 Include Buy Now Script in Templates **File**: `projectmycelium/src/views/marketplace/layout.html` **Add before closing `` tag**: ```html ``` ## Part 5: API Endpoints ### 5.1 Add Auto Top-up Endpoints **File**: `projectmycelium/src/controllers/wallet.rs` **Add new endpoints** (after line 900): ```rust /// Configure auto top-up settings pub async fn configure_auto_topup( request: web::Json, session: Session, ) -> Result { let auto_topup_service = crate::services::auto_topup::AutoTopUpService::builder() .build() .map_err(|e| actix_web::error::ErrorInternalServerError(e))?; match auto_topup_service.configure_auto_topup(&session, request.into_inner()) { Ok(()) => Ok(HttpResponse::Ok().json(serde_json::json!({ "success": true, "message": "Auto top-up configured successfully" }))), Err(e) => Ok(HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "message": e }))) } } /// Get auto top-up status pub async fn get_auto_topup_status(session: Session) -> Result { let user_email = session.get::("user_email") .map_err(|e| actix_web::error::ErrorInternalServerError(e))? .ok_or_else(|| actix_web::error::ErrorUnauthorized("User not authenticated"))?; let persistent_data = crate::services::user_persistence::UserPersistence::load_user_data(&user_email) .unwrap_or_default(); let auto_topup_enabled = persistent_data.auto_topup_settings .as_ref() .map(|s| s.enabled) .unwrap_or(false); Ok(HttpResponse::Ok().json(serde_json::json!({ "enabled": auto_topup_enabled, "settings": persistent_data.auto_topup_settings }))) } /// Trigger auto top-up pub async fn trigger_auto_topup( request: web::Json, session: Session, ) -> Result { let auto_topup_service = crate::services::auto_topup::AutoTopUpService::builder() .build() .map_err(|e| actix_web::error::ErrorInternalServerError(e))?; let required_amount = request.get("required_amount") .and_then(|v| v.as_f64()) .map(|f| rust_decimal::Decimal::from_f64_retain(f).unwrap_or_default()) .unwrap_or_default(); match auto_topup_service.check_and_trigger_topup(&session, required_amount).await { Ok(success) => Ok(HttpResponse::Ok().json(serde_json::json!({ "success": success, "message": if success { "Auto top-up completed" } else { "Auto top-up failed" } }))), Err(e) => Ok(HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "message": e }))) } } ``` ### 5.2 Update Routes **File**: `projectmycelium/src/routes/mod.rs` **Add new routes** (after line 208): ```rust // Auto top-up API routes .route("/wallet/auto-topup/configure", web::post().to(WalletController::configure_auto_topup)) .route("/wallet/auto-topup/status", web::get().to(WalletController::get_auto_topup_status)) .route("/wallet/auto-topup/trigger", web::post().to(WalletController::trigger_auto_topup)) ``` ## Part 6: Documentation Updates ### 6.1 Update TFP Documentation **File**: `projectmycelium/src/views/docs/tfp.html` **Replace entire content** with USD Credits documentation: ```html {% extends "docs/layout.html" %} {% block title %}USD Credits - Project Mycelium{% endblock %} {% block docs_content %}

USD Credits

Project Mycelium uses a simple USD credits system for all transactions.

Simple and Intuitive

1 Credit = $1 USD. No complex conversions or confusing terminology.

How Credits Work

  • Direct USD Pricing: All products are priced in clear USD amounts
  • Easy Top-up: Add credits to your wallet with standard payment methods
  • Auto Top-up: Automatically purchase credits when your balance gets low
  • One-Click Purchasing: Buy products instantly with the "Buy Now" button

Auto Top-up

Configure automatic credit purchasing for seamless marketplace experience:

  1. Go to your Wallet
  2. Enable Auto Top-up in the settings section
  3. Set your threshold (e.g., when credits fall below $10)
  4. Set your top-up amount (e.g., purchase $25 when triggered)
  5. Choose your payment method

Versatile Purchase Options

The marketplace offers two convenient ways to purchase products:

  • Buy Now: Instant one-click purchase with automatic balance management and auto top-up integration
  • Add to Cart: Traditional shopping cart experience for purchasing multiple items together
Best of Both Worlds: Use "Buy Now" for quick single purchases, or "Add to Cart" when you want to compare multiple products or make bulk purchases.

Getting Started

  1. Create your Project Mycelium account
  2. Add credits to your wallet
  3. Browse the marketplace
  4. Click "Buy Now" for instant purchases
{% endblock %} ``` ### 6.2 Update Documentation Navigation **File**: `projectmycelium/src/views/docs/layout.html` **Update navigation link** (find the TFP link and replace): ```html USD Credits ``` ### 6.3 Update Getting Started Documentation **File**: `projectmycelium/src/views/docs/getting_started.html` **Update wallet setup section** (find TFP references and replace): ```html

Step 2: Setup Your Wallet

You'll need to add USD credits to your wallet to purchase marketplace products.

  • Navigate to your Wallet
  • Click "Quick Top-Up" to add credits
  • Choose from preset amounts ($10, $25, $50, $100) or enter a custom amount
  • Complete payment with your preferred method
Pro Tip: Enable Auto Top-up to automatically purchase credits when your balance gets low!
``` ### 6.4 Update Route for Documentation **File**: `projectmycelium/src/routes/mod.rs` **Update documentation route** (find the tfp route and update): ```rust .route("/docs/credits", web::get().to(DocsController::credits)) ``` **Add redirect for old TFP documentation**: ```rust .route("/docs/tfp", web::get().to(|| async { HttpResponse::MovedPermanently() .append_header(("Location", "/docs/credits")) .finish() })) ``` ### 6.5 Update Documentation Controller **File**: `projectmycelium/src/controllers/docs.rs` **Add credits method** (replace the tfp method): ```rust /// USD Credits documentation page pub async fn credits(tmpl: web::Data, session: Session) -> Result { let mut ctx = crate::models::builders::ContextBuilder::new() .active_page("docs") .build(); // Add user session data if available if let Ok(Some(user_json)) = session.get::("user") { ctx.insert("user", &user_json); } match tmpl.render("docs/credits.html", &ctx) { Ok(rendered) => Ok(HttpResponse::Ok().content_type("text/html").body(rendered)), Err(e) => { log::error!("Template rendering error: {}", e); Ok(HttpResponse::InternalServerError().body("Template rendering failed")) } } } ``` ## Part 7: Hide Pools Page ### 7.1 Update Navigation **File**: `projectmycelium/src/views/dashboard/layout.html` or main navigation template **Comment out or remove pools navigation link**: ```html ``` ### 7.2 Keep Pools Route as Hidden **File**: `projectmycelium/src/routes/mod.rs` **Comment out main pools route but keep as admin route**: ```rust // HIDE: Main pools route - keep for admin/future use // .route("/dashboard/pools", web::get().to(DashboardController::pools)) // Keep as hidden admin route .route("/dashboard/pools-admin", web::get().to(DashboardController::pools)) ``` ## Part 8: Update Default User Data ### 8.1 Update Default Wallet Balance **File**: `projectmycelium/src/services/user_persistence.rs` **Update Default implementation** (around line 73): ```rust impl Default for UserPersistentData { fn default() -> Self { Self { user_email: String::new(), wallet_balance: Decimal::ZERO, // Start with $0.00 USD credits transactions: Vec::new(), staked_amount: Decimal::ZERO, pool_positions: HashMap::new(), // ... existing fields display_currency: Some("USD".to_string()), // Default to USD quick_topup_amounts: Some(vec![dec!(10), dec!(25), dec!(50), dec!(100)]), // USD amounts auto_topup_settings: None, // User can configure later // ... rest of fields } } } ``` ## Part 9: Implementation Timeline ### Week 1: Foundation (Days 1-7) - **Day 1-2**: Update currency system and mock data - **Day 3-4**: Add auto top-up models and builders - **Day 5-6**: Create auto top-up service - **Day 7**: Update transaction types and test core functionality ### Week 2: API & Backend (Days 8-14) - **Day 8-9**: Implement auto top-up API endpoints - **Day 10-11**: Update routes and test API functionality - **Day 12-13**: Update default user data and persistence - **Day 14**: Backend integration testing ### Week 3: Frontend & UX (Days 15-21) - **Day 15-16**: Update wallet templates and UI - **Day 17-18**: Create and integrate Buy Now JavaScript - **Day 19-20**: Update all marketplace templates with Buy Now buttons - **Day 21**: Frontend integration testing ### Week 4: Documentation & Polish (Days 22-28) - **Day 22-23**: Update documentation and help content - **Day 24-25**: Hide pools page and update navigation - **Day 26-27**: End-to-end testing and bug fixes - **Day 28**: Final polish and deployment preparation ## Part 10: Testing Checklist ### Core Functionality Tests - [ ] Currency system displays USD correctly - [ ] Auto top-up configuration saves and loads - [ ] Auto top-up triggers when balance is low - [ ] Buy Now buttons work on all marketplace pages - [ ] Instant purchase completes successfully - [ ] Wallet balance updates correctly after purchases - [ ] Transaction history shows USD amounts ### User Experience Tests - [ ] New user sees $0.00 balance - [ ] Quick top-up buttons show USD amounts - [ ] Auto top-up UI is intuitive and clear - [ ] Buy Now provides immediate feedback - [ ] Error handling works for insufficient balance - [ ] Documentation is clear and helpful ### Integration Tests - [ ] Buy Now integrates with auto top-up - [ ] Navbar balance updates after purchases - [ ] All marketplace sections have Buy Now buttons - [ ] Documentation links work correctly - [ ] Pools page is hidden from navigation ## Conclusion This implementation plan provides a complete transformation of the Project Mycelium to a clean USD credits system with OpenRouter-style UX. The plan: ✅ **Leverages existing architecture** with builder patterns and service consistency ✅ **Provides file-specific implementation details** with exact line numbers ✅ **Includes complete auto top-up system** with seamless user experience ✅ **Implements one-click Buy Now functionality** across all marketplace sections ✅ **Updates documentation** to reflect the new credits system ✅ **Maintains clean codebase** by hiding rather than removing pools functionality The result will be an intuitive marketplace where users can easily purchase products with clear USD pricing, automatic balance management, and one-click purchasing - exactly matching the OpenRouter experience you envisioned.