Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2217 from ManfredKarrer/list-grin
Add Grin
- Loading branch information
Showing
4 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
106 changes: 106 additions & 0 deletions
106
assets/src/main/java/bisq/asset/GrinAddressValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* 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; | ||
|
||
/** | ||
* The supported "address" (better wallet URL) format is IP:port or the grinbox format. | ||
* | ||
* 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 IPV4 = "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"; | ||
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"); | ||
|
||
if (address.matches("^" + IPV4 + ":" + PORT)) | ||
return AddressValidationResult.validAddress(); | ||
|
||
|
||
// We might have a 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"); | ||
|
||
if (domain != null && !domain.matches("^" + DOMAIN)) | ||
return AddressValidationResult.invalidAddress("Invalid domain"); | ||
|
||
if (port != null && !port.matches("^" + PORT)) | ||
return AddressValidationResult.invalidAddress("Invalid port"); | ||
|
||
return AddressValidationResult.validAddress(); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* 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.coins; | ||
|
||
import bisq.asset.Coin; | ||
import bisq.asset.GrinAddressValidator; | ||
|
||
public class Grin extends Coin { | ||
|
||
public Grin() { | ||
super("Grin", "GRIN", new GrinAddressValidator()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* 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.coins; | ||
|
||
import bisq.asset.AbstractAssetTest; | ||
|
||
import org.junit.Test; | ||
|
||
public class GrinTest extends AbstractAssetTest { | ||
|
||
public GrinTest() { | ||
super(new Grin()); | ||
} | ||
|
||
@Test | ||
public void testValidAddresses() { | ||
assertValidAddress("0.0.0.0:8080"); | ||
assertValidAddress("173.194.34.134:8080"); | ||
assertValidAddress("127.0.0.1:8080"); | ||
assertValidAddress("192.168.0.1:8080"); | ||
assertValidAddress("18.101.25.153:8080"); | ||
assertValidAddress("173.194.34.134:1"); | ||
assertValidAddress("173.194.34.134:11"); | ||
assertValidAddress("173.194.34.134:1111"); | ||
assertValidAddress("173.194.34.134:65535"); | ||
|
||
// 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"); | ||
} | ||
|
||
@Test | ||
public void testInvalidAddresses() { | ||
assertInvalidAddress("google.com"); | ||
assertInvalidAddress("100.100.100.100"); | ||
assertInvalidAddress(".100.100.100.100:1222"); | ||
assertInvalidAddress("100..100.100.100:1222."); | ||
assertInvalidAddress("100.100.100.100.:1222"); | ||
assertInvalidAddress("999.999.999.999:1222"); | ||
assertInvalidAddress("256.256.256.256:1222"); | ||
assertInvalidAddress("256.100.100.100.100:1222"); | ||
assertInvalidAddress("123.123.123:1222"); | ||
assertInvalidAddress("http://123.123.123:1222"); | ||
assertInvalidAddress("1000.2.3.4:1222"); | ||
assertInvalidAddress("999.2.3.4:1222"); | ||
// too large port | ||
assertInvalidAddress("173.194.34.134:65536"); | ||
|
||
assertInvalidAddress("gVvk7rLBg3r3qoWYL3VsREnBbooT7nynxx5HtDvUWCJUaNCnddvY1111"); | ||
assertInvalidAddress("grinbox:/gVtWzX5NTLCBkyNV19QVdnLXue13heAVRD36sfkGD6xpqy7k7e4a"); | ||
assertInvalidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com."); | ||
assertInvalidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com:1220a"); | ||
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsAsomerelay.com"); | ||
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com1220"); | ||
|
||
} | ||
} |