diff --git a/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java b/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java new file mode 100644 index 0000000000..22b28523da --- /dev/null +++ b/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java @@ -0,0 +1,55 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.asset; + +/** + * {@link AddressValidator} for Base58-encoded Cryptonote addresses. + * + * @author Chris Beams + * @since 0.7.0 + */ +public class CryptonoteAddressValidator implements AddressValidator { + + private final String prefix; + private final String subAddressPrefix; + private final String validCharactersRegex = "^[1-9A-HJ-NP-Za-km-z]+$"; + + public CryptonoteAddressValidator(String prefix, String subAddressPrefix) { + this.prefix = prefix; + this.subAddressPrefix = subAddressPrefix; + } + + @Override + public AddressValidationResult validate(String address) { + if (!address.matches(validCharactersRegex)) { + // Invalid characters + return AddressValidationResult.invalidStructure(); + } + + if (address.startsWith(prefix) && address.length() == 94 + prefix.length()) { + // Standard address + return AddressValidationResult.validAddress(); + } else if (address.startsWith(subAddressPrefix) && address.length() == 94 + subAddressPrefix.length()) { + // Subaddress + return AddressValidationResult.validAddress(); + } else { + // Integrated? Invalid? Doesn't matter + return AddressValidationResult.invalidStructure(); + } + } +} diff --git a/assets/src/main/java/bisq/asset/coins/Monero.java b/assets/src/main/java/bisq/asset/coins/Monero.java index 477dddd041..17f3c9cb92 100644 --- a/assets/src/main/java/bisq/asset/coins/Monero.java +++ b/assets/src/main/java/bisq/asset/coins/Monero.java @@ -18,11 +18,11 @@ package bisq.asset.coins; import bisq.asset.Coin; -import bisq.asset.DefaultAddressValidator; +import bisq.asset.CryptonoteAddressValidator; public class Monero extends Coin { public Monero() { - super("Monero", "XMR", new DefaultAddressValidator()); + super("Monero", "XMR", new CryptonoteAddressValidator("4", "8")); } } diff --git a/assets/src/test/java/bisq/asset/coins/MoneroTest.java b/assets/src/test/java/bisq/asset/coins/MoneroTest.java index 0136eeea28..0b28aa5ef7 100644 --- a/assets/src/test/java/bisq/asset/coins/MoneroTest.java +++ b/assets/src/test/java/bisq/asset/coins/MoneroTest.java @@ -17,11 +17,28 @@ package bisq.asset.coins; -import bisq.asset.AbstractAssetWithDefaultValidatorTest; +import bisq.asset.AbstractAssetTest; +import org.junit.Test; -public class MoneroTest extends AbstractAssetWithDefaultValidatorTest { +public class MoneroTest extends AbstractAssetTest { public MoneroTest() { super(new Monero()); } + + @Test + public void testValidAddresses() { + assertValidAddress("4BJHitCigGy6giuYsJFP26KGkTKiQDJ6HJP1pan2ir2CCV8Twc2WWmo4fu1NVXt8XLGYAkjo5cJ3yH68Lfz9ZXEUJ9MeqPW"); + assertValidAddress("46tM15KsogEW5MiVmBn7waPF8u8ZsB6aHjJk7BAv1wvMKfWhQ2h2so5BCJ9cRakfPt5BFo452oy3K8UK6L2u2v7aJ3Nf7P2"); + assertValidAddress("86iQTnEqQ9mXJFvBvbY3KU5do5Jh2NCkpTcZsw3TMZ6oKNJhELvAreZFQ1p8EknRRTKPp2vg9fJvy47Q4ARVChjLMuUAFQJ"); + } + + @Test + public void testInvalidAddresses() { + assertInvalidAddress(""); + assertInvalidAddress("4BJHitCigGy6giuYsJFP26KGkTKiQDJ6HJP1pan2ir2CCV8Twc2WWmo4fu1NVXt8XLGYAkjo5cJ3yH68Lfz9ZXEUJ9MeqP"); + assertInvalidAddress("4BJHitCigGy6giuYsJFP26KGkTKiQDJ6HJP1pan2ir2CCV8Twc2WWmo4fu1NVXt8XLGYAkjo5cJ3yH68Lfz9ZXEUJ9MeqPWW"); + assertInvalidAddress("86iQTnEqQ9mXJFvBvbY3KU5do5Jh2NCkpTcZsw3TMZ6oKNJhELvAreZFQ1p8EknRRTKPp2vg9fJvy47Q4ARVChjLMuUAFQ!"); + assertInvalidAddress("76iQTnEqQ9mXJFvBvbY3KU5do5Jh2NCkpTcZsw3TMZ6oKNJhELvAreZFQ1p8EknRRTKPp2vg9fJvy47Q4ARVChjLMuUAFQJ"); + } }