Craig Raw
3 years ago
9 changed files with 2 additions and 262 deletions
@ -1,2 +0,0 @@ |
|||||
mime-type=x-scheme-handler/aopp |
|
||||
description=Verify Address Ownership URI |
|
@ -1,22 +0,0 @@ |
|||||
package com.sparrowwallet.sparrow.event; |
|
||||
|
|
||||
import com.sparrowwallet.drongo.wallet.Wallet; |
|
||||
import com.sparrowwallet.sparrow.net.Aopp; |
|
||||
|
|
||||
public class ReceiveProofEvent { |
|
||||
private final Wallet wallet; |
|
||||
private final Aopp aopp; |
|
||||
|
|
||||
public ReceiveProofEvent(Wallet wallet, Aopp aopp) { |
|
||||
this.wallet = wallet; |
|
||||
this.aopp = aopp; |
|
||||
} |
|
||||
|
|
||||
public Wallet getWallet() { |
|
||||
return wallet; |
|
||||
} |
|
||||
|
|
||||
public Aopp getAopp() { |
|
||||
return aopp; |
|
||||
} |
|
||||
} |
|
@ -1,167 +0,0 @@ |
|||||
package com.sparrowwallet.sparrow.net; |
|
||||
|
|
||||
import com.google.gson.Gson; |
|
||||
import com.google.gson.GsonBuilder; |
|
||||
import com.sparrowwallet.drongo.address.Address; |
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType; |
|
||||
import com.sparrowwallet.sparrow.AppServices; |
|
||||
import org.slf4j.Logger; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
|
|
||||
import java.io.*; |
|
||||
import java.net.*; |
|
||||
import java.nio.charset.StandardCharsets; |
|
||||
import java.util.LinkedHashMap; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
public class Aopp { |
|
||||
private static final Logger log = LoggerFactory.getLogger(Aopp.class); |
|
||||
|
|
||||
public static final String SCHEME = "aopp"; |
|
||||
|
|
||||
private final int version; |
|
||||
private final String message; |
|
||||
private final ScriptType scriptType; |
|
||||
private final URL callback; |
|
||||
|
|
||||
public Aopp(URI uri) throws MalformedURLException { |
|
||||
if(!uri.getScheme().equals(SCHEME)) { |
|
||||
throw new IllegalArgumentException("Uri " + uri + " does not have the correct scheme"); |
|
||||
} |
|
||||
|
|
||||
Map<String, String> parameterMap = new LinkedHashMap<>(); |
|
||||
String query = uri.getSchemeSpecificPart(); |
|
||||
if(query.startsWith("?")) { |
|
||||
query = query.substring(1); |
|
||||
} |
|
||||
|
|
||||
String[] pairs = query.split("&"); |
|
||||
for(String pair : pairs) { |
|
||||
int idx = pair.indexOf("="); |
|
||||
parameterMap.put(pair.substring(0, idx), pair.substring(idx + 1)); |
|
||||
} |
|
||||
|
|
||||
String strVersion = parameterMap.get("v"); |
|
||||
if(strVersion == null) { |
|
||||
throw new IllegalArgumentException("No version parameter provided"); |
|
||||
} |
|
||||
|
|
||||
version = Integer.parseInt(strVersion); |
|
||||
if(version != 0) { |
|
||||
throw new IllegalArgumentException("Unsupported version number " + version); |
|
||||
} |
|
||||
|
|
||||
String strMessage = parameterMap.get("msg"); |
|
||||
if(strMessage == null) { |
|
||||
throw new IllegalArgumentException("No msg parameter provided"); |
|
||||
} |
|
||||
message = strMessage.replace('+', ' '); |
|
||||
|
|
||||
String asset = parameterMap.get("asset"); |
|
||||
if(asset == null || !asset.equals("btc")) { |
|
||||
throw new IllegalArgumentException("Unsupported asset type " + asset); |
|
||||
} |
|
||||
|
|
||||
String format = parameterMap.get("format"); |
|
||||
if(format == null) { |
|
||||
throw new IllegalArgumentException("No format parameter provided"); |
|
||||
} |
|
||||
if(format.equals("p2sh")) { |
|
||||
format = "p2sh_p2wpkh"; |
|
||||
} |
|
||||
|
|
||||
if(format.equals("any")) { |
|
||||
scriptType = null; |
|
||||
} else { |
|
||||
scriptType = ScriptType.valueOf(format.toUpperCase()); |
|
||||
} |
|
||||
|
|
||||
String callbackUrl = parameterMap.get("callback"); |
|
||||
if(callbackUrl == null) { |
|
||||
throw new IllegalArgumentException("No callback parameter provided"); |
|
||||
} |
|
||||
|
|
||||
callback = new URL(callbackUrl); |
|
||||
} |
|
||||
|
|
||||
public void sendProofOfAddress(Address address, String signature) throws URISyntaxException, IOException, InterruptedException, AoppException { |
|
||||
Proxy proxy = AppServices.getProxy(); |
|
||||
|
|
||||
CallbackRequest callbackRequest = new CallbackRequest(version, address.toString(), signature); |
|
||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create(); |
|
||||
String json = gson.toJson(callbackRequest); |
|
||||
|
|
||||
if(log.isDebugEnabled()) { |
|
||||
log.debug("Sending " + json + " to " + callback); |
|
||||
} |
|
||||
|
|
||||
HttpURLConnection connection = proxy == null ? (HttpURLConnection)callback.openConnection() : (HttpURLConnection)callback.openConnection(proxy); |
|
||||
connection.setRequestMethod("POST"); |
|
||||
connection.setRequestProperty("Content-Type", "application/json"); |
|
||||
connection.setDoOutput(true); |
|
||||
|
|
||||
try(OutputStream os = connection.getOutputStream()) { |
|
||||
byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8); |
|
||||
os.write(jsonBytes); |
|
||||
} |
|
||||
|
|
||||
StringBuilder response = new StringBuilder(); |
|
||||
try(BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { |
|
||||
String responseLine; |
|
||||
while((responseLine = br.readLine()) != null) { |
|
||||
response.append(responseLine.trim()); |
|
||||
} |
|
||||
} |
|
||||
int statusCode = connection.getResponseCode(); |
|
||||
|
|
||||
if(log.isDebugEnabled()) { |
|
||||
log.debug("Received " + statusCode + " " + response); |
|
||||
} |
|
||||
|
|
||||
if(statusCode < 200 || statusCode >= 300) { |
|
||||
throw new AoppException("Could not send proof of ownership. Server returned " + response); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ScriptType getScriptType() { |
|
||||
return scriptType; |
|
||||
} |
|
||||
|
|
||||
public String getMessage() { |
|
||||
return message; |
|
||||
} |
|
||||
|
|
||||
public URL getCallback() { |
|
||||
return callback; |
|
||||
} |
|
||||
|
|
||||
private static class CallbackRequest { |
|
||||
public CallbackRequest(int version, String address, String signature) { |
|
||||
this.version = version; |
|
||||
this.address = address; |
|
||||
this.signature = signature; |
|
||||
} |
|
||||
|
|
||||
public int version; |
|
||||
public String address; |
|
||||
public String signature; |
|
||||
} |
|
||||
|
|
||||
public static final class AoppException extends Exception { |
|
||||
public AoppException(String message) { |
|
||||
super(message); |
|
||||
} |
|
||||
|
|
||||
public AoppException(String message, Throwable cause) { |
|
||||
super(message, cause); |
|
||||
} |
|
||||
|
|
||||
public AoppException(Throwable cause) { |
|
||||
super(cause); |
|
||||
} |
|
||||
|
|
||||
public AoppException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
|
||||
super(message, cause, enableSuppression, writableStackTrace); |
|
||||
} |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue