From 29708736415395c599bc1132e7b1fe9734e42e7f Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Fri, 5 Sep 2025 12:13:05 +0400 Subject: [PATCH 1/8] Add nametag mint transaction data. Update inMemoryClient test --- .../sdk/transaction/MintTransactionData.java | 26 --- .../NametagMintTransactionData.java | 34 +++ .../com/unicity/sdk/e2e/CommonTestFlow.java | 3 +- .../sdk/e2e/TokenInMemoryClientTest.java | 221 +++++++++++++++++- .../java/com/unicity/sdk/token/TokenTest.java | 3 +- 5 files changed, 255 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/unicity/sdk/transaction/NametagMintTransactionData.java diff --git a/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java b/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java index f02cca3..8786d5c 100644 --- a/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java +++ b/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java @@ -56,32 +56,6 @@ public MintTransactionData( this.reason = reason; } - public static MintTransactionData createForNametag( - String name, - TokenType tokenType, - byte[] tokenData, - TokenCoinData coinData, - Address recipient, - byte[] salt, - Address targetAddress - ) { - Objects.requireNonNull(name, "Name cannot be null"); - Objects.requireNonNull(targetAddress, "Target address cannot be null"); - - return new MintTransactionData<>( - TokenId.fromNameTag(name), - tokenType, - tokenData, - coinData, - recipient, - salt, - new DataHasher(HashAlgorithm.SHA256) - .update(targetAddress.getAddress().getBytes(StandardCharsets.UTF_8)) - .digest(), - null - ); - } - public TokenId getTokenId() { return this.tokenId; } diff --git a/src/main/java/com/unicity/sdk/transaction/NametagMintTransactionData.java b/src/main/java/com/unicity/sdk/transaction/NametagMintTransactionData.java new file mode 100644 index 0000000..9e80353 --- /dev/null +++ b/src/main/java/com/unicity/sdk/transaction/NametagMintTransactionData.java @@ -0,0 +1,34 @@ +package com.unicity.sdk.transaction; + +import com.unicity.sdk.address.Address; +import com.unicity.sdk.hash.DataHasher; +import com.unicity.sdk.hash.HashAlgorithm; +import com.unicity.sdk.token.TokenId; +import com.unicity.sdk.token.TokenType; +import com.unicity.sdk.token.fungible.TokenCoinData; +import java.nio.charset.StandardCharsets; + +public class NametagMintTransactionData extends MintTransactionData { + public NametagMintTransactionData( + String name, + TokenType tokenType, + byte[] tokenData, + TokenCoinData coinData, + Address recipient, + byte[] salt, + Address targetAddress + ) { + super( + TokenId.fromNameTag(name), + tokenType, + tokenData, + coinData, + recipient, + salt, + new DataHasher(HashAlgorithm.SHA256) + .update(targetAddress.getAddress().getBytes(StandardCharsets.UTF_8)) + .digest(), + null + ); + } +} \ No newline at end of file diff --git a/src/test/java/com/unicity/sdk/e2e/CommonTestFlow.java b/src/test/java/com/unicity/sdk/e2e/CommonTestFlow.java index 40ce47a..e9916a4 100644 --- a/src/test/java/com/unicity/sdk/e2e/CommonTestFlow.java +++ b/src/test/java/com/unicity/sdk/e2e/CommonTestFlow.java @@ -25,6 +25,7 @@ import com.unicity.sdk.token.TokenType; import com.unicity.sdk.token.fungible.CoinId; import com.unicity.sdk.transaction.MintTransactionReason; +import com.unicity.sdk.transaction.NametagMintTransactionData; import com.unicity.sdk.transaction.split.SplitMintReason; import com.unicity.sdk.token.fungible.TokenCoinData; import com.unicity.sdk.transaction.InclusionProof; @@ -166,7 +167,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti DirectAddress bobNametagAddress = bobNametagPredicate.getReference(bobNametagTokenType) .toAddress(); MintCommitment nametagMintCommitment = MintCommitment.create( - MintTransactionData.createForNametag( + new NametagMintTransactionData<>( bobNameTag, bobNametagTokenType, new byte[10], diff --git a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java index 7d1bc34..6171943 100644 --- a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java +++ b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java @@ -1,7 +1,40 @@ package com.unicity.sdk.e2e; +import static com.unicity.sdk.utils.TestUtils.randomBytes; +import static com.unicity.sdk.utils.TestUtils.randomCoinData; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.unicity.sdk.StateTransitionClient; import com.unicity.sdk.TestAggregatorClient; +import com.unicity.sdk.address.Address; +import com.unicity.sdk.address.ProxyAddress; +import com.unicity.sdk.api.SubmitCommitmentResponse; +import com.unicity.sdk.api.SubmitCommitmentStatus; +import com.unicity.sdk.hash.DataHash; +import com.unicity.sdk.hash.DataHasher; +import com.unicity.sdk.hash.HashAlgorithm; +import com.unicity.sdk.predicate.MaskedPredicate; +import com.unicity.sdk.signing.SigningService; +import com.unicity.sdk.token.NameTagTokenState; +import com.unicity.sdk.token.Token; +import com.unicity.sdk.token.TokenId; +import com.unicity.sdk.token.TokenState; +import com.unicity.sdk.token.TokenType; +import com.unicity.sdk.token.fungible.TokenCoinData; +import com.unicity.sdk.transaction.InclusionProof; +import com.unicity.sdk.transaction.MintCommitment; +import com.unicity.sdk.transaction.MintTransactionData; +import com.unicity.sdk.transaction.MintTransactionReason; +import com.unicity.sdk.transaction.NametagMintTransactionData; +import com.unicity.sdk.transaction.Transaction; +import com.unicity.sdk.transaction.TransferCommitment; +import com.unicity.sdk.transaction.TransferTransactionData; +import com.unicity.sdk.util.InclusionProofUtils; +import com.unicity.sdk.utils.TestTokenData; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.UUID; import org.junit.jupiter.api.Test; /** @@ -10,11 +43,191 @@ */ public class TokenInMemoryClientTest { - private StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); + public static Token mintToken(StateTransitionClient client, byte[] secret) throws Exception { + TokenId tokenId = new TokenId(randomBytes(32)); + TokenType tokenType = new TokenType(randomBytes(32)); + TokenCoinData coinData = randomCoinData(2); + byte[] nonce = randomBytes(32); + SigningService signingService = SigningService.createFromSecret(secret, nonce); - @Test - void testTransferFlow() throws Exception { - CommonTestFlow.testTransferFlow(this.client); + MaskedPredicate predicate = MaskedPredicate.create( + signingService, + HashAlgorithm.SHA256, + nonce + ); + + Address address = predicate.getReference(tokenType).toAddress(); + TokenState tokenState = new TokenState(predicate, null); + + MintCommitment> commitment = MintCommitment.create( + new MintTransactionData<>( + tokenId, + tokenType, + new TestTokenData(randomBytes(32)).getData(), + coinData, + address, + new byte[5], + null, + null + ) + ); + + // Submit mint transaction using StateTransitionClient + SubmitCommitmentResponse response = client + .submitCommitment(commitment) + .get(); + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit mint commitment: %s", + response.getStatus())); + } + + // Wait for inclusion proof + InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( + client, + commitment + ).get(); + + // Create mint transaction + return new Token<>( + tokenState, + commitment.toTransaction(inclusionProof) + ); + } + + public static Token mintNametagToken(StateTransitionClient client, byte[] secret, + String nametag, Address targetAddress) throws Exception { + TokenType tokenType = new TokenType(randomBytes(32)); + TokenCoinData coinData = randomCoinData(2); + byte[] nonce = randomBytes(32); + SigningService signingService = SigningService.createFromSecret(secret, nonce); + + MaskedPredicate predicate = MaskedPredicate.create( + signingService, + HashAlgorithm.SHA256, + nonce + ); + + Address address = predicate.getReference(tokenType).toAddress(); + TokenState tokenState = new NameTagTokenState(predicate, targetAddress); + + MintCommitment> commitment = MintCommitment.create( + new NametagMintTransactionData<>( + nametag, + tokenType, + new TestTokenData(randomBytes(32)).getData(), + coinData, + address, + new byte[5], + targetAddress + ) + ); + + // Submit mint transaction using StateTransitionClient + SubmitCommitmentResponse response = client + .submitCommitment(commitment) + .get(); + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit mint commitment: %s", + response.getStatus())); + } + + // Wait for inclusion proof + InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( + client, + commitment + ).get(); + + // Create mint transaction + return new Token<>( + tokenState, + commitment.toTransaction(inclusionProof) + ); } + public static Transaction transferToken( + StateTransitionClient client, + byte[] secret, + Token token, + Address targetAddress, + DataHash dataHash + ) throws Exception { + TransferCommitment commitment = TransferCommitment.create( + token, + targetAddress, + randomBytes(32), + dataHash, + null, + SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + ); + + SubmitCommitmentResponse response = client.submitCommitment(token, commitment).get(); + + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit transaction commitment: %s", + response.getStatus())); + } + + // Wait for inclusion proof + InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( + client, + commitment + ).get(); + + // Create transfer transaction + return commitment.toTransaction( + token, + inclusionProof + ); + } + + @Test + public void testNametagTransfer() throws Exception { + StateTransitionClient client = new StateTransitionClient( + new TestAggregatorClient()); + byte[] ALICE_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); + byte[] BOB_SECRET = "BOB".getBytes(StandardCharsets.UTF_8); + + // Alice mints a token + Token aliceToken = mintToken(client, ALICE_SECRET); + assertTrue(aliceToken.verify().isSuccessful()); + + // Bob creates nametag + String bobNameTag = UUID.randomUUID().toString(); + byte[] bobStateData = "Bob's custom data".getBytes(StandardCharsets.UTF_8); + + // Alice transfers to Bob + Transaction aliceToBobTransferTransaction = transferToken( + client, + ALICE_SECRET, + aliceToken, + ProxyAddress.create(bobNameTag), + new DataHasher(HashAlgorithm.SHA256).update(bobStateData).digest() + ); + + // Bob prepares to receive the token + + byte[] bobNonce = randomBytes(32); + SigningService bobSigningService = SigningService.createFromSecret(BOB_SECRET, bobNonce); + MaskedPredicate bobPredicate = MaskedPredicate.create(bobSigningService, HashAlgorithm.SHA256, + bobNonce); + + // Bob creates nametag + Token bobNametagToken = mintNametagToken(client, BOB_SECRET, + bobNameTag, + bobPredicate.getReference(aliceToken.getType()).toAddress()); + + // Bob finalizes the token + Token bobToken = client.finalizeTransaction( + aliceToken, + new TokenState(bobPredicate, bobStateData), + aliceToBobTransferTransaction, + List.of(bobNametagToken) + ); + + // Verify Bob is now the owner + assertTrue(bobToken.verify().isSuccessful()); + assertTrue(bobToken.getState().getUnlockPredicate().isOwner(bobSigningService.getPublicKey())); + assertEquals(aliceToken.getId(), bobToken.getId()); + assertEquals(aliceToken.getType(), bobToken.getType()); + } } \ No newline at end of file diff --git a/src/test/java/com/unicity/sdk/token/TokenTest.java b/src/test/java/com/unicity/sdk/token/TokenTest.java index 5e6dfe5..01d16d9 100644 --- a/src/test/java/com/unicity/sdk/token/TokenTest.java +++ b/src/test/java/com/unicity/sdk/token/TokenTest.java @@ -11,6 +11,7 @@ import com.unicity.sdk.token.fungible.TokenCoinData; import com.unicity.sdk.transaction.InclusionProof; import com.unicity.sdk.transaction.MintTransactionData; +import com.unicity.sdk.transaction.NametagMintTransactionData; import com.unicity.sdk.transaction.Transaction; import com.unicity.sdk.transaction.TransferTransactionData; import com.unicity.sdk.utils.TestUtils; @@ -47,7 +48,7 @@ public void testJsonSerialization() throws IOException { nametagNonce), DirectAddress.create(new DataHash(HashAlgorithm.SHA256, TestUtils.randomBytes(32))) ); - MintTransactionData nametagGenesisData = MintTransactionData.createForNametag( + MintTransactionData nametagGenesisData = new NametagMintTransactionData<>( UUID.randomUUID().toString(), new TokenType(TestUtils.randomBytes(32)), TestUtils.randomBytes(5), From ccc4e3284b81a282160c3524ccf693d7af774461 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Fri, 5 Sep 2025 14:14:15 +0400 Subject: [PATCH 2/8] Change uuid to real nametag --- src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java index 6171943..8f1e832 100644 --- a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java +++ b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java @@ -34,7 +34,6 @@ import com.unicity.sdk.utils.TestTokenData; import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.UUID; import org.junit.jupiter.api.Test; /** @@ -192,7 +191,7 @@ public void testNametagTransfer() throws Exception { assertTrue(aliceToken.verify().isSuccessful()); // Bob creates nametag - String bobNameTag = UUID.randomUUID().toString(); + String bobNameTag = "bob@unicity-labs.com"; byte[] bobStateData = "Bob's custom data".getBytes(StandardCharsets.UTF_8); // Alice transfers to Bob From dfb342fcf712ba20bd3b015301c64d368e719d53 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 14:14:30 +0400 Subject: [PATCH 3/8] Improve the flow in nametag test to represent real world usecase --- .../sdk/e2e/TokenInMemoryClientTest.java | 124 ++++++++++-------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java index 8f1e832..0e6f95d 100644 --- a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java +++ b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.fasterxml.jackson.core.type.TypeReference; import com.unicity.sdk.StateTransitionClient; import com.unicity.sdk.TestAggregatorClient; import com.unicity.sdk.address.Address; @@ -15,6 +16,7 @@ import com.unicity.sdk.hash.DataHasher; import com.unicity.sdk.hash.HashAlgorithm; import com.unicity.sdk.predicate.MaskedPredicate; +import com.unicity.sdk.serializer.UnicityObjectMapper; import com.unicity.sdk.signing.SigningService; import com.unicity.sdk.token.NameTagTokenState; import com.unicity.sdk.token.Token; @@ -41,8 +43,73 @@ * structure. */ public class TokenInMemoryClientTest { + private static final byte[] ALICE_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); + private static final byte[] BOB_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); - public static Token mintToken(StateTransitionClient client, byte[] secret) throws Exception { + @Test + public void testNametagTransfer() throws Exception { + StateTransitionClient client = new StateTransitionClient( + new TestAggregatorClient()); + + // Alice mints token on her environment + Token aliceToken = mintToken(client, ALICE_SECRET); + assertTrue(aliceToken.verify().isSuccessful()); + + // Bob prepares information for receiving the token from alice + String bobNameTag = "bob@unicity-labs.com"; + byte[] bobStateData = "Bob's custom data".getBytes(StandardCharsets.UTF_8); + + // Bob creates predicate for the token he will receive to create an address + byte[] bobNonce = randomBytes(32); + SigningService bobSigningService = SigningService.createFromSecret(BOB_SECRET, bobNonce); + MaskedPredicate bobPredicate = MaskedPredicate.create(bobSigningService, HashAlgorithm.SHA256, + bobNonce); + + // Bob creates nametag and put real address into it so alice could use nametag to send token + Token bobNametagToken = mintNametagToken( + client, + BOB_SECRET, + bobNameTag, + bobPredicate.getReference(aliceToken.getType()).toAddress() + ); + + // Bob gives nametag and data hash he will put into token to alice and alice transfers token + Transaction aliceToBobTransferTransaction = transferToken( + client, + ALICE_SECRET, + aliceToken, + ProxyAddress.create(bobNameTag), + new DataHasher(HashAlgorithm.SHA256).update(bobStateData).digest() + ); + + // Alice creates JSON representations of the token and transaction to simulate sending over network + byte[] aliceTokenJson = UnicityObjectMapper.JSON + .writeValueAsBytes(aliceToken); + byte[] aliceToBobTransferTransactionJson = UnicityObjectMapper.JSON + .writeValueAsBytes(aliceToBobTransferTransaction); + + // Bob receives token and transaction in json format and finalizes the transaction + Token bobToken = client.finalizeTransaction( + UnicityObjectMapper.JSON.readValue( + aliceTokenJson, + UnicityObjectMapper.JSON.getTypeFactory().constructType(Token.class) + ), + new TokenState(bobPredicate, bobStateData), + UnicityObjectMapper.JSON.readValue( + aliceToBobTransferTransactionJson, + UnicityObjectMapper.JSON.getTypeFactory().constructParametricType(Transaction.class, TransferTransactionData.class) + ), + List.of(bobNametagToken) + ); + + // Verify Bob is now the owner + assertTrue(bobToken.verify().isSuccessful()); + assertTrue(bobToken.getState().getUnlockPredicate().isOwner(bobSigningService.getPublicKey())); + assertEquals(aliceToken.getId(), bobToken.getId()); + assertEquals(aliceToken.getType(), bobToken.getType()); + } + + private static Token mintToken(StateTransitionClient client, byte[] secret) throws Exception { TokenId tokenId = new TokenId(randomBytes(32)); TokenType tokenType = new TokenType(randomBytes(32)); TokenCoinData coinData = randomCoinData(2); @@ -93,7 +160,7 @@ public static Token mintToken(StateTransitionClient client, byte[] secret) th ); } - public static Token mintNametagToken(StateTransitionClient client, byte[] secret, + private static Token mintNametagToken(StateTransitionClient client, byte[] secret, String nametag, Address targetAddress) throws Exception { TokenType tokenType = new TokenType(randomBytes(32)); TokenCoinData coinData = randomCoinData(2); @@ -143,7 +210,7 @@ public static Token mintNametagToken(StateTransitionClient client, byte[] sec ); } - public static Transaction transferToken( + private static Transaction transferToken( StateTransitionClient client, byte[] secret, Token token, @@ -178,55 +245,4 @@ public static Transaction transferToken( inclusionProof ); } - - @Test - public void testNametagTransfer() throws Exception { - StateTransitionClient client = new StateTransitionClient( - new TestAggregatorClient()); - byte[] ALICE_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); - byte[] BOB_SECRET = "BOB".getBytes(StandardCharsets.UTF_8); - - // Alice mints a token - Token aliceToken = mintToken(client, ALICE_SECRET); - assertTrue(aliceToken.verify().isSuccessful()); - - // Bob creates nametag - String bobNameTag = "bob@unicity-labs.com"; - byte[] bobStateData = "Bob's custom data".getBytes(StandardCharsets.UTF_8); - - // Alice transfers to Bob - Transaction aliceToBobTransferTransaction = transferToken( - client, - ALICE_SECRET, - aliceToken, - ProxyAddress.create(bobNameTag), - new DataHasher(HashAlgorithm.SHA256).update(bobStateData).digest() - ); - - // Bob prepares to receive the token - - byte[] bobNonce = randomBytes(32); - SigningService bobSigningService = SigningService.createFromSecret(BOB_SECRET, bobNonce); - MaskedPredicate bobPredicate = MaskedPredicate.create(bobSigningService, HashAlgorithm.SHA256, - bobNonce); - - // Bob creates nametag - Token bobNametagToken = mintNametagToken(client, BOB_SECRET, - bobNameTag, - bobPredicate.getReference(aliceToken.getType()).toAddress()); - - // Bob finalizes the token - Token bobToken = client.finalizeTransaction( - aliceToken, - new TokenState(bobPredicate, bobStateData), - aliceToBobTransferTransaction, - List.of(bobNametagToken) - ); - - // Verify Bob is now the owner - assertTrue(bobToken.verify().isSuccessful()); - assertTrue(bobToken.getState().getUnlockPredicate().isOwner(bobSigningService.getPublicKey())); - assertEquals(aliceToken.getId(), bobToken.getId()); - assertEquals(aliceToken.getType(), bobToken.getType()); - } } \ No newline at end of file From 8af3f29fef92c18aa9de21bd0216a9c79018d164 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 14:17:48 +0400 Subject: [PATCH 4/8] Fix bob secret in TokenInMemoryClientTest --- src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java index 0e6f95d..a27c43d 100644 --- a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java +++ b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java @@ -44,7 +44,7 @@ */ public class TokenInMemoryClientTest { private static final byte[] ALICE_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); - private static final byte[] BOB_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); + private static final byte[] BOB_SECRET = "BOB".getBytes(StandardCharsets.UTF_8); @Test public void testNametagTransfer() throws Exception { From a97252efa7180574b4b547a716dcd1095392e300 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 21:11:50 +0400 Subject: [PATCH 5/8] Add token split functional test --- .../java/com/unicity/sdk/token/Token.java | 4 + .../java/com/unicity/sdk/token/TokenId.java | 3 + .../sdk/transaction/MintTransactionData.java | 1 - .../sdk/transaction/TransferCommitment.java | 2 +- .../sdk/common/split/TokenSplitTest.java | 199 ++++++++++++++ .../sdk/e2e/TokenInMemoryClientTest.java | 248 ------------------ .../functional/FunctionalTokenSplitTest.java | 13 + .../com/unicity/sdk/utils/TokenUtils.java | 173 ++++++++++++ 8 files changed, 393 insertions(+), 250 deletions(-) create mode 100644 src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java delete mode 100644 src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java create mode 100644 src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java create mode 100644 src/test/java/com/unicity/sdk/utils/TokenUtils.java diff --git a/src/main/java/com/unicity/sdk/token/Token.java b/src/main/java/com/unicity/sdk/token/Token.java index 641d27c..299902c 100644 --- a/src/main/java/com/unicity/sdk/token/Token.java +++ b/src/main/java/com/unicity/sdk/token/Token.java @@ -44,6 +44,10 @@ public Token(TokenState state, Transaction genesis, List genesis, List> nametags) { + this(state, genesis, List.of(), nametags); + } + public Token(TokenState state, Transaction genesis) { this(state, genesis, List.of(), List.of()); } diff --git a/src/main/java/com/unicity/sdk/token/TokenId.java b/src/main/java/com/unicity/sdk/token/TokenId.java index d703096..d781689 100644 --- a/src/main/java/com/unicity/sdk/token/TokenId.java +++ b/src/main/java/com/unicity/sdk/token/TokenId.java @@ -7,6 +7,7 @@ import com.unicity.sdk.util.HexConverter; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Objects; /** * Globally unique identifier of a token. @@ -27,6 +28,8 @@ public BitString toBitString() { } public static TokenId fromNameTag(String name) { + Objects.requireNonNull(name, "Name cannot be null"); + return new TokenId( new DataHasher(HashAlgorithm.SHA256) .update(name.getBytes(StandardCharsets.UTF_8)) diff --git a/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java b/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java index 8786d5c..0781621 100644 --- a/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java +++ b/src/main/java/com/unicity/sdk/transaction/MintTransactionData.java @@ -12,7 +12,6 @@ import com.unicity.sdk.token.TokenType; import com.unicity.sdk.token.fungible.TokenCoinData; import com.unicity.sdk.util.HexConverter; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; import java.util.Optional; diff --git a/src/main/java/com/unicity/sdk/transaction/TransferCommitment.java b/src/main/java/com/unicity/sdk/transaction/TransferCommitment.java index 8f41af9..e057417 100644 --- a/src/main/java/com/unicity/sdk/transaction/TransferCommitment.java +++ b/src/main/java/com/unicity/sdk/transaction/TransferCommitment.java @@ -52,7 +52,7 @@ public Transaction toTransaction(Token token, throw new RuntimeException("Inclusion proof verification failed."); } - if (!inclusionProof.getAuthenticator().isPresent()) { + if (inclusionProof.getAuthenticator().isEmpty()) { throw new RuntimeException("Authenticator is missing from inclusion proof."); } diff --git a/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java b/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java new file mode 100644 index 0000000..fe934cd --- /dev/null +++ b/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java @@ -0,0 +1,199 @@ +package com.unicity.sdk.common.split; + +import static com.unicity.sdk.utils.TestUtils.randomBytes; + +import com.unicity.sdk.StateTransitionClient; +import com.unicity.sdk.address.Address; +import com.unicity.sdk.address.DirectAddress; +import com.unicity.sdk.address.ProxyAddress; +import com.unicity.sdk.api.SubmitCommitmentResponse; +import com.unicity.sdk.api.SubmitCommitmentStatus; +import com.unicity.sdk.hash.DataHash; +import com.unicity.sdk.hash.DataHasher; +import com.unicity.sdk.hash.HashAlgorithm; +import com.unicity.sdk.predicate.MaskedPredicate; +import com.unicity.sdk.signing.SigningService; +import com.unicity.sdk.token.Token; +import com.unicity.sdk.token.TokenId; +import com.unicity.sdk.token.TokenState; +import com.unicity.sdk.token.TokenType; +import com.unicity.sdk.token.fungible.CoinId; +import com.unicity.sdk.token.fungible.TokenCoinData; +import com.unicity.sdk.transaction.MintCommitment; +import com.unicity.sdk.transaction.MintTransactionData; +import com.unicity.sdk.transaction.TransferCommitment; +import com.unicity.sdk.transaction.split.SplitMintReason; +import com.unicity.sdk.transaction.split.TokenSplitBuilder; +import com.unicity.sdk.transaction.split.TokenSplitBuilder.TokenSplit; +import com.unicity.sdk.util.InclusionProofUtils; +import com.unicity.sdk.utils.TokenUtils; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public abstract class TokenSplitTest { + + protected StateTransitionClient client; + + @Test + void testTokenSplitFullAmounts() throws Exception { + byte[] secret = "SECRET".getBytes(StandardCharsets.UTF_8); + + Token token = TokenUtils.mintToken( + this.client, + secret, + new TokenId(randomBytes(32)), + new TokenType(randomBytes(32)), + randomBytes(32), + new TokenCoinData(Map.of( + new CoinId("test_eur".getBytes(StandardCharsets.UTF_8)), + BigInteger.valueOf(100), + new CoinId("test_usd".getBytes(StandardCharsets.UTF_8)), + BigInteger.valueOf(100) + )), + randomBytes(32), + randomBytes(32), + null + ); + + String nametag = "my_nametag"; + + Token nametagToken = TokenUtils.mintNametagToken( + this.client, + secret, + nametag, + DirectAddress.create(DataHash.fromImprint(new byte[34])) + ); + + TokenSplitBuilder builder = new TokenSplitBuilder(); + TokenSplit split = builder + .createToken( + new TokenId(randomBytes(32)), + new TokenType(randomBytes(32)), + null, + new TokenCoinData(Map.of( + new CoinId("test_eur".getBytes(StandardCharsets.UTF_8)), + BigInteger.valueOf(100) + )), + ProxyAddress.create(nametag), + randomBytes(32), + null + ) + .createToken( + new TokenId(randomBytes(32)), + new TokenType(randomBytes(32)), + null, + new TokenCoinData(Map.of( + new CoinId("test_usd".getBytes(StandardCharsets.UTF_8)), + BigInteger.valueOf(100) + )), + ProxyAddress.create(nametag), + randomBytes(32), + null + ) + .build(token); + + TransferCommitment burnCommitment = split.createBurnCommitment( + randomBytes(32), + SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + ); + + SubmitCommitmentResponse burnCommitmentResponse = this.client + .submitCommitment(token, burnCommitment) + .get(); + + if (burnCommitmentResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit burn commitment: %s", + burnCommitmentResponse.getStatus())); + } + + List>> mintCommitments = split.createSplitMintCommitments( + burnCommitment.toTransaction( + token, + InclusionProofUtils.waitInclusionProof(this.client, burnCommitment).get() + ) + ); + + for (MintCommitment> commitment : mintCommitments) { + SubmitCommitmentResponse response = this.client + .submitCommitment(commitment) + .get(); + + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit burn commitment: %s", + response.getStatus())); + } + + byte[] nonce = randomBytes(32); + TokenState state = new TokenState( + MaskedPredicate.create( + SigningService.createFromSecret(secret, nonce), + HashAlgorithm.SHA256, + nonce + ), + null + ); + Address address = state.getUnlockPredicate() + .getReference( + commitment.getTransactionData().getTokenType() + ) + .toAddress(); + + byte[] nametagNonce = randomBytes(32); + TokenState nametagTokenState = new TokenState( + MaskedPredicate.create( + SigningService.createFromSecret(secret, nametagNonce), + HashAlgorithm.SHA256, + nametagNonce + ), + address.getAddress().getBytes(StandardCharsets.UTF_8) + ); + + TransferCommitment nametagCommitment = TransferCommitment.create( + nametagToken, + nametagTokenState.getUnlockPredicate().getReference(nametagToken.getType()).toAddress(), + randomBytes(32), + new DataHasher(HashAlgorithm.SHA256) + .update(address.getAddress().getBytes(StandardCharsets.UTF_8)) + .digest(), + null, + SigningService.createFromSecret( + secret, + nametagToken.getState().getUnlockPredicate().getNonce() + ) + ); + + SubmitCommitmentResponse nametagTransferResponse = this.client + .submitCommitment(nametagToken, nametagCommitment).get(); + if (nametagTransferResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit burn commitment: %s", + response.getStatus())); + } + + nametagToken = this.client.finalizeTransaction( + nametagToken, + nametagTokenState, + nametagCommitment.toTransaction( + nametagToken, + InclusionProofUtils.waitInclusionProof(this.client, nametagCommitment).get() + ) + ); + + Token> splitToken = new Token<>( + state, + commitment.toTransaction( + InclusionProofUtils.waitInclusionProof(this.client, commitment).get()), + List.of(nametagToken) + ); + + Assertions.assertTrue(splitToken.verify().isSuccessful()); + } + + + } + + +} diff --git a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java b/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java deleted file mode 100644 index a27c43d..0000000 --- a/src/test/java/com/unicity/sdk/e2e/TokenInMemoryClientTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.unicity.sdk.e2e; - -import static com.unicity.sdk.utils.TestUtils.randomBytes; -import static com.unicity.sdk.utils.TestUtils.randomCoinData; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.unicity.sdk.StateTransitionClient; -import com.unicity.sdk.TestAggregatorClient; -import com.unicity.sdk.address.Address; -import com.unicity.sdk.address.ProxyAddress; -import com.unicity.sdk.api.SubmitCommitmentResponse; -import com.unicity.sdk.api.SubmitCommitmentStatus; -import com.unicity.sdk.hash.DataHash; -import com.unicity.sdk.hash.DataHasher; -import com.unicity.sdk.hash.HashAlgorithm; -import com.unicity.sdk.predicate.MaskedPredicate; -import com.unicity.sdk.serializer.UnicityObjectMapper; -import com.unicity.sdk.signing.SigningService; -import com.unicity.sdk.token.NameTagTokenState; -import com.unicity.sdk.token.Token; -import com.unicity.sdk.token.TokenId; -import com.unicity.sdk.token.TokenState; -import com.unicity.sdk.token.TokenType; -import com.unicity.sdk.token.fungible.TokenCoinData; -import com.unicity.sdk.transaction.InclusionProof; -import com.unicity.sdk.transaction.MintCommitment; -import com.unicity.sdk.transaction.MintTransactionData; -import com.unicity.sdk.transaction.MintTransactionReason; -import com.unicity.sdk.transaction.NametagMintTransactionData; -import com.unicity.sdk.transaction.Transaction; -import com.unicity.sdk.transaction.TransferCommitment; -import com.unicity.sdk.transaction.TransferTransactionData; -import com.unicity.sdk.util.InclusionProofUtils; -import com.unicity.sdk.utils.TestTokenData; -import java.nio.charset.StandardCharsets; -import java.util.List; -import org.junit.jupiter.api.Test; - -/** - * End-to-end tests for token operations using CommonTestFlow. Matches TypeScript SDK's test - * structure. - */ -public class TokenInMemoryClientTest { - private static final byte[] ALICE_SECRET = "ALICE".getBytes(StandardCharsets.UTF_8); - private static final byte[] BOB_SECRET = "BOB".getBytes(StandardCharsets.UTF_8); - - @Test - public void testNametagTransfer() throws Exception { - StateTransitionClient client = new StateTransitionClient( - new TestAggregatorClient()); - - // Alice mints token on her environment - Token aliceToken = mintToken(client, ALICE_SECRET); - assertTrue(aliceToken.verify().isSuccessful()); - - // Bob prepares information for receiving the token from alice - String bobNameTag = "bob@unicity-labs.com"; - byte[] bobStateData = "Bob's custom data".getBytes(StandardCharsets.UTF_8); - - // Bob creates predicate for the token he will receive to create an address - byte[] bobNonce = randomBytes(32); - SigningService bobSigningService = SigningService.createFromSecret(BOB_SECRET, bobNonce); - MaskedPredicate bobPredicate = MaskedPredicate.create(bobSigningService, HashAlgorithm.SHA256, - bobNonce); - - // Bob creates nametag and put real address into it so alice could use nametag to send token - Token bobNametagToken = mintNametagToken( - client, - BOB_SECRET, - bobNameTag, - bobPredicate.getReference(aliceToken.getType()).toAddress() - ); - - // Bob gives nametag and data hash he will put into token to alice and alice transfers token - Transaction aliceToBobTransferTransaction = transferToken( - client, - ALICE_SECRET, - aliceToken, - ProxyAddress.create(bobNameTag), - new DataHasher(HashAlgorithm.SHA256).update(bobStateData).digest() - ); - - // Alice creates JSON representations of the token and transaction to simulate sending over network - byte[] aliceTokenJson = UnicityObjectMapper.JSON - .writeValueAsBytes(aliceToken); - byte[] aliceToBobTransferTransactionJson = UnicityObjectMapper.JSON - .writeValueAsBytes(aliceToBobTransferTransaction); - - // Bob receives token and transaction in json format and finalizes the transaction - Token bobToken = client.finalizeTransaction( - UnicityObjectMapper.JSON.readValue( - aliceTokenJson, - UnicityObjectMapper.JSON.getTypeFactory().constructType(Token.class) - ), - new TokenState(bobPredicate, bobStateData), - UnicityObjectMapper.JSON.readValue( - aliceToBobTransferTransactionJson, - UnicityObjectMapper.JSON.getTypeFactory().constructParametricType(Transaction.class, TransferTransactionData.class) - ), - List.of(bobNametagToken) - ); - - // Verify Bob is now the owner - assertTrue(bobToken.verify().isSuccessful()); - assertTrue(bobToken.getState().getUnlockPredicate().isOwner(bobSigningService.getPublicKey())); - assertEquals(aliceToken.getId(), bobToken.getId()); - assertEquals(aliceToken.getType(), bobToken.getType()); - } - - private static Token mintToken(StateTransitionClient client, byte[] secret) throws Exception { - TokenId tokenId = new TokenId(randomBytes(32)); - TokenType tokenType = new TokenType(randomBytes(32)); - TokenCoinData coinData = randomCoinData(2); - byte[] nonce = randomBytes(32); - SigningService signingService = SigningService.createFromSecret(secret, nonce); - - MaskedPredicate predicate = MaskedPredicate.create( - signingService, - HashAlgorithm.SHA256, - nonce - ); - - Address address = predicate.getReference(tokenType).toAddress(); - TokenState tokenState = new TokenState(predicate, null); - - MintCommitment> commitment = MintCommitment.create( - new MintTransactionData<>( - tokenId, - tokenType, - new TestTokenData(randomBytes(32)).getData(), - coinData, - address, - new byte[5], - null, - null - ) - ); - - // Submit mint transaction using StateTransitionClient - SubmitCommitmentResponse response = client - .submitCommitment(commitment) - .get(); - if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit mint commitment: %s", - response.getStatus())); - } - - // Wait for inclusion proof - InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( - client, - commitment - ).get(); - - // Create mint transaction - return new Token<>( - tokenState, - commitment.toTransaction(inclusionProof) - ); - } - - private static Token mintNametagToken(StateTransitionClient client, byte[] secret, - String nametag, Address targetAddress) throws Exception { - TokenType tokenType = new TokenType(randomBytes(32)); - TokenCoinData coinData = randomCoinData(2); - byte[] nonce = randomBytes(32); - SigningService signingService = SigningService.createFromSecret(secret, nonce); - - MaskedPredicate predicate = MaskedPredicate.create( - signingService, - HashAlgorithm.SHA256, - nonce - ); - - Address address = predicate.getReference(tokenType).toAddress(); - TokenState tokenState = new NameTagTokenState(predicate, targetAddress); - - MintCommitment> commitment = MintCommitment.create( - new NametagMintTransactionData<>( - nametag, - tokenType, - new TestTokenData(randomBytes(32)).getData(), - coinData, - address, - new byte[5], - targetAddress - ) - ); - - // Submit mint transaction using StateTransitionClient - SubmitCommitmentResponse response = client - .submitCommitment(commitment) - .get(); - if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit mint commitment: %s", - response.getStatus())); - } - - // Wait for inclusion proof - InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( - client, - commitment - ).get(); - - // Create mint transaction - return new Token<>( - tokenState, - commitment.toTransaction(inclusionProof) - ); - } - - private static Transaction transferToken( - StateTransitionClient client, - byte[] secret, - Token token, - Address targetAddress, - DataHash dataHash - ) throws Exception { - TransferCommitment commitment = TransferCommitment.create( - token, - targetAddress, - randomBytes(32), - dataHash, - null, - SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) - ); - - SubmitCommitmentResponse response = client.submitCommitment(token, commitment).get(); - - if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit transaction commitment: %s", - response.getStatus())); - } - - // Wait for inclusion proof - InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( - client, - commitment - ).get(); - - // Create transfer transaction - return commitment.toTransaction( - token, - inclusionProof - ); - } -} \ No newline at end of file diff --git a/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java b/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java new file mode 100644 index 0000000..131973c --- /dev/null +++ b/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java @@ -0,0 +1,13 @@ +package com.unicity.sdk.functional; + +import com.unicity.sdk.StateTransitionClient; +import com.unicity.sdk.TestAggregatorClient; +import com.unicity.sdk.common.split.TokenSplitTest; +import org.junit.jupiter.api.BeforeEach; + +public class FunctionalTokenSplitTest extends TokenSplitTest { + @BeforeEach + void setUp() { + this.client = new StateTransitionClient(new TestAggregatorClient()); + } +} diff --git a/src/test/java/com/unicity/sdk/utils/TokenUtils.java b/src/test/java/com/unicity/sdk/utils/TokenUtils.java new file mode 100644 index 0000000..d2fa9bf --- /dev/null +++ b/src/test/java/com/unicity/sdk/utils/TokenUtils.java @@ -0,0 +1,173 @@ +package com.unicity.sdk.utils; + +import static com.unicity.sdk.utils.TestUtils.randomBytes; +import static com.unicity.sdk.utils.TestUtils.randomCoinData; + +import com.unicity.sdk.StateTransitionClient; +import com.unicity.sdk.address.Address; +import com.unicity.sdk.api.SubmitCommitmentResponse; +import com.unicity.sdk.api.SubmitCommitmentStatus; +import com.unicity.sdk.hash.DataHash; +import com.unicity.sdk.hash.HashAlgorithm; +import com.unicity.sdk.predicate.MaskedPredicate; +import com.unicity.sdk.signing.SigningService; +import com.unicity.sdk.token.NameTagTokenState; +import com.unicity.sdk.token.Token; +import com.unicity.sdk.token.TokenId; +import com.unicity.sdk.token.TokenState; +import com.unicity.sdk.token.TokenType; +import com.unicity.sdk.token.fungible.TokenCoinData; +import com.unicity.sdk.transaction.InclusionProof; +import com.unicity.sdk.transaction.MintCommitment; +import com.unicity.sdk.transaction.MintTransactionData; +import com.unicity.sdk.transaction.MintTransactionReason; +import com.unicity.sdk.transaction.NametagMintTransactionData; +import com.unicity.sdk.util.InclusionProofUtils; + +public class TokenUtils { + public static Token mintToken(StateTransitionClient client, byte[] secret) throws Exception { + return TokenUtils.mintToken( + client, + secret, + new TokenId(randomBytes(32)), + new TokenType(randomBytes(32)), + randomBytes(32), + randomCoinData(2), + randomBytes(32), + randomBytes(32), + null + ); + } + + public static Token mintToken( + StateTransitionClient client, + byte[] secret, + TokenId tokenId, + TokenType tokenType, + byte[] tokenData, + TokenCoinData coinData, + byte[] nonce, + byte[] salt, + DataHash dataHash + ) throws Exception { + SigningService signingService = SigningService.createFromSecret(secret, nonce); + + MaskedPredicate predicate = MaskedPredicate.create( + signingService, + HashAlgorithm.SHA256, + nonce + ); + + Address address = predicate.getReference(tokenType).toAddress(); + TokenState tokenState = new TokenState(predicate, null); + + MintCommitment> commitment = MintCommitment.create( + new MintTransactionData<>( + tokenId, + tokenType, + tokenData, + coinData, + address, + salt, + dataHash, + null + ) + ); + + // Submit mint transaction using StateTransitionClient + SubmitCommitmentResponse response = client + .submitCommitment(commitment) + .get(); + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit mint commitment: %s", + response.getStatus())); + } + + // Wait for inclusion proof + InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( + client, + commitment + ).get(); + + // Create mint transaction + return new Token<>( + tokenState, + commitment.toTransaction(inclusionProof) + ); + } + + public static Token mintNametagToken( + StateTransitionClient client, + byte[] secret, + String nametag, + Address targetAddress + ) throws Exception { + return mintNametagToken( + client, + secret, + new TokenType(randomBytes(32)), + randomBytes(32), + randomCoinData(2), + nametag, + targetAddress, + randomBytes(32), + randomBytes(32) + ); + } + + public static Token mintNametagToken( + StateTransitionClient client, + byte[] secret, + TokenType tokenType, + byte[] tokenData, + TokenCoinData coinData, + String nametag, + Address targetAddress, + byte[] nonce, + byte[] salt + ) throws Exception { + SigningService signingService = SigningService.createFromSecret(secret, nonce); + + MaskedPredicate predicate = MaskedPredicate.create( + signingService, + HashAlgorithm.SHA256, + nonce + ); + + Address address = predicate.getReference(tokenType).toAddress(); + TokenState tokenState = new NameTagTokenState(predicate, targetAddress); + + MintCommitment> commitment = MintCommitment.create( + new NametagMintTransactionData<>( + nametag, + tokenType, + tokenData, + coinData, + address, + salt, + targetAddress + ) + ); + + // Submit mint transaction using StateTransitionClient + SubmitCommitmentResponse response = client + .submitCommitment(commitment) + .get(); + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit mint commitment: %s", + response.getStatus())); + } + + // Wait for inclusion proof + InclusionProof inclusionProof = InclusionProofUtils.waitInclusionProof( + client, + commitment + ).get(); + + // Create mint transaction + return new Token<>( + tokenState, + commitment.toTransaction(inclusionProof) + ); + } +} From 3f029fbd07728d4b438fcab91f7a2fdcfd878f16 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 22:28:05 +0400 Subject: [PATCH 6/8] Update error wording in split test --- .../com/unicity/sdk/common/split/TokenSplitTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java b/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java index fe934cd..7c0077e 100644 --- a/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java +++ b/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java @@ -65,6 +65,7 @@ void testTokenSplitFullAmounts() throws Exception { this.client, secret, nametag, + // Direct to random address in the beginning DirectAddress.create(DataHash.fromImprint(new byte[34])) ); @@ -167,9 +168,10 @@ void testTokenSplitFullAmounts() throws Exception { ); SubmitCommitmentResponse nametagTransferResponse = this.client - .submitCommitment(nametagToken, nametagCommitment).get(); + .submitCommitment(nametagToken, nametagCommitment) + .get(); if (nametagTransferResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit burn commitment: %s", + throw new Exception(String.format("Failed to submit nametag transfer commitment: %s", response.getStatus())); } @@ -185,7 +187,8 @@ void testTokenSplitFullAmounts() throws Exception { Token> splitToken = new Token<>( state, commitment.toTransaction( - InclusionProofUtils.waitInclusionProof(this.client, commitment).get()), + InclusionProofUtils.waitInclusionProof(this.client, commitment).get() + ), List.of(nametagToken) ); From 44b49f670ffa1062ec422b01216923daf5211977 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 22:40:01 +0400 Subject: [PATCH 7/8] Fix naming of abstract token split class --- .../common/split/{TokenSplitTest.java => BaseTokenSplitTest.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/java/com/unicity/sdk/common/split/{TokenSplitTest.java => BaseTokenSplitTest.java} (100%) diff --git a/src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java b/src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java similarity index 100% rename from src/test/java/com/unicity/sdk/common/split/TokenSplitTest.java rename to src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java From 1276f026e6c144fc72e9be8cd19d5e0f3537b16d Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Sat, 6 Sep 2025 22:45:44 +0400 Subject: [PATCH 8/8] Fix naming of abstract token split class --- .../java/com/unicity/sdk/common/split/BaseTokenSplitTest.java | 2 +- .../com/unicity/sdk/functional/FunctionalTokenSplitTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java b/src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java index 7c0077e..ada2f55 100644 --- a/src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java +++ b/src/test/java/com/unicity/sdk/common/split/BaseTokenSplitTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -public abstract class TokenSplitTest { +public abstract class BaseTokenSplitTest { protected StateTransitionClient client; diff --git a/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java b/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java index 131973c..f3f8c4d 100644 --- a/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java +++ b/src/test/java/com/unicity/sdk/functional/FunctionalTokenSplitTest.java @@ -2,10 +2,10 @@ import com.unicity.sdk.StateTransitionClient; import com.unicity.sdk.TestAggregatorClient; -import com.unicity.sdk.common.split.TokenSplitTest; +import com.unicity.sdk.common.split.BaseTokenSplitTest; import org.junit.jupiter.api.BeforeEach; -public class FunctionalTokenSplitTest extends TokenSplitTest { +public class FunctionalTokenSplitTest extends BaseTokenSplitTest { @BeforeEach void setUp() { this.client = new StateTransitionClient(new TestAggregatorClient());