mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 01:41:11 +01:00
Changes required for GRIN re-listing
This commit is contained in:
parent
284eaf2c11
commit
5bf7bba0c6
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.asset;
|
||||
|
||||
/**
|
||||
* We only support the grinbox format as it is currently the only tool which offers a validation options of sender.
|
||||
* Beside that is the IP:port format very insecure with MITM attacks.
|
||||
*
|
||||
* Here is the information from a conversation with the Grinbox developer regarding the Grinbox address format.
|
||||
*
|
||||
A Grinbox address is of the format: grinbox://<key>@domain.com:port where everything besides <key> is optional.
|
||||
If no domain is specified, the default relay grinbox.io will be used.
|
||||
|
||||
The <key> is a base58check encoded value (like in Bitcoin). For Grin mainnet, the first 2 bytes will be [1, 11] and
|
||||
the following 33 bytes should be a valid secp256k1 compressed public key.
|
||||
|
||||
Some examples of valid addresses are:
|
||||
|
||||
gVvRNiuopubvxPrs1BzJdQjVdFAxmkLzMqiVJzUZ7ubznhdtNTGB
|
||||
gVvUcSafSTD3YTSqgNf9ojEYWkz3zMZNfsjdpdb9en5mxc6gmja6
|
||||
gVvk7rLBg3r3qoWYL3VsREnBbooT7nynxx5HtDvUWCJUaNCnddvY
|
||||
grinbox://gVtWzX5NTLCBkyNV19QVdnLXue13heAVRD36sfkGD6xpqy7k7e4a
|
||||
gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com
|
||||
grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com:1220
|
||||
|
||||
Some examples of invalid addresses are:
|
||||
|
||||
gVuBJDKcWkhueMfBLAbFwV4ax55YXPeinWXdRME1Zi3eiC6sFNye (invalid checksum)
|
||||
geWGCMQjxZMHG3EtTaRbR7rH9rE4DsmLfpm1iiZEa7HFKjjkgpf2 (wrong version bytes)
|
||||
gVvddC2jYAfxTxnikcbTEQKLjhJZpqpBg39tXkwAKnD2Pys2mWiK (invalid public key)
|
||||
|
||||
We only add the basic validation without checksum, version byte and pubkey validation as that would require much more
|
||||
effort. Any Grin developer is welcome to add that though!
|
||||
|
||||
*/
|
||||
public class GrinAddressValidator implements AddressValidator {
|
||||
// A Grin Wallet URL (address is not the correct term) can be in the form IP:port or a grinbox format.
|
||||
// The grinbox has the format grinbox://<key>@domain.com:port where everything beside the key is optional.
|
||||
|
||||
|
||||
// Regex for IP validation borrowed from https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
||||
private static final String PORT = "((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$";
|
||||
private static final String DOMAIN = "[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\\.[a-zA-Z]{2,}$";
|
||||
private static final String KEY = "[a-km-zA-HJ-NP-Z1-9]{52}$";
|
||||
|
||||
public GrinAddressValidator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressValidationResult validate(String address) {
|
||||
if (address == null || address.length() == 0)
|
||||
return AddressValidationResult.invalidAddress("Address may not be empty (only Grinbox format is supported)");
|
||||
|
||||
// We only support grinbox address
|
||||
String key;
|
||||
String domain = null;
|
||||
String port = null;
|
||||
address = address.replace("grinbox://", "");
|
||||
if (address.contains("@")) {
|
||||
String[] keyAndDomain = address.split("@");
|
||||
key = keyAndDomain[0];
|
||||
if (keyAndDomain.length > 1) {
|
||||
domain = keyAndDomain[1];
|
||||
if (domain.contains(":")) {
|
||||
String[] domainAndPort = domain.split(":");
|
||||
domain = domainAndPort[0];
|
||||
if (domainAndPort.length > 1)
|
||||
port = domainAndPort[1];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
key = address;
|
||||
}
|
||||
|
||||
if (!key.matches("^" + KEY))
|
||||
return AddressValidationResult.invalidAddress("Invalid key (only Grinbox format is supported)");
|
||||
|
||||
if (domain != null && !domain.matches("^" + DOMAIN))
|
||||
return AddressValidationResult.invalidAddress("Invalid domain (only Grinbox format is supported)");
|
||||
|
||||
if (port != null && !port.matches("^" + PORT))
|
||||
return AddressValidationResult.invalidAddress("Invalid port (only Grinbox format is supported)");
|
||||
|
||||
return AddressValidationResult.validAddress();
|
||||
|
||||
}
|
||||
}
|
@ -17,14 +17,39 @@
|
||||
|
||||
package bisq.asset.coins;
|
||||
|
||||
import bisq.asset.AddressValidationResult;
|
||||
import bisq.asset.AddressValidator;
|
||||
import bisq.asset.AltCoinAccountDisclaimer;
|
||||
import bisq.asset.Coin;
|
||||
import bisq.asset.GrinAddressValidator;
|
||||
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Bech32;
|
||||
|
||||
@AltCoinAccountDisclaimer("account.altcoin.popup.grin.msg")
|
||||
public class Grin extends Coin {
|
||||
|
||||
static String coinName = "Grin";
|
||||
|
||||
public Grin() {
|
||||
super("Grin", "GRIN", new GrinAddressValidator());
|
||||
super(coinName, coinName.toUpperCase(), new GrinAddressValidator());
|
||||
}
|
||||
|
||||
public static class GrinAddressValidator implements AddressValidator {
|
||||
|
||||
@Override
|
||||
public AddressValidationResult validate(String address) {
|
||||
try {
|
||||
Bech32.Bech32Data bechData = Bech32.decode(address);
|
||||
if (!bechData.hrp.equals(coinName.toLowerCase())) {
|
||||
return AddressValidationResult.invalidAddress(String.format("invalid address prefix %x", bechData.hrp));
|
||||
}
|
||||
if (bechData.data.length != 52) {
|
||||
return AddressValidationResult.invalidAddress(String.format("invalid address length %x", bechData.data.length));
|
||||
}
|
||||
return AddressValidationResult.validAddress();
|
||||
} catch (AddressFormatException e) {
|
||||
return AddressValidationResult.invalidStructure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,17 +29,29 @@ public class GrinTest extends AbstractAssetTest {
|
||||
|
||||
@Test
|
||||
public void testValidAddresses() {
|
||||
// grinbox
|
||||
assertValidAddress("gVvk7rLBg3r3qoWYL3VsREnBbooT7nynxx5HtDvUWCJUaNCnddvY");
|
||||
assertValidAddress("grinbox://gVtWzX5NTLCBkyNV19QVdnLXue13heAVRD36sfkGD6xpqy7k7e4a");
|
||||
assertValidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com");
|
||||
assertValidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com:1220");
|
||||
assertValidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com");
|
||||
assertValidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com:1220");
|
||||
// valid slatepack addresses
|
||||
assertValidAddress("grin1ephxt0u33rz9zpl7exer2awfr9s9ae28qsx7908q2zq03uv3sj7suqdule");
|
||||
assertValidAddress("grin1wwg5k80qje0lw32ldttgl52lew0ucmv64zux27pzanl0a2ku85ps5gxafa");
|
||||
assertValidAddress("grin1mdxxaz8g5zc4fhqcvcu79c0sp3md9j2f6tt5cxde78scjatkh3zqzrgl9r");
|
||||
assertValidAddress("grin17whxsfzj3su0rtpd3hkcjt3hlatvc89dpc9syvrmq2shhnhc9f6sehqe3x");
|
||||
assertValidAddress("grin1cq636ment795xn68knzu0ewp73f3zdlgv6dsqv8x7vf2v0j4ek5sk6nmk3");
|
||||
assertValidAddress("grin1wm78wjsf2ws507hea4zqrcywxltjwhtgfrwzhdrr9l80l7tpz5fsj58lk0");
|
||||
assertValidAddress("grin1jezf3lkcexvj3ydjwanan6khs42fr4036guh0c4vkc04fyxarl6svjzuuh");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidAddresses() {
|
||||
// invalid slatepack address (bech32 format invalid)
|
||||
assertInvalidAddress("grin1p4fuklglxqsgg602hu4c4jl4aunu5tynyf4lkg96ezh3jefzpy6swshp5x"); // from 0015-slatepack.md#slatepackaddress
|
||||
|
||||
// grinbox
|
||||
assertInvalidAddress("gVvk7rLBg3r3qoWYL3VsREnBbooT7nynxx5HtDvUWCJUaNCnddvY");
|
||||
assertInvalidAddress("grinbox://gVtWzX5NTLCBkyNV19QVdnLXue13heAVRD36sfkGD6xpqy7k7e4a");
|
||||
assertInvalidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com");
|
||||
assertInvalidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com:1220");
|
||||
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com");
|
||||
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com:1220");
|
||||
|
||||
// valid IP:port addresses but not supported in Bisq
|
||||
assertInvalidAddress("0.0.0.0:8080");
|
||||
assertInvalidAddress("173.194.34.134:8080");
|
||||
|
@ -1729,15 +1729,13 @@ account.altcoin.popup.XZC.msg=When using Zcoin you can only use the transparent
|
||||
the untraceable addresses, because the mediator or arbitrator would not be able to verify the transaction with untraceable addresses at a block explorer.
|
||||
# suppress inspection "UnusedProperty"
|
||||
account.altcoin.popup.grin.msg=GRIN requires an interactive process between the sender and receiver to create the \
|
||||
transaction. Be sure to follow the instructions from the GRIN project web page to reliably send and receive GRIN \
|
||||
(the receiver needs to be online or at least be online during a certain time frame). \n\n\
|
||||
Bisq supports only the Grinbox (Wallet713) wallet URL format. \n\n\
|
||||
transaction. Be sure to follow the instructions from the GRIN project web page [HYPERLINK:https://grin.mw] to reliably send and receive GRIN. \
|
||||
More information on transacting GRIN can be found here [HYPERLINK:https://docs.grin.mw/about-grin/transactions/].\n\n\
|
||||
The GRIN sender is required to provide proof that they have sent GRIN successfully. If the wallet cannot provide that proof, a \
|
||||
potential dispute will be resolved in favor of the GRIN receiver. Please be sure that you use the \
|
||||
latest Grinbox software which supports the transaction proof and that you understand the process of transferring and \
|
||||
latest GRIN software which supports the transaction proof and that you understand the process of transferring and \
|
||||
receiving GRIN as well as how to create the proof. \n\n\
|
||||
See https://github.com/vault713/wallet713/blob/master/docs/usage.md#transaction-proofs-grinbox-only for more \
|
||||
information about the Grinbox proof tool.
|
||||
See [HYPERLINK:https://bisq.wiki/Trading_GRIN] for more information about trading GRIN on Bisq.
|
||||
# suppress inspection "UnusedProperty"
|
||||
account.altcoin.popup.beam.msg=BEAM requires an interactive process between the sender and receiver to create the \
|
||||
transaction. \n\n\
|
||||
|
Loading…
Reference in New Issue
Block a user