Main coves client
1import 'dart:math';
2import 'dart:typed_data';
3
4import 'package:crypto/crypto.dart' as crypto;
5
6import '../runtime/runtime_implementation.dart';
7import '../utils/lock.dart';
8import 'flutter_key.dart';
9
10/// Flutter implementation of RuntimeImplementation.
11///
12/// Provides cryptographic operations for OAuth flows using:
13/// - pointycastle for EC key generation (via FlutterKey)
14/// - crypto package for SHA hashing
15/// - Random.secure() for cryptographically secure random values
16/// - requestLocalLock for concurrency control
17///
18/// This implementation supports:
19/// - ES256, ES384, ES512, ES256K (Elliptic Curve algorithms)
20/// - SHA-256, SHA-384, SHA-512 (Hash algorithms)
21/// - Secure random number generation
22/// - Local (in-memory) locking for token refresh
23///
24/// Example:
25/// ```dart
26/// final runtime = FlutterRuntime();
27///
28/// // Generate a key
29/// final key = await runtime.createKey(['ES256', 'ES384']);
30///
31/// // Hash some data
32/// final hash = await runtime.digest(
33/// Uint8List.fromList([1, 2, 3]),
34/// DigestAlgorithm.sha256(),
35/// );
36///
37/// // Generate random bytes
38/// final random = await runtime.getRandomValues(32);
39/// ```
40class FlutterRuntime implements RuntimeImplementation {
41 /// Creates a FlutterRuntime instance.
42 const FlutterRuntime();
43
44 @override
45 RuntimeKeyFactory get createKey {
46 return (List<String> algs) async {
47 return FlutterKey.generate(algs);
48 };
49 }
50
51 @override
52 RuntimeDigest get digest {
53 return (Uint8List bytes, DigestAlgorithm algorithm) async {
54 switch (algorithm.name) {
55 case 'sha256':
56 case 'SHA-256':
57 return Uint8List.fromList(crypto.sha256.convert(bytes).bytes);
58
59 case 'sha384':
60 case 'SHA-384':
61 return Uint8List.fromList(crypto.sha384.convert(bytes).bytes);
62
63 case 'sha512':
64 case 'SHA-512':
65 return Uint8List.fromList(crypto.sha512.convert(bytes).bytes);
66
67 default:
68 throw UnsupportedError(
69 'Unsupported digest algorithm: ${algorithm.name}',
70 );
71 }
72 };
73 }
74
75 @override
76 RuntimeRandomValues get getRandomValues {
77 return (int length) async {
78 final random = Random.secure();
79 return Uint8List.fromList(
80 List.generate(length, (_) => random.nextInt(256)),
81 );
82 };
83 }
84
85 @override
86 RuntimeLock get requestLock {
87 // Use the local lock implementation from utils/lock.dart
88 // This prevents concurrent token refresh within a single isolate
89 return requestLocalLock;
90 }
91}