mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-11-30 16:36:36 -05:00
support Solana (SOL)
This commit is contained in:
parent
0dc67f06c4
commit
b0446c637f
7 changed files with 174 additions and 0 deletions
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* This file is part of Haveno.
|
||||
*
|
||||
* Haveno 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.
|
||||
*
|
||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package haveno.asset;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Validates a Solana address.
|
||||
*/
|
||||
public class SolanaAddressValidator implements AddressValidator {
|
||||
|
||||
private static final String BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
public SolanaAddressValidator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressValidationResult validate(String address) {
|
||||
if (!isValidSolanaAddress(address)) {
|
||||
return AddressValidationResult.invalidStructure();
|
||||
}
|
||||
return AddressValidationResult.validAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given address is a valid Solana address.
|
||||
*
|
||||
* This code is AI-generated and has been tested with a variety of addresses.
|
||||
*
|
||||
* @param addr the address to validate
|
||||
* @return true if the address is valid, false otherwise
|
||||
*/
|
||||
private static boolean isValidSolanaAddress(String address) {
|
||||
if (address == null) return false;
|
||||
if (address.length() < 32 || address.length() > 44) return false; // typical Solana length range
|
||||
|
||||
// Check all chars are base58 valid
|
||||
for (char c : address.toCharArray()) {
|
||||
if (BASE58_ALPHABET.indexOf(c) == -1) return false;
|
||||
}
|
||||
|
||||
// Decode from base58 and ensure exactly 32 bytes
|
||||
byte[] decoded = decodeBase58(address);
|
||||
return decoded != null && decoded.length == 32;
|
||||
}
|
||||
|
||||
private static byte[] decodeBase58(String input) {
|
||||
BigInteger num = BigInteger.ZERO;
|
||||
BigInteger base = BigInteger.valueOf(58);
|
||||
|
||||
for (char c : input.toCharArray()) {
|
||||
int digit = BASE58_ALPHABET.indexOf(c);
|
||||
if (digit < 0) return null; // invalid char
|
||||
num = num.multiply(base).add(BigInteger.valueOf(digit));
|
||||
}
|
||||
|
||||
// Convert BigInteger to byte array
|
||||
byte[] bytes = num.toByteArray();
|
||||
|
||||
// Remove sign byte if present
|
||||
if (bytes.length > 1 && bytes[0] == 0) {
|
||||
byte[] tmp = new byte[bytes.length - 1];
|
||||
System.arraycopy(bytes, 1, tmp, 0, tmp.length);
|
||||
bytes = tmp;
|
||||
}
|
||||
|
||||
// Count leading '1's and add leading zero bytes
|
||||
int leadingZeros = 0;
|
||||
for (char c : input.toCharArray()) {
|
||||
if (c == '1') leadingZeros++;
|
||||
else break;
|
||||
}
|
||||
|
||||
byte[] result = new byte[leadingZeros + bytes.length];
|
||||
System.arraycopy(bytes, 0, result, leadingZeros, bytes.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
28
assets/src/main/java/haveno/asset/coins/Solana.java
Normal file
28
assets/src/main/java/haveno/asset/coins/Solana.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* This file is part of Haveno.
|
||||
*
|
||||
* Haveno 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.
|
||||
*
|
||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package haveno.asset.coins;
|
||||
|
||||
import haveno.asset.Coin;
|
||||
import haveno.asset.SolanaAddressValidator;
|
||||
|
||||
public class Solana extends Coin {
|
||||
|
||||
public Solana() {
|
||||
super("Solana", "SOL", new SolanaAddressValidator());
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ haveno.asset.coins.Ether
|
|||
haveno.asset.coins.Litecoin
|
||||
haveno.asset.coins.Monero
|
||||
haveno.asset.coins.Ripple
|
||||
haveno.asset.coins.Solana
|
||||
haveno.asset.tokens.TetherUSDERC20
|
||||
haveno.asset.tokens.TetherUSDTRC20
|
||||
haveno.asset.tokens.USDCoinERC20
|
||||
|
|
|
|||
46
assets/src/test/java/haveno/asset/coins/SolanaTest.java
Normal file
46
assets/src/test/java/haveno/asset/coins/SolanaTest.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file is part of Haveno.
|
||||
*
|
||||
* Haveno 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.
|
||||
*
|
||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package haveno.asset.coins;
|
||||
|
||||
import haveno.asset.AbstractAssetTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SolanaTest extends AbstractAssetTest {
|
||||
|
||||
public SolanaTest() {
|
||||
super(new Solana());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAddresses() {
|
||||
assertValidAddress("4Nd1mYZbtJbHkj9QwxAXWah8X9M8vZ9H1fsn6uhPW33k");
|
||||
assertValidAddress("8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NqAcoH7okh4wz7");
|
||||
assertValidAddress("H3C5pGrMmD8FrGd9VRtNVbY3tWusJX3A1u33f9bdBpsk");
|
||||
assertValidAddress("7zVhJcA5s8zfg3UoDUuG4zmnqaVmLqj6L6F6L8WPLnYw");
|
||||
assertValidAddress("AVHUu155WoNexeNCGce8mrb8hvg8pBgvCJh4vtd3Q1RV");
|
||||
assertValidAddress("8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NqAcoH7okh4wz");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidAddresses() {
|
||||
assertInvalidAddress("4Nd1mYZbtJbHkj9QwxAXWah8X9M8vZ9H1fsn6uhPW33O");
|
||||
assertInvalidAddress("H3C5pGrMmD8FrGd9VRtNVbY3tWusJX3A1u33f9bdBpskAAA");
|
||||
assertInvalidAddress("1");
|
||||
assertInvalidAddress("abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789");
|
||||
}
|
||||
}
|
||||
|
|
@ -202,6 +202,7 @@ public class CurrencyUtil {
|
|||
result.add(new CryptoCurrency("LTC", "Litecoin"));
|
||||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||
result.add(new CryptoCurrency("ADA", "Cardano"));
|
||||
result.add(new CryptoCurrency("SOL", "Solana"));
|
||||
result.add(new CryptoCurrency("DAI-ERC20", "Dai Stablecoin"));
|
||||
result.add(new CryptoCurrency("USDT-ERC20", "Tether USD"));
|
||||
result.add(new CryptoCurrency("USDT-TRC20", "Tether USD"));
|
||||
|
|
|
|||
|
|
@ -361,6 +361,10 @@
|
|||
-fx-image: url("../../images/ada_logo.png");
|
||||
}
|
||||
|
||||
#image-sol-logo {
|
||||
-fx-image: url("../../images/sol_logo.png");
|
||||
}
|
||||
|
||||
#image-dark-mode-toggle {
|
||||
-fx-image: url("../../images/dark_mode_toggle.png");
|
||||
}
|
||||
|
|
|
|||
BIN
desktop/src/main/resources/images/sol_logo.png
Normal file
BIN
desktop/src/main/resources/images/sol_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Loading…
Add table
Add a link
Reference in a new issue