Add support for addresses with integrated payment ID

This commit is contained in:
chimp1984 2020-09-02 20:29:19 -05:00
parent bf73ffcfa6
commit 86821277d9
No known key found for this signature in database
GPG key ID: 9801B4EC591F90E3
2 changed files with 26 additions and 8 deletions

View file

@ -28,22 +28,38 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
public class CryptoNoteUtils { public class CryptoNoteUtils {
public static String convertToRawHex(String address) { public static String getRawSpendKeyAndViewKey(String address) throws CryptoNoteUtils.CryptoNoteException {
try { try {
byte[] decoded = MoneroBase58.decode(address); // See https://monerodocs.org/public-address/standard-address/
// omit the type (1st byte) and checksum (last 4 byte) byte[] decoded = CryptoNoteUtils.MoneroBase58.decode(address);
byte[] slice = Arrays.copyOfRange(decoded, 1, decoded.length - 4); // Standard addresses are of length 69 and addresses with integrated payment ID of length 77.
if (decoded.length <= 65) {
throw new CryptoNoteUtils.CryptoNoteException("The address we received is too short. address=" + address);
}
// If the length is not as expected but still can be truncated we log an error and continue.
if (decoded.length != 69 && decoded.length != 77) {
System.out.println("The address we received is not in the expected format. address=" + address);
}
// We remove the network type byte, the checksum (4 bytes) and optionally the payment ID (8 bytes if present)
// So extract the 64 bytes after the first byte, which are the 32 byte public spend key + the 32 byte public view key
byte[] slice = Arrays.copyOfRange(decoded, 1, 65);
return Utils.HEX.encode(slice); return Utils.HEX.encode(slice);
} catch (CryptoNoteException e) { } catch (CryptoNoteUtils.CryptoNoteException e) {
e.printStackTrace(); throw new CryptoNoteUtils.CryptoNoteException(e);
} }
return null;
} }
public static class CryptoNoteException extends Exception { public static class CryptoNoteException extends Exception {
CryptoNoteException(String msg) { CryptoNoteException(String msg) {
super(msg); super(msg);
} }
public CryptoNoteException(CryptoNoteException exception) {
super(exception);
}
} }
static class Keccak { static class Keccak {

View file

@ -74,7 +74,7 @@ public class XmrTxProofParser implements AssetTxProofParser<XmrTxProofRequest.Re
if (jsonAddress == null) { if (jsonAddress == null) {
return XmrTxProofRequest.Result.ERROR.with(XmrTxProofRequest.Detail.API_INVALID.error("Missing address field")); return XmrTxProofRequest.Result.ERROR.with(XmrTxProofRequest.Detail.API_INVALID.error("Missing address field"));
} else { } else {
String expectedAddressHex = CryptoNoteUtils.convertToRawHex(model.getRecipientAddress()); String expectedAddressHex = CryptoNoteUtils.getRawSpendKeyAndViewKey(model.getRecipientAddress());
if (!jsonAddress.getAsString().equalsIgnoreCase(expectedAddressHex)) { if (!jsonAddress.getAsString().equalsIgnoreCase(expectedAddressHex)) {
log.warn("Address from json result (convertToRawHex):\n{}\nExpected (convertToRawHex):\n{}\nRecipient address:\n{}", log.warn("Address from json result (convertToRawHex):\n{}\nExpected (convertToRawHex):\n{}\nRecipient address:\n{}",
jsonAddress.getAsString(), expectedAddressHex, model.getRecipientAddress()); jsonAddress.getAsString(), expectedAddressHex, model.getRecipientAddress());
@ -167,6 +167,8 @@ public class XmrTxProofParser implements AssetTxProofParser<XmrTxProofRequest.Re
} catch (JsonParseException | NullPointerException e) { } catch (JsonParseException | NullPointerException e) {
return XmrTxProofRequest.Result.ERROR.with(XmrTxProofRequest.Detail.API_INVALID.error(e.toString())); return XmrTxProofRequest.Result.ERROR.with(XmrTxProofRequest.Detail.API_INVALID.error(e.toString()));
} catch (CryptoNoteUtils.CryptoNoteException e) {
return XmrTxProofRequest.Result.ERROR.with(XmrTxProofRequest.Detail.ADDRESS_INVALID.error(e.toString()));
} }
} }
} }