diff --git a/core/src/main/java/com/google/bitcoin/uri/BitcoinURI.java b/core/src/main/java/com/google/bitcoin/uri/BitcoinURI.java
index d158b789..4cfb0a8e 100644
--- a/core/src/main/java/com/google/bitcoin/uri/BitcoinURI.java
+++ b/core/src/main/java/com/google/bitcoin/uri/BitcoinURI.java
@@ -93,7 +93,6 @@ public class BitcoinURI {
private static final String ENCODED_SPACE_CHARACTER = "%20";
private static final String AMPERSAND_SEPARATOR = "&";
private static final String QUESTION_MARK_SEPARATOR = "?";
- private static final String COLON_SEPARATOR = ":";
/**
* Contains all the parameters in the order in which they were processed
@@ -121,12 +120,7 @@ public class BitcoinURI {
Preconditions.checkNotNull(input);
log.debug("Attempting to parse '{}' for {}", input, params == null ? "any" : params.getId());
- // URI validation
- if (!input.startsWith(BITCOIN_SCHEME)) {
- throw new BitcoinURIParseException("Bad scheme - expecting '" + BITCOIN_SCHEME + "'");
- }
-
- // Attempt to form the URI (fail fast syntax checking to official standards)
+ // Attempt to form the URI (fail fast syntax checking to official standards).
URI uri;
try {
uri = new URI(input);
@@ -135,15 +129,21 @@ public class BitcoinURI {
}
// URI is formed as bitcoin:
?
+ // blockchain.info generates URIs of non-BIP compliant form bitcoin://address?....
+ // We support both until Ben fixes his code.
// Remove the bitcoin scheme.
// (Note: getSchemeSpecificPart() is not used as it unescapes the label and parse then fails.
// For instance with : bitcoin:129mVqKUmJ9uwPxKJBnNdABbuaaNfho4Ha?amount=0.06&label=Tom%20%26%20Jerry
// the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed
// as 'Tom ' instead of 'Tom & Jerry')
- String schemeSpecificPart = "";
- if (uri.toString().startsWith(BITCOIN_SCHEME + COLON_SEPARATOR)) {
- schemeSpecificPart = uri.toString().substring(BITCOIN_SCHEME.length() + 1);
+ String schemeSpecificPart;
+ if (input.startsWith("bitcoin://")) {
+ schemeSpecificPart = input.substring("bitcoin://".length());
+ } else if (input.startsWith("bitcoin:")) {
+ schemeSpecificPart = input.substring("bitcoin:".length());
+ } else {
+ throw new BitcoinURIParseException("Unsupported URI scheme: " + uri.getScheme());
}
// Split off the address from the rest of the query parameters.
@@ -311,7 +311,7 @@ public class BitcoinURI {
}
StringBuilder builder = new StringBuilder();
- builder.append(BITCOIN_SCHEME).append(COLON_SEPARATOR).append(address);
+ builder.append(BITCOIN_SCHEME).append(":").append(address);
boolean questionMarkHasBeenOutput = false;
diff --git a/core/src/test/java/com/google/bitcoin/uri/BitcoinURITest.java b/core/src/test/java/com/google/bitcoin/uri/BitcoinURITest.java
index 9653c5d8..28cd2eab 100644
--- a/core/src/test/java/com/google/bitcoin/uri/BitcoinURITest.java
+++ b/core/src/test/java/com/google/bitcoin/uri/BitcoinURITest.java
@@ -111,7 +111,6 @@ public class BitcoinURITest {
testObject = new BitcoinURI(NetworkParameters.prodNet(), "blimpcoin:" + PRODNET_GOOD_ADDRESS);
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
- assertTrue(e.getMessage().contains("Bad scheme"));
}
}
@@ -153,7 +152,6 @@ public class BitcoinURITest {
testObject = new BitcoinURI(NetworkParameters.prodNet(), BitcoinURI.BITCOIN_SCHEME);
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
- assertTrue(e.getMessage().contains("Missing address"));
}
}
@@ -413,4 +411,13 @@ public class BitcoinURITest {
assertTrue(e.getMessage().contains("req-aardvark"));
}
}
+
+ @Test
+ public void brokenURIs() throws BitcoinURIParseException {
+ // Check we can parse the incorrectly formatted URIs produced by blockchain.info and its iPhone app.
+ String str = "bitcoin://1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH?amount=0.01000000";
+ BitcoinURI uri = new BitcoinURI(str);
+ assertEquals("1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH", uri.getAddress().toString());
+ assertEquals(Utils.toNanoCoins(0, 1), uri.getAmount());
+ }
}