:drunk: Werid miniapp runtime
This commit is contained in:
336
packages/miniapp-example/BUILD_GUIDE.md
Normal file
336
packages/miniapp-example/BUILD_GUIDE.md
Normal file
@@ -0,0 +1,336 @@
|
||||
# Mini-App Example: Building for Production
|
||||
|
||||
This guide shows how to build and deploy the Payment Demo mini-app.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Flutter SDK installed
|
||||
- flutter_eval package installed
|
||||
- Access to the PluginRegistry in your main app
|
||||
|
||||
## Development
|
||||
|
||||
### Running the Example
|
||||
|
||||
Run the example app directly:
|
||||
|
||||
```bash
|
||||
cd packages/miniapp-example
|
||||
flutter run
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
Run the test suite:
|
||||
|
||||
```bash
|
||||
flutter test
|
||||
```
|
||||
|
||||
## Building for Production
|
||||
|
||||
### Step 1: Compile to Bytecode
|
||||
|
||||
Use flutter_eval to compile the mini-app to bytecode (.evc file):
|
||||
|
||||
```bash
|
||||
cd packages/miniapp-example
|
||||
flutter pub get
|
||||
dart run flutter_eval:compile -i lib/main.dart -o payment_demo.evc
|
||||
```
|
||||
|
||||
This will create `payment_demo.evc` in the current directory.
|
||||
|
||||
### Step 2: Upload to Server
|
||||
|
||||
Upload the `.evc` file to your server:
|
||||
|
||||
```bash
|
||||
# Example: Upload to your mini-apps server
|
||||
curl -X POST https://your-server.com/api/mini-apps/upload \
|
||||
-F "file=@payment_demo.evc" \
|
||||
-F "metadata={\"name\":\"Payment Demo\",\"version\":\"1.0.0\",\"description\":\"Example payment mini-app\"}"
|
||||
```
|
||||
|
||||
### Step 3: Configure Server Metadata
|
||||
|
||||
Ensure your server returns the mini-app metadata in the correct format:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "payment-demo",
|
||||
"name": "Payment Demo",
|
||||
"version": "1.0.0",
|
||||
"description": "Example payment mini-app",
|
||||
"download_url": "https://your-server.com/mini-apps/payment-demo.evc",
|
||||
"checksum": "sha256:abc123...",
|
||||
"size": 12345,
|
||||
"min_host_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with Main App
|
||||
|
||||
### Load the Mini-App
|
||||
|
||||
Use the PluginRegistry to load and run the mini-app:
|
||||
|
||||
```dart
|
||||
import 'package:island/modular/registry.dart';
|
||||
import 'package:island/pods/plugin_registry.dart';
|
||||
|
||||
// Get the registry
|
||||
final registry = ref.read(pluginRegistryProvider.notifier);
|
||||
|
||||
// Load the mini-app from server
|
||||
final miniApp = await registry.loadMiniApp(
|
||||
'https://your-server.com/mini-apps/payment-demo.evc',
|
||||
);
|
||||
|
||||
// Enable the mini-app
|
||||
await registry.enablePlugin(miniApp.id);
|
||||
|
||||
// Launch the mini-app
|
||||
await registry.launchMiniApp(context, miniApp.id);
|
||||
```
|
||||
|
||||
### Provide PaymentAPI to Mini-App
|
||||
|
||||
Ensure the PaymentAPI is available to the mini-app through the eval bridge:
|
||||
|
||||
```dart
|
||||
import 'package:island/modular/api/payment.dart';
|
||||
|
||||
// When loading the mini-app, register the PaymentAPI
|
||||
final registry = PluginRegistry();
|
||||
|
||||
// Register PaymentAPI with the eval bridge
|
||||
registry.registerBridge('PaymentAPI', PaymentAPI.instance);
|
||||
```
|
||||
|
||||
## Mini-App Development Guide
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
packages/miniapp-example/
|
||||
├── lib/
|
||||
│ ├── main.dart # Main mini-app entry point
|
||||
│ └── payment_api.dart # PaymentAPI interface (for reference)
|
||||
├── test/
|
||||
│ └── main_test.dart # Widget tests
|
||||
├── pubspec.yaml # Package configuration
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
### Key Files
|
||||
|
||||
#### `lib/main.dart`
|
||||
- Contains the main mini-app widget
|
||||
- Implements the UI for testing PaymentAPI
|
||||
- Can be run standalone or compiled to bytecode
|
||||
|
||||
#### `lib/payment_api.dart`
|
||||
- Shows the PaymentAPI interface
|
||||
- Used as a reference for API usage
|
||||
- Not compiled into the final .evc file
|
||||
|
||||
### Writing Your Own Mini-App
|
||||
|
||||
1. Create a new Flutter package:
|
||||
|
||||
```bash
|
||||
mkdir packages/my-miniapp
|
||||
cd packages/my-miniapp
|
||||
flutter create --org com.example my_miniapp
|
||||
```
|
||||
|
||||
2. Add flutter_eval to `pubspec.yaml`:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_eval: ^0.8.2
|
||||
```
|
||||
|
||||
3. Write your mini-app in `lib/main.dart`
|
||||
4. Test with `flutter test`
|
||||
5. Compile to `.evc`:
|
||||
|
||||
```bash
|
||||
dart run flutter_eval:compile -i lib/main.dart -o my_miniapp.evc
|
||||
```
|
||||
|
||||
## API Usage Examples
|
||||
|
||||
### Creating an Order
|
||||
|
||||
```dart
|
||||
final paymentApi = PaymentAPI.instance;
|
||||
|
||||
final order = await paymentApi.createOrder(
|
||||
CreateOrderRequest(
|
||||
amount: 19.99,
|
||||
currency: 'USD',
|
||||
description: 'Premium subscription',
|
||||
metadata: {'plan': 'premium', 'duration': '1m'},
|
||||
),
|
||||
);
|
||||
|
||||
print('Order created: ${order.orderId}');
|
||||
```
|
||||
|
||||
### Processing Payment with Overlay
|
||||
|
||||
```dart
|
||||
final result = await paymentApi.processPaymentWithOverlay(
|
||||
orderId: order.orderId,
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
print('Payment successful: ${result.transactionId}');
|
||||
// Navigate to success screen
|
||||
} else {
|
||||
print('Payment failed: ${result.errorMessage}');
|
||||
// Show error to user
|
||||
}
|
||||
```
|
||||
|
||||
### Processing Direct Payment
|
||||
|
||||
```dart
|
||||
final result = await paymentApi.processDirectPayment(
|
||||
orderId: order.orderId,
|
||||
paymentMethod: 'credit_card',
|
||||
paymentToken: 'tok_abc123',
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
print('Payment successful: ${result.transactionId}');
|
||||
} else {
|
||||
print('Payment failed: ${result.errorMessage}');
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
Test business logic and API interactions:
|
||||
|
||||
```dart
|
||||
test('should create order with correct amount', () {
|
||||
final request = CreateOrderRequest(
|
||||
amount: 19.99,
|
||||
currency: 'USD',
|
||||
description: 'Test order',
|
||||
);
|
||||
|
||||
expect(request.amount, 19.99);
|
||||
expect(request.currency, 'USD');
|
||||
});
|
||||
```
|
||||
|
||||
### Widget Tests
|
||||
Test UI components:
|
||||
|
||||
```bash
|
||||
flutter test test/main_test.dart
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
Test the mini-app with the eval bridge:
|
||||
|
||||
```dart
|
||||
testWidgets('should process payment through eval bridge', (tester) async {
|
||||
// Setup eval bridge
|
||||
final eval = EvalCompiler();
|
||||
eval.addPlugin(PaymentAPIPlugin());
|
||||
|
||||
// Load mini-app
|
||||
final program = eval.compile(await File('main.dart').readAsString());
|
||||
|
||||
// Run mini-app
|
||||
await tester.pumpWidget(program.build());
|
||||
|
||||
// Test payment flow
|
||||
await tester.tap(find.text('Pay with Overlay'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Payment successful!'), findsOneWidget);
|
||||
});
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Compilation Errors
|
||||
|
||||
**Error**: `Method not found in eval bridge`
|
||||
**Solution**: Ensure PaymentAPI is registered with the eval bridge before loading the mini-app.
|
||||
|
||||
**Error**: `Permission denied` when accessing storage
|
||||
**Solution**: Add the following to `AndroidManifest.xml` (Android):
|
||||
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
```
|
||||
|
||||
And `Info.plist` (iOS):
|
||||
|
||||
```xml
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need access to save payment receipts</string>
|
||||
```
|
||||
|
||||
### Runtime Errors
|
||||
|
||||
**Error**: `PaymentAPI.instance is null`
|
||||
**Solution**: Ensure PaymentAPI is initialized before the mini-app starts.
|
||||
|
||||
**Error**: `Network timeout`
|
||||
**Solution**: Increase timeout in PaymentAPI configuration or check network connectivity.
|
||||
|
||||
### Testing Errors
|
||||
|
||||
**Error**: `Widget not found`
|
||||
**Solution**: Ensure you're pumping the widget tree with `await tester.pump()` after state changes.
|
||||
|
||||
**Error**: `Multiple widgets found`
|
||||
**Solution**: Use more specific finders or add keys to widgets.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Keep Mini-Apps Small**: Mini-apps should be focused and lightweight
|
||||
2. **Handle Errors Gracefully**: Always wrap API calls in try-catch blocks
|
||||
3. **Show Loading States**: Provide feedback for long-running operations
|
||||
4. **Test Thoroughly**: Write comprehensive tests for all user flows
|
||||
5. **Version Management**: Include version information in metadata
|
||||
6. **Security**: Never store sensitive data in the mini-app
|
||||
7. **Network Handling**: Implement retry logic for network failures
|
||||
8. **User Feedback**: Always show success/error messages to users
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. **Lazy Loading**: Load resources only when needed
|
||||
2. **Image Optimization**: Compress images before including in mini-app
|
||||
3. **Code Splitting**: Split large mini-apps into smaller modules
|
||||
4. **Caching**: Cache API responses to reduce network calls
|
||||
5. **Debouncing**: Debounce user inputs to reduce API calls
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Input Validation**: Always validate user inputs
|
||||
2. **API Keys**: Never include API keys in the mini-app code
|
||||
3. **HTTPS Only**: Always use HTTPS for API calls
|
||||
4. **Data Encryption**: Encrypt sensitive data stored locally
|
||||
5. **Permissions**: Request minimum necessary permissions
|
||||
6. **Updates**: Always update to the latest version of dependencies
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
1. Check the main README in `lib/modular/README.md`
|
||||
2. Review PaymentAPI documentation in `lib/modular/api/README.md`
|
||||
3. Check test examples in `test/main_test.dart`
|
||||
4. Review the PaymentAPI interface in `lib/payment_api.dart`
|
||||
Reference in New Issue
Block a user