From 32b0af73812ccef57b9bfa1889a5ff08a26eda73 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 2 Oct 2020 10:51:50 +0200 Subject: [PATCH] samourai bitcoin uri compatibility --- .../sparrowwallet/drongo/address/Address.java | 66 ++++++++++--------- .../sparrowwallet/drongo/uri/BitcoinURI.java | 2 +- .../drongo/uri/BitcoinUriTest.java | 15 +++++ 3 files changed, 51 insertions(+), 32 deletions(-) create mode 100644 src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java diff --git a/src/main/java/com/sparrowwallet/drongo/address/Address.java b/src/main/java/com/sparrowwallet/drongo/address/Address.java index 9b367cd..0aeecc3 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/Address.java +++ b/src/main/java/com/sparrowwallet/drongo/address/Address.java @@ -84,42 +84,46 @@ public abstract class Address { public static Address fromString(Network network, String address) throws InvalidAddressException { Exception nested = null; - if(address != null && (network.hasP2PKHAddressPrefix(address) || network.hasP2SHAddressPrefix(address))) { - try { - byte[] decodedBytes = Base58.decodeChecked(address); - if(decodedBytes.length == 21) { - int version = Byte.toUnsignedInt(decodedBytes[0]); - byte[] hash = Arrays.copyOfRange(decodedBytes, 1, 21); - if(version == network.getP2PKHAddressHeader()) { - return new P2PKHAddress(hash); - } - if(version == network.getP2SHAddressHeader()) { - return new P2SHAddress(hash); - } - } - } catch (Exception e) { - nested = e; - } - } + if(address != null) { + address = address.toLowerCase(); - if(address != null && address.startsWith(network.getBech32AddressHRP())) { - try { - Bech32.Bech32Data data = Bech32.decode(address); - if(data.hrp.equals(network.getBech32AddressHRP())) { - int witnessVersion = data.data[0]; - if (witnessVersion == 0) { - byte[] convertedProgram = Arrays.copyOfRange(data.data, 1, data.data.length); - byte[] witnessProgram = Bech32.convertBits(convertedProgram, 0, convertedProgram.length, 5, 8, false); - if (witnessProgram.length == 20) { - return new P2WPKHAddress(witnessProgram); + if(network.hasP2PKHAddressPrefix(address) || network.hasP2SHAddressPrefix(address)) { + try { + byte[] decodedBytes = Base58.decodeChecked(address); + if(decodedBytes.length == 21) { + int version = Byte.toUnsignedInt(decodedBytes[0]); + byte[] hash = Arrays.copyOfRange(decodedBytes, 1, 21); + if(version == network.getP2PKHAddressHeader()) { + return new P2PKHAddress(hash); } - if (witnessProgram.length == 32) { - return new P2WSHAddress(witnessProgram); + if(version == network.getP2SHAddressHeader()) { + return new P2SHAddress(hash); } } + } catch (Exception e) { + nested = e; + } + } + + if(address.startsWith(network.getBech32AddressHRP())) { + try { + Bech32.Bech32Data data = Bech32.decode(address); + if(data.hrp.equals(network.getBech32AddressHRP())) { + int witnessVersion = data.data[0]; + if (witnessVersion == 0) { + byte[] convertedProgram = Arrays.copyOfRange(data.data, 1, data.data.length); + byte[] witnessProgram = Bech32.convertBits(convertedProgram, 0, convertedProgram.length, 5, 8, false); + if (witnessProgram.length == 20) { + return new P2WPKHAddress(witnessProgram); + } + if (witnessProgram.length == 32) { + return new P2WSHAddress(witnessProgram); + } + } + } + } catch (Exception e) { + nested = e; } - } catch (Exception e) { - nested = e; } } diff --git a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java index 6ee9bc0..0771696 100644 --- a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java +++ b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java @@ -165,7 +165,7 @@ public class BitcoinURI { if(FIELD_AMOUNT.equals(nameToken) && !valueToken.isEmpty()) { // Decode the amount (contains an optional decimal component to 8dp). try { - long amount = new BigDecimal(valueToken).movePointRight(SMALLEST_UNIT_EXPONENT).longValueExact(); + long amount = new BigDecimal(valueToken.replace(',', '.')).movePointRight(SMALLEST_UNIT_EXPONENT).longValueExact(); if(amount > MAX_BITCOIN * SATOSHIS_PER_BITCOIN) { throw new BitcoinURIParseException("Maximum amount exceeded"); } diff --git a/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java b/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java new file mode 100644 index 0000000..52c6628 --- /dev/null +++ b/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java @@ -0,0 +1,15 @@ +package com.sparrowwallet.drongo.uri; + +import org.junit.Assert; +import org.junit.Test; + +public class BitcoinUriTest { + @Test + public void testSamourai() throws BitcoinURIParseException { + String uri = "bitcoin:BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994?amount=0,001"; + BitcoinURI bitcoinURI = new BitcoinURI(uri); + + Assert.assertEquals("BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994".toLowerCase(), bitcoinURI.getAddress().toString()); + Assert.assertEquals(Long.valueOf(100000), bitcoinURI.getAmount()); + } +}