Skip to content

Commit

Permalink
Implement external browser for iOS marketplace
Browse files Browse the repository at this point in the history
move lnurl auth outside the browser
  • Loading branch information
roeierez authored and erdemyerebasmaz committed Oct 8, 2024
1 parent 6f97b29 commit d094d70
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 33 deletions.
28 changes: 28 additions & 0 deletions lib/routes/marketplace/lnurl_auth.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

import 'dart:convert';

import 'package:breez/bloc/lnurl/lnurl_actions.dart';
import 'package:breez/bloc/lnurl/lnurl_bloc.dart';
import 'package:breez/bloc/lnurl/lnurl_model.dart';
import 'package:breez/bloc/marketplace/vendor_model.dart';
import 'package:http/http.dart' as http;

Future<String> handleLNUrlAuth(VendorModel vendor, LNUrlBloc lnurlBloc, String responsdID) async {
Uri uri = Uri.parse(vendor.url);
var response = await http.get(uri);
if (response.statusCode != 200 && response.statusCode != 201) {
throw Exception("Failed to call ${vendor.displayName} API");
}
Map<String, dynamic> decoded = json.decode(response.body);
String lnUrl = decoded[responsdID] as String;
Fetch fetchAction = Fetch(lnUrl);
lnurlBloc.actionsSink.add(fetchAction);
var fetchResponse = await fetchAction.future;
if (fetchResponse.runtimeType != AuthFetchResponse) {
throw "Invalid URL";
}
AuthFetchResponse authResponse = fetchResponse as AuthFetchResponse;
var action = Login(authResponse, jwt: true);
lnurlBloc.actionsSink.add(action);
return await action.future;
}
40 changes: 8 additions & 32 deletions lib/routes/marketplace/lnurl_webview.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import 'dart:convert';

import 'package:breez/bloc/account/account_bloc.dart';
import 'package:breez/bloc/lnurl/lnurl_actions.dart';
import 'package:breez/bloc/lnurl/lnurl_bloc.dart';
import 'package:breez/bloc/lnurl/lnurl_model.dart';
import 'package:breez/bloc/marketplace/vendor_model.dart';
import 'package:breez/routes/marketplace/vendor_webview.dart';
import 'package:breez/widgets/error_dialog.dart';
import 'package:breez/widgets/loader.dart';
import 'package:breez_translations/breez_translations_locales.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'lnurl_auth.dart';

class LNURLWebViewPage extends StatefulWidget {
final AccountBloc accountBloc;
Expand Down Expand Up @@ -41,7 +38,12 @@ class LNURLWebViewPageState extends State<LNURLWebViewPage> {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_handleLNUrlAuth().catchError(
handleLNUrlAuth(widget.vendorModel, widget.lnurlBloc, widget.responseID)
.then((jwt) {
if (mounted) {
setState(() => jwtToken = jwt);
}
}).catchError(
(err) {
final texts = context.texts();

Expand All @@ -56,32 +58,6 @@ class LNURLWebViewPageState extends State<LNURLWebViewPage> {
});
}

Future _handleLNUrlAuth() async {
final texts = context.texts();
Uri uri = widget.endpointURI;
var response = widget.vendorModel.id == "lnmarkets" ? await http.post(uri) : await http.get(uri);
if (response.statusCode != 200 && response.statusCode != 201) {
throw Exception(
texts.lnurl_webview_error_message(widget.vendorModel.displayName),
);
}
Map<String, dynamic> decoded = json.decode(response.body);
String lnUrl = decoded[widget.responseID] as String;
Fetch fetchAction = Fetch(lnUrl);
widget.lnurlBloc.actionsSink.add(fetchAction);
var fetchResponse = await fetchAction.future;
if (fetchResponse.runtimeType != AuthFetchResponse) {
throw texts.lnurl_webview_error_invalid_url;
}
AuthFetchResponse authResponse = fetchResponse as AuthFetchResponse;
var action = Login(authResponse, jwt: true);
widget.lnurlBloc.actionsSink.add(action);
String jwt = await action.future;
if (mounted) {
setState(() => jwtToken = jwt);
}
}

@override
Widget build(BuildContext context) {
if (jwtToken == null) {
Expand Down
31 changes: 30 additions & 1 deletion lib/routes/marketplace/vendor_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import 'package:breez/bloc/account/account_bloc.dart';
import 'package:breez/bloc/blocs_provider.dart';
import 'package:breez/bloc/lnurl/lnurl_bloc.dart';
import 'package:breez/bloc/marketplace/vendor_model.dart';
import 'package:breez/routes/marketplace/lnurl_auth.dart';
import 'package:breez/theme_data.dart' as theme;
import 'package:breez/widgets/error_dialog.dart';
import 'package:breez/widgets/route.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

import 'lnurl_webview.dart';
import 'vendor_webview.dart';
Expand All @@ -17,6 +21,7 @@ class VendorRow extends StatelessWidget {

@override
Widget build(BuildContext context) {
final lnurlBloc = AppBlocsProvider.of<LNUrlBloc>(context);
Color vendorFgColor = theme.vendorTheme[_vendor.id.toLowerCase()]?.iconFgColor ?? Colors.transparent;
Color vendorBgColor = theme.vendorTheme[_vendor.id.toLowerCase()]?.iconBgColor ?? Colors.white;
Color vendorTextColor = theme.vendorTheme[_vendor.id.toLowerCase()]?.textColor ?? Colors.black;
Expand All @@ -42,7 +47,31 @@ class VendorRow extends StatelessWidget {
: Container();

final vendorCard = GestureDetector(
onTap: () {
onTap: () async {

// iOS only
if (defaultTargetPlatform == TargetPlatform.iOS) {
try {
var url = _vendor.url;
if (_vendor.id == "lnmarkets" || _vendor.id == "Kollider") {
var responseID =
_vendor.id == "lnmarkets" ? "lnurl" : "lnurl_auth";
var jwtToken = await handleLNUrlAuth(_vendor, lnurlBloc, responseID);
url = url + "?token=$jwtToken";
}
launch(_vendor.url);
}
catch(err) {
promptError(
context,
"Error",
Text(err.toString())
);
}
return;
}

// non iOS
Navigator.push(context, FadeInRoute(
builder: (_) {
if (_vendor.endpointURI != null) {
Expand Down

0 comments on commit d094d70

Please sign in to comment.