diff --git a/lib/config/config.dart b/lib/config/config.dart index 10439237..6ec29be8 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -1,7 +1,13 @@ import 'package:didpay/features/pfis/pfi.dart'; class Config { - static const List devPfis = []; + static List devPfis = [ + Pfi( + id: '1', + name: 'DID PFI 1', + didUri: 'did:web:localhost%3A8892:ingress', + ), + ]; static const pfisJsonUrl = 'https://raw.githubusercontent.com/TBD54566975/pfi-providers-data/main/pfis.json'; } diff --git a/lib/features/pfis/pfi_verification_page.dart b/lib/features/pfis/pfi_verification_page.dart index dc1fb758..1d0b80f4 100644 --- a/lib/features/pfis/pfi_verification_page.dart +++ b/lib/features/pfis/pfi_verification_page.dart @@ -1,3 +1,4 @@ +import 'package:didpay/services/service_providers.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:didpay/features/pfis/pfi.dart'; import 'package:didpay/features/pfis/pfi_confirmation_page.dart'; @@ -13,9 +14,6 @@ class PfiVerificationPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - const proof = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'; - final controller = WebViewController() ..setBackgroundColor(Theme.of(context).colorScheme.background) ..setNavigationDelegate( @@ -38,9 +36,9 @@ class PfiVerificationPage extends HookConsumerWidget { useEffect(() { Future.microtask(() async { - final result = await DidDht.resolve(pfi.didUri); - final widgetService = result.didDocument?.service - ?.firstWhere((e) => e.type == 'kyc-widget'); + final result = await DidWeb.resolve(pfi.didUri); + final widgetService = + result.didDocument?.service?.firstWhere((e) => e.type == 'IDV'); if (widgetService?.serviceEndpoint == null) { final snackBar = SnackBar( content: const Text('PFI does not support KYC widget'), @@ -53,9 +51,11 @@ class PfiVerificationPage extends HookConsumerWidget { return; } - final fullPath = - '${widgetService?.serviceEndpoint}?proof=$proof&callback_uri=didpay://kyc'; + final idvWidgetUrl = await ref + .read(idvServiceProvider) + .getWidgetUrl('http://${widgetService?.serviceEndpoint}'); + final fullPath = '$idvWidgetUrl&callback_uri=didpay://kyc'; controller.loadRequest(Uri.parse(fullPath)); }); diff --git a/lib/features/pfis/pfis_notifier.dart b/lib/features/pfis/pfis_notifier.dart index 27b0bc88..2bf366eb 100644 --- a/lib/features/pfis/pfis_notifier.dart +++ b/lib/features/pfis/pfis_notifier.dart @@ -19,7 +19,7 @@ class PfisAsyncNotifier extends AsyncNotifier> { Future reload() async { if (Config.devPfis.isNotEmpty) { - state = const AsyncData(Config.devPfis); + state = AsyncData(Config.devPfis); return; } diff --git a/lib/services/idv_service.dart b/lib/services/idv_service.dart new file mode 100644 index 00000000..a6955c28 --- /dev/null +++ b/lib/services/idv_service.dart @@ -0,0 +1,35 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:web5_flutter/web5_flutter.dart'; + +class IdvService { + Future getWidgetUrl(String idvAuthRequestUrl) async { + final response = await http.get(Uri.parse(idvAuthRequestUrl)); + if (response.statusCode != 200) { + throw Exception('Failed to load auth request'); + } + + // Parse the URI string so we can extract the query parameters + Uri fakeUri = Uri.parse('https://example.com/?${response.body}'); + final request = fakeUri.queryParameters['request']; + + if (request == null) { + throw Exception('Request not found'); + } + + final jwtParts = request.split('.'); + final encodedClaims = jwtParts[1]; + + Map decoded = json.fromBase64Url(encodedClaims); + final responseUri = decoded['response_uri']; + + final idvResponse = await http.post(Uri.parse(responseUri), + body: json.encode({ + 'id_token': '123', + })); + + Map decodedIdvResponse = json.decode(idvResponse.body); + return decodedIdvResponse['url']; + } +} diff --git a/lib/services/service_providers.dart b/lib/services/service_providers.dart index 6932d487..b0ad24aa 100644 --- a/lib/services/service_providers.dart +++ b/lib/services/service_providers.dart @@ -1,3 +1,4 @@ +import 'package:didpay/services/idv_service.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -7,3 +8,5 @@ final secureStorageProvider = final sharedPreferencesProvider = Provider((ref) => throw UnimplementedError()); + +final idvServiceProvider = Provider((ref) => IdvService()); diff --git a/pubspec.lock b/pubspec.lock index be63ad1d..5b27c2d5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -106,10 +106,10 @@ packages: dependency: "direct main" description: name: flutter_hooks - sha256: "09f64db63fee3b2ab8b9038a1346be7d8986977fae3fec601275bf32455ccfc0" + sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70 url: "https://pub.dev" source: hosted - version: "0.20.4" + version: "0.20.5" flutter_lints: dependency: "direct dev" description: @@ -127,10 +127,10 @@ packages: dependency: transitive description: name: flutter_riverpod - sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5 + sha256: "4bce556b7ecbfea26109638d5237684538d4abc509d253e6c5c4c5733b360098" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.10" flutter_secure_storage: dependency: "direct main" description: @@ -193,18 +193,18 @@ packages: dependency: "direct main" description: name: hooks_riverpod - sha256: c12a456e03ef9be65b0be66963596650ad7a3220e96c7e7b0a048562ea32d6ae + sha256: "758b07eba336e3cbacbd81dba481f2228a14102083fdde07045e8514e8054c49" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.10" http: dependency: "direct main" description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_parser: dependency: transitive description: @@ -265,10 +265,10 @@ packages: dependency: "direct dev" description: name: mocktail - sha256: f603ebd85a576e5914870b02e5839fc5d0243b867bf710651cf239a28ebb365e + sha256: c4b5007d91ca4f67256e720cb1b6d704e79a510183a12fa551021f652577dce6 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.3" path: dependency: transitive description: @@ -281,10 +281,10 @@ packages: dependency: transitive description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: @@ -297,10 +297,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -313,10 +313,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -345,18 +345,18 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" riverpod: dependency: transitive description: name: riverpod - sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11" + sha256: "548e2192eb7aeb826eb89387f814edb76594f3363e2c0bb99dd733d795ba3589" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.0" shared_preferences: dependency: "direct main" description: @@ -503,7 +503,7 @@ packages: description: path: "packages/web5" ref: main - resolved-ref: d42e7f746111f2aa98350f59508793531664ddff + resolved-ref: "0e9de93e2b7398828b269a191d119e133dfeac39" url: "https://github.com/TBD54566975/web5-dart.git" source: git version: "0.1.0" @@ -512,7 +512,7 @@ packages: description: path: "packages/web5_flutter" ref: main - resolved-ref: d42e7f746111f2aa98350f59508793531664ddff + resolved-ref: "0e9de93e2b7398828b269a191d119e133dfeac39" url: "https://github.com/TBD54566975/web5-dart.git" source: git version: "0.1.0" @@ -520,34 +520,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: "60e23976834e995c404c0b21d3b9db37ecd77d3303ef74f8b8d7a7b19947fc04" + sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413 url: "https://pub.dev" source: hosted - version: "4.4.3" + version: "4.5.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96" + sha256: "3e5f4e9d818086b0d01a66fb1ff9cc72ab0cc58c71980e3d3661c5685ea0efb0" url: "https://pub.dev" source: hosted - version: "3.13.2" + version: "3.15.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943 + sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "02d8f3ebbc842704b2b662377b3ee11c0f8f1bbaa8eab6398262f40049819160" + sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c" url: "https://pub.dev" source: hosted - version: "3.10.1" + version: "3.10.2" win32: dependency: transitive description: