Skip to content

Commit

Permalink
Remove prefix from QR code scans (#121)
Browse files Browse the repository at this point in the history
* Remove prefix from QR code scans

* Remove query parameters from address and parse amount

Did not modify PaymentUriInfo to avoid issues with segwit variants
  • Loading branch information
takenagain authored Apr 4, 2024
1 parent 571a223 commit 3dffc55
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ class _AmountAddressStepState extends State<AmountAddressStep> {
widget.addressController.text = address;
}

set qrAmount(String amount) {
widget.amountController.text = amount;
}

void showWrongCoinDialog(PaymentUriInfo uriInfo) {
dialogBloc.dialog = showDialog<void>(
context: context,
Expand Down Expand Up @@ -301,15 +305,17 @@ class _AmountAddressStepState extends State<AmountAddressStep> {
barcode = 'Error';
});
} else {
final address = result;
final uri = Uri.tryParse(address.trim());
final String address = getAddressFromUri(result.trim());
final String amount = getParameterValue(result.trim(), 'amount');
final Uri uri = Uri.tryParse(result.trim());

setState(() {
final PaymentUriInfo uriInfo = PaymentUriInfo.fromUri(uri);
if (uriInfo != null) {
handlePaymentData(uriInfo);
} else {
handleQrAdress(address);
qrAmount = amount ?? '';
}
});
}
Expand Down
29 changes: 29 additions & 0 deletions lib/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,35 @@ class PaymentUriInfo {
final String amount;
}

/// Returns the value of a [parameter] from the [address].
/// Returns null if the [parameter] is not found.
/// [address] is expected to be a blockchain address or URL with parameters,
/// e.g. '?amount=123'
///
/// Example usage:
/// ```dart
/// getParameterValue('litecoin:NPZcaiggQTy6uxL?amount=0.2', 'amount') == '0.2'
/// ```
String getParameterValue(String address, String parameter) {
final RegExp regExp = RegExp('(?<=$parameter=)(.*?)(?=&|\$)');
final RegExpMatch match = regExp.firstMatch(address);
return match?.group(0);
}

/// Returns the address from the [uri].
/// Returns the [uri] if no address is found.
/// [uri] is expected to be a blockchain address or URL with parameters,
/// e.g. '?amount=123'
/// Example usage:
/// ```dart
/// getAddressFromUri('litecoin:NPZcaiggQTy6uxL?amount=0.2') == 'NPZcaiggQTy6uxL'
/// ```
String getAddressFromUri(String uri) {
final RegExp regExp = RegExp(r'(?<=:)(.*?)(?=\?|$)');
final RegExpMatch match = regExp.firstMatch(uri);
return match?.group(0) ?? uri.split(':').last;
}

void showUriDetailsDialog(
BuildContext context, PaymentUriInfo uriInfo, Function callbackIfAccepted) {
if (uriInfo == null) return;
Expand Down
50 changes: 50 additions & 0 deletions test/utils/utils_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:komodo_dex/model/coin.dart';
import 'package:komodo_dex/utils/utils.dart';

void main() {
group('removeBlockchainPrefix', () {
test('removes blockchain prefix from address', () {
const String address = 'eth:0x1234567890abcdef';
final String result = getAddressFromUri(address);
expect(result, '0x1234567890abcdef');
});

test('removes blackcoin prefix from address', () {
const String address = 'blackcoin:B8Q9aZ4Mz1ZwWYaknJdZ8t3Z6z9F3Fz1Zz';
final String result = getAddressFromUri(address);
expect(result, 'B8Q9aZ4Mz1ZwWYaknJdZ8t3Z6z9F3Fz1Zz');
});

test('returns the same address if no prefix is present', () {
const String address = '0x1234567890abcdef';
final String result = getAddressFromUri(address);
expect(result, '0x1234567890abcdef');
});
});

group('getParameterValue', () {
test('returns the parameter value from the address', () {
const String address =
'eth:0x1234567890abcdef?param1=value1&param2=value2';
const String parameter = 'param1';
final String result = getParameterValue(address, parameter);
expect(result, 'value1');
});

test('returns null if the parameter is not present in the address', () {
const String address =
'eth:0x1234567890abcdef?param1=value1&param2=value2';
const String parameter = 'param3';
final String result = getParameterValue(address, parameter);
expect(result, isNull);
});

test('returns null if the address does not contain any parameters', () {
const String address = 'eth:0x1234567890abcdef';
const String parameter = 'param1';
final String result = getParameterValue(address, parameter);
expect(result, isNull);
});
});
}

0 comments on commit 3dffc55

Please sign in to comment.