Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/main/java/org/stellar/sdk/Address.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.stellar.sdk;

import lombok.EqualsAndHashCode;
import org.stellar.sdk.xdr.ContractID;
import org.stellar.sdk.xdr.Hash;
import org.stellar.sdk.xdr.SCAddress;
import org.stellar.sdk.xdr.SCVal;
Expand Down Expand Up @@ -65,7 +66,8 @@ public static Address fromSCAddress(SCAddress scAddress) {
case SC_ADDRESS_TYPE_ACCOUNT:
return new Address(StrKey.encodeEd25519PublicKey(scAddress.getAccountId()));
case SC_ADDRESS_TYPE_CONTRACT:
return new Address(StrKey.encodeContract(scAddress.getContractId().getHash()));
return new Address(
StrKey.encodeContract(scAddress.getContractId().getContractID().getHash()));
default:
throw new IllegalArgumentException("Unsupported address type");
}
Expand Down Expand Up @@ -100,7 +102,7 @@ public SCAddress toSCAddress() {
break;
case CONTRACT:
scAddress.setDiscriminant(org.stellar.sdk.xdr.SCAddressType.SC_ADDRESS_TYPE_CONTRACT);
scAddress.setContractId(new Hash(this.key));
scAddress.setContractId(new ContractID(new Hash(this.key)));
break;
default:
throw new IllegalArgumentException("Unsupported address type");
Expand Down
86 changes: 85 additions & 1 deletion src/main/java/org/stellar/sdk/StrKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,48 @@ public static byte[] decodeContract(String data) {
return decodeCheck(VersionByte.CONTRACT, data.toCharArray());
}

/**
* Encodes raw data to strkey liquidity pool ID (L...)
*
* @param data data to encode
* @return "L..." representation of the key
*/
public static String encodeLiquidityPool(byte[] data) {
char[] encoded = encodeCheck(VersionByte.LIQUIDITY_POOL, data);
return String.valueOf(encoded);
}

/**
* Decodes strkey liquidity pool ID (L...) to raw bytes.
*
* @param data data to decode
* @return raw bytes
*/
public static byte[] decodeLiquidityPool(String data) {
return decodeCheck(VersionByte.LIQUIDITY_POOL, data.toCharArray());
}

/**
* Encodes raw data to strkey claimable balance ID (B...)
*
* @param data data to encode
* @return "B..." representation of the key
*/
public static String encodeClaimableBalance(byte[] data) {
char[] encoded = encodeCheck(VersionByte.CLAIMABLE_BALANCE, data);
return String.valueOf(encoded);
}

/**
* Decodes strkey claimable balance ID (B...) to raw bytes.
*
* @param data data to decode
* @return raw bytes
*/
public static byte[] decodeClaimableBalance(String data) {
return decodeCheck(VersionByte.CLAIMABLE_BALANCE, data.toCharArray());
}

/**
* Encodes raw data to strkey Stellar account ID (G...)
*
Expand Down Expand Up @@ -319,6 +361,36 @@ public static boolean isValidContract(String contractId) {
}
}

/**
* Checks validity of liquidity pool (L...) address.
*
* @param liquidityPoolId the liquidity pool ID to check
* @return true if the given liquidity pool ID is a valid liquidity pool ID, false otherwise
*/
public static boolean isValidLiquidityPool(String liquidityPoolId) {
try {
decodeLiquidityPool(liquidityPoolId);
return true;
} catch (Exception e) {
return false;
}
}

/**
* Checks validity of claimable balance (B...) address.
*
* @param claimableBalanceId the claimable balance ID to check
* @return true if the given claimable balance ID is a valid claimable balance ID, false otherwise
*/
public static boolean isValidClaimableBalance(String claimableBalanceId) {
try {
decodeClaimableBalance(claimableBalanceId);
return true;
} catch (Exception e) {
return false;
}
}

static char[] encodeCheck(VersionByte versionByte, byte[] data) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(versionByte.getValue());
Expand Down Expand Up @@ -409,6 +481,16 @@ static byte[] decodeCheck(VersionByte versionByte, char[] encoded) {
"Invalid data length, expected 40 bytes, got " + data.length);
}
break;
case CLAIMABLE_BALANCE:
if (data.length != 32 + 1) {
// If we are encoding a claimable balance, the binary bytes of the key has a length of
// 33-bytes:
// 1-byte value indicating the type of claimable balance, where 0x00 maps to V0, and a
// 32-byte SHA256 hash.
throw new IllegalArgumentException(
"Invalid data length, expected 33 bytes, got " + data.length);
}
break;
default:
if (data.length != 32) {
throw new IllegalArgumentException(
Expand Down Expand Up @@ -530,7 +612,9 @@ enum VersionByte {
PRE_AUTH_TX((byte) (19 << 3)), // T
SHA256_HASH((byte) (23 << 3)), // X
SIGNED_PAYLOAD((byte) (15 << 3)), // P
CONTRACT((byte) (2 << 3)); // C
CONTRACT((byte) (2 << 3)), // C
LIQUIDITY_POOL((byte) (11 << 3)), // L
CLAIMABLE_BALANCE((byte) (1 << 3)); // B

private final byte value;

Expand Down
49 changes: 49 additions & 0 deletions src/test/java/org/stellar/sdk/StrKeyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.Test;
Expand Down Expand Up @@ -637,4 +639,51 @@ public void testEncodeAndDecodeContract() {
assertEquals(strKey, StrKey.encodeContract(rawData));
assertArrayEquals(rawData, StrKey.decodeContract(strKey));
}

@Test
public void testEncodeAndDecodeLiquidityPool() {
byte[] rawData =
Util.hexToBytes("3f0c34bf93ad0d9971d04ccc90f705511c838aad9734a4a2fb0d7a03fc7fe89a");
String strKey = "LA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUPJN";
assertEquals(strKey, StrKey.encodeLiquidityPool(rawData));
assertArrayEquals(rawData, StrKey.decodeLiquidityPool(strKey));
}

@Test
public void testIsValidLiquidityPool() {
assertFalse(StrKey.isValidLiquidityPool("LA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA"));
assertFalse(StrKey.isValidLiquidityPool(""));
assertFalse(
StrKey.isValidLiquidityPool("SBCVMMCBEDB64TVJZFYJOJAERZC4YVVUOE6SYR2Y76CBTENGUSGWRRVO"));
assertFalse(
StrKey.isValidLiquidityPool(
"MAQAA5L65LSYH7CQ3VTJ7F3HHLGCL3DSLAR2Y47263D56MNNGHSQSAAAAAAAAAAE2LP26"));
assertTrue(
StrKey.isValidLiquidityPool("LA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUPJN"));
}

@Test
public void testEncodeAndDecodeClaimableBalance() {
byte[] rawData =
Util.hexToBytes("003f0c34bf93ad0d9971d04ccc90f705511c838aad9734a4a2fb0d7a03fc7fe89a");
String strKey = "BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4TU";
assertEquals(strKey, StrKey.encodeClaimableBalance(rawData));
assertArrayEquals(rawData, StrKey.decodeClaimableBalance(strKey));
}

@Test
public void tesIsValidClaimableBalance() {
assertFalse(
StrKey.isValidClaimableBalance(
"BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4T"));
assertFalse(StrKey.isValidClaimableBalance(""));
assertFalse(
StrKey.isValidClaimableBalance("SBCVMMCBEDB64TVJZFYJOJAERZC4YVVUOE6SYR2Y76CBTENGUSGWRRVO"));
assertFalse(
StrKey.isValidClaimableBalance(
"MAQAA5L65LSYH7CQ3VTJ7F3HHLGCL3DSLAR2Y47263D56MNNGHSQSAAAAAAAAAAE2LP26"));
assertTrue(
StrKey.isValidClaimableBalance(
"BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4TU"));
}
}