mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-11-30 16:36:36 -05:00
support Tron (TRX)
This commit is contained in:
parent
b0446c637f
commit
878cbb86ce
7 changed files with 183 additions and 0 deletions
104
assets/src/main/java/haveno/asset/TronAddressValidator.java
Normal file
104
assets/src/main/java/haveno/asset/TronAddressValidator.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Validates a Tron address.
|
||||
*/
|
||||
public class TronAddressValidator implements AddressValidator {
|
||||
|
||||
private static final String BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
private static final byte MAINNET_PREFIX = 0x41;
|
||||
|
||||
public TronAddressValidator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressValidationResult validate(String address) {
|
||||
if (!isValidTronAddress(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 isValidTronAddress(String address) {
|
||||
if (address == null || address.length() != 34) return false;
|
||||
|
||||
byte[] decoded = decodeBase58(address);
|
||||
if (decoded == null || decoded.length != 25) return false; // 21 bytes data + 4 bytes checksum
|
||||
|
||||
// Check checksum
|
||||
byte[] data = Arrays.copyOfRange(decoded, 0, 21);
|
||||
byte[] checksum = Arrays.copyOfRange(decoded, 21, 25);
|
||||
byte[] calculatedChecksum = Arrays.copyOfRange(doubleSHA256(data), 0, 4);
|
||||
|
||||
if (!Arrays.equals(checksum, calculatedChecksum)) return false;
|
||||
|
||||
// Check mainnet prefix
|
||||
return data[0] == MAINNET_PREFIX;
|
||||
}
|
||||
|
||||
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;
|
||||
num = num.multiply(base).add(BigInteger.valueOf(digit));
|
||||
}
|
||||
|
||||
// Convert BigInteger to byte array
|
||||
byte[] bytes = num.toByteArray();
|
||||
if (bytes.length > 1 && bytes[0] == 0) {
|
||||
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
|
||||
}
|
||||
|
||||
// Add leading zero bytes for '1's
|
||||
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;
|
||||
}
|
||||
|
||||
private static byte[] doubleSHA256(byte[] data) {
|
||||
try {
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
return sha256.digest(sha256.digest(data));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
assets/src/main/java/haveno/asset/coins/Tron.java
Normal file
28
assets/src/main/java/haveno/asset/coins/Tron.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.TronAddressValidator;
|
||||
|
||||
public class Tron extends Coin {
|
||||
|
||||
public Tron() {
|
||||
super("Tron", "TRX", new TronAddressValidator());
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ haveno.asset.coins.Litecoin
|
|||
haveno.asset.coins.Monero
|
||||
haveno.asset.coins.Ripple
|
||||
haveno.asset.coins.Solana
|
||||
haveno.asset.coins.Tron
|
||||
haveno.asset.tokens.TetherUSDERC20
|
||||
haveno.asset.tokens.TetherUSDTRC20
|
||||
haveno.asset.tokens.USDCoinERC20
|
||||
|
|
|
|||
45
assets/src/test/java/haveno/asset/coins/TronTest.java
Normal file
45
assets/src/test/java/haveno/asset/coins/TronTest.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 TronTest extends AbstractAssetTest {
|
||||
|
||||
public TronTest() {
|
||||
super(new Tron());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAddresses() {
|
||||
assertValidAddress("TRjE1H8dxypKM1NZRdysbs9wo7huR4bdNz");
|
||||
assertValidAddress("THdUXD3mZqT5aMnPQMtBSJX9ANGjaeUwQK");
|
||||
assertValidAddress("THUE6WTLaEGytFyuGJQUcKc3r245UKypoi");
|
||||
assertValidAddress("TH7vVF9RTMXM9x7ZnPnbNcEph734hpu8cf");
|
||||
assertValidAddress("TJNtFduS4oebw3jgGKCYmgSpTdyPieb6Ha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidAddresses() {
|
||||
assertInvalidAddress("TJRyWwFs9wTFGZg3L8nL62xwP9iK8QdK9R");
|
||||
assertInvalidAddress("TJRyWwFs9wTFGZg3L8nL62xwP9iK8QdK9X");
|
||||
assertInvalidAddress("1JRyWwFs9wTFGZg3L8nL62xwP9iK8QdK9R");
|
||||
assertInvalidAddress("TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVo");
|
||||
}
|
||||
}
|
||||
|
|
@ -203,6 +203,7 @@ public class CurrencyUtil {
|
|||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||
result.add(new CryptoCurrency("ADA", "Cardano"));
|
||||
result.add(new CryptoCurrency("SOL", "Solana"));
|
||||
result.add(new CryptoCurrency("TRX", "Tron"));
|
||||
result.add(new CryptoCurrency("DAI-ERC20", "Dai Stablecoin"));
|
||||
result.add(new CryptoCurrency("USDT-ERC20", "Tether USD"));
|
||||
result.add(new CryptoCurrency("USDT-TRC20", "Tether USD"));
|
||||
|
|
|
|||
|
|
@ -365,6 +365,10 @@
|
|||
-fx-image: url("../../images/sol_logo.png");
|
||||
}
|
||||
|
||||
#image-trx-logo {
|
||||
-fx-image: url("../../images/trx_logo.png");
|
||||
}
|
||||
|
||||
#image-dark-mode-toggle {
|
||||
-fx-image: url("../../images/dark_mode_toggle.png");
|
||||
}
|
||||
|
|
|
|||
BIN
desktop/src/main/resources/images/trx_logo.png
Normal file
BIN
desktop/src/main/resources/images/trx_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Loading…
Add table
Add a link
Reference in a new issue