Skip to content

Commit 154f2e9

Browse files
Merge pull request #120 from manishdait/issue-97
feat: Added TokenClient API
2 parents 8681d78 + f8b7bea commit 154f2e9

File tree

13 files changed

+627
-33
lines changed

13 files changed

+627
-33
lines changed

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/TokenClient.java

Lines changed: 380 additions & 0 deletions
Large diffs are not rendered by default.

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/NftClientImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void transferNfts(@NonNull final TokenId tokenId, @NonNull final List<Lon
116116
@NonNull final PrivateKey fromAccountKey, @NonNull final AccountId toAccountId) throws HieroException {
117117
final TokenTransferRequest request = TokenTransferRequest.of(tokenId, serialNumber, fromAccountId, toAccountId,
118118
fromAccountKey);
119-
client.executeTransferTransactionForNft(request);
119+
client.executeTransferTransaction(request);
120120
}
121121

122122

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/ProtocolLayerClientImpl.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ public TokenBurnResult executeBurnTokenTransaction(@NonNull final TokenBurnReque
430430
}
431431

432432
final TransactionReceipt receipt = executeTransactionAndWaitOnReceipt(transaction);
433-
return new TokenBurnResult(receipt.transactionId, receipt.status);
433+
return new TokenBurnResult(receipt.transactionId, receipt.status, receipt.totalSupply);
434434
} catch (final Exception e) {
435435
throw new HieroException("Failed to execute burn token transaction", e);
436436
}
@@ -452,22 +452,29 @@ public TokenMintResult executeMintTokenTransaction(@NonNull final TokenMintReque
452452
}
453453
sign(transaction, request.supplyKey());
454454
final TransactionReceipt receipt = executeTransactionAndWaitOnReceipt(transaction);
455-
return new TokenMintResult(receipt.transactionId, receipt.status, receipt.serials);
455+
return new TokenMintResult(receipt.transactionId, receipt.status, receipt.serials, receipt.totalSupply);
456456
} catch (final Exception e) {
457457
throw new HieroException("Failed to execute mint token transaction", e);
458458
}
459459
}
460460

461-
public TokenTransferResult executeTransferTransactionForNft(@NonNull final TokenTransferRequest request)
461+
public TokenTransferResult executeTransferTransaction(@NonNull final TokenTransferRequest request)
462462
throws HieroException {
463463
Objects.requireNonNull(request, "request must not be null");
464464
try {
465465
final TransferTransaction transaction = new TransferTransaction()
466466
.setMaxTransactionFee(request.maxTransactionFee())
467467
.setTransactionValidDuration(request.transactionValidDuration());
468-
request.serials().forEach(
469-
serial -> transaction.addNftTransfer(new NftId(request.tokenId(), serial), request.sender(),
470-
request.receiver()));
468+
if (!request.serials().isEmpty()) {
469+
request.serials().forEach(
470+
serial -> transaction.addNftTransfer(new NftId(request.tokenId(), serial), request.sender(),
471+
request.receiver()));
472+
} else if (request.amount() != null) {
473+
transaction.addTokenTransfer(request.tokenId(), request.sender(), request.amount() * -1);
474+
transaction.addTokenTransfer(request.tokenId(), request.receiver(), request.amount());
475+
} else {
476+
throw new IllegalArgumentException("either amount or serial must be provided");
477+
}
471478
sign(transaction, request.senderKey());
472479
final TransactionReceipt receipt = executeTransactionAndWaitOnReceipt(transaction);
473480
return new TokenTransferResult(receipt.transactionId, receipt.status);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.openelements.hiero.base.implementation;
2+
3+
import com.openelements.hiero.base.TokenClient;
4+
import com.hedera.hashgraph.sdk.AccountId;
5+
import com.hedera.hashgraph.sdk.PrivateKey;
6+
import com.hedera.hashgraph.sdk.TokenId;
7+
import com.hedera.hashgraph.sdk.TokenType;
8+
import com.openelements.hiero.base.HieroException;
9+
import com.openelements.hiero.base.data.Account;
10+
import com.openelements.hiero.base.protocol.*;
11+
import org.jspecify.annotations.NonNull;
12+
13+
import java.util.Objects;
14+
15+
public class TokenClientImpl implements TokenClient {
16+
private final ProtocolLayerClient client;
17+
18+
private final Account operationalAccount;
19+
20+
public TokenClientImpl(@NonNull final ProtocolLayerClient client, @NonNull final Account operationalAccount) {
21+
this.client = Objects.requireNonNull(client, "client must not be null");
22+
this.operationalAccount = Objects.requireNonNull(operationalAccount, "operationalAccount must not be null");
23+
}
24+
25+
@Override
26+
public TokenId createToken(@NonNull String name, @NonNull String symbol)
27+
throws HieroException {
28+
return createToken(name, symbol, operationalAccount);
29+
}
30+
31+
@Override
32+
public TokenId createToken(@NonNull String name, @NonNull String symbol, @NonNull PrivateKey supplyKey)
33+
throws HieroException {
34+
return createToken(name, symbol, operationalAccount, supplyKey);
35+
}
36+
37+
@Override
38+
public TokenId createToken(@NonNull String name, @NonNull String symbol, @NonNull AccountId treasuryAccountId,
39+
@NonNull PrivateKey treasuryKey) throws HieroException {
40+
return createToken(name, symbol, treasuryAccountId, treasuryKey, operationalAccount.privateKey());
41+
}
42+
43+
@Override
44+
public TokenId createToken(@NonNull String name, @NonNull String symbol, @NonNull AccountId treasuryAccountId,
45+
@NonNull PrivateKey treasuryKey, @NonNull PrivateKey supplyKey) throws HieroException {
46+
final TokenCreateRequest request = TokenCreateRequest.of(name, symbol, treasuryAccountId, treasuryKey,
47+
TokenType.FUNGIBLE_COMMON, supplyKey);
48+
final TokenCreateResult result = client.executeTokenCreateTransaction(request);
49+
return result.tokenId();
50+
}
51+
52+
@Override
53+
public void associateToken(@NonNull TokenId tokenId, @NonNull AccountId accountId, @NonNull PrivateKey accountKey)
54+
throws HieroException {
55+
final TokenAssociateRequest request = TokenAssociateRequest.of(tokenId, accountId, accountKey);
56+
client.executeTokenAssociateTransaction(request);
57+
}
58+
59+
@Override
60+
public long mintToken(@NonNull TokenId tokenId, long amount) throws HieroException {
61+
return mintToken(tokenId, operationalAccount.privateKey(), amount);
62+
}
63+
64+
@Override
65+
public long mintToken(@NonNull TokenId tokenId, @NonNull PrivateKey supplyKey, long amount)
66+
throws HieroException {
67+
final TokenMintRequest request = TokenMintRequest.of(tokenId, supplyKey, amount);
68+
final TokenMintResult result = client.executeMintTokenTransaction(request);
69+
return result.totalSupply();
70+
}
71+
72+
@Override
73+
public long burnToken(@NonNull TokenId tokenId, long amount) throws HieroException {
74+
return burnToken(tokenId, amount, operationalAccount.privateKey());
75+
}
76+
77+
@Override
78+
public long burnToken(@NonNull TokenId tokenId, long amount, @NonNull PrivateKey supplyKey) throws HieroException {
79+
final TokenBurnRequest request = TokenBurnRequest.of(tokenId, supplyKey, amount);
80+
final TokenBurnResult result = client.executeBurnTokenTransaction(request);
81+
return result.totalSupply();
82+
}
83+
84+
@Override
85+
public void transferToken(@NonNull TokenId tokenId, @NonNull AccountId toAccountId, long amount) throws HieroException {
86+
transferToken(tokenId, operationalAccount, toAccountId, amount);
87+
}
88+
89+
@Override
90+
public void transferToken(@NonNull TokenId tokenId, @NonNull AccountId fromAccountId,
91+
@NonNull PrivateKey fromAccountKey, @NonNull AccountId toAccountId, long amount) throws HieroException {
92+
final TokenTransferRequest request = TokenTransferRequest.of(tokenId, fromAccountId, toAccountId, fromAccountKey, amount);
93+
client.executeTransferTransaction(request);
94+
}
95+
}

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/protocol/ProtocolLayerClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ TokenAssociateResult executeTokenAssociateTransaction(@NonNull final TokenAssoci
179179
* @throws HieroException if the transaction could not be executed
180180
*/
181181
@NonNull
182-
TokenTransferResult executeTransferTransactionForNft(@NonNull final TokenTransferRequest request)
182+
TokenTransferResult executeTransferTransaction(@NonNull final TokenTransferRequest request)
183183
throws HieroException;
184184

185185
/**

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/protocol/TokenBurnRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ public static TokenBurnRequest of(TokenId tokenId, Set<Long> serials, PrivateKey
3131
return new TokenBurnRequest(TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE,
3232
TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION, tokenId, supplyKey, null, serials);
3333
}
34+
35+
public static TokenBurnRequest of(TokenId tokenId, PrivateKey supplyKey, long amount) {
36+
return new TokenBurnRequest(TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE,
37+
TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION, tokenId, supplyKey, amount, null);
38+
}
3439
}

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/protocol/TokenBurnResult.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
import java.util.Objects;
66
import org.jspecify.annotations.NonNull;
77

8-
public record TokenBurnResult(@NonNull TransactionId transactionId, @NonNull Status status) implements
9-
TransactionResult {
8+
public record TokenBurnResult(@NonNull TransactionId transactionId, @NonNull Status status, @NonNull Long totalSupply)
9+
implements TransactionResult {
1010

1111
public TokenBurnResult {
1212
Objects.requireNonNull(transactionId, "transactionId must not be null");
1313
Objects.requireNonNull(status, "status must not be null");
14+
Objects.requireNonNull(totalSupply, "totalSupply must not be null");
1415
}
1516
}

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/protocol/TokenMintResult.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
import org.jspecify.annotations.NonNull;
88

99
public record TokenMintResult(@NonNull TransactionId transactionId, @NonNull Status status,
10-
@NonNull List<Long> serials) implements TransactionResult {
10+
@NonNull List<Long> serials, @NonNull Long totalSupply) implements TransactionResult {
1111

1212
public TokenMintResult {
1313
Objects.requireNonNull(transactionId, "transactionId must not be null");
1414
Objects.requireNonNull(status, "status must not be null");
1515
Objects.requireNonNull(serials, "serials must not be null");
16+
Objects.requireNonNull(totalSupply, "totalSupply must not be null");
1617
}
1718
}

hiero-enterprise-base/src/main/java/com/openelements/hiero/base/protocol/TokenTransferRequest.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
import java.util.List;
99
import java.util.Objects;
1010
import org.jspecify.annotations.NonNull;
11+
import org.jspecify.annotations.Nullable;
1112

1213
public record TokenTransferRequest(@NonNull Hbar maxTransactionFee,
1314
@NonNull Duration transactionValidDuration,
1415
@NonNull TokenId tokenId,
1516
@NonNull List<Long> serials,
17+
@Nullable Long amount,
1618
@NonNull AccountId sender,
1719
@NonNull AccountId receiver,
1820
@NonNull PrivateKey senderKey) implements TransactionRequest {
@@ -25,9 +27,10 @@ public record TokenTransferRequest(@NonNull Hbar maxTransactionFee,
2527
Objects.requireNonNull(receiver, "receiver must not be null");
2628
Objects.requireNonNull(senderKey, "senderKey must not be null");
2729
Objects.requireNonNull(serials, "serials must not be null");
28-
if (serials.isEmpty()) {
29-
throw new IllegalArgumentException("serials must not be empty");
30+
if (amount == null && serials.isEmpty()) {
31+
throw new IllegalArgumentException("either amount or serial must be provided");
3032
}
33+
3134
serials.forEach(serial -> {
3235
if (serial < 0) {
3336
throw new IllegalArgumentException("serial must be positive");
@@ -43,8 +46,12 @@ public static TokenTransferRequest of(@NonNull final TokenId tokenId, final long
4346
public static TokenTransferRequest of(@NonNull final TokenId tokenId, @NonNull final List<Long> serials,
4447
@NonNull final AccountId sender, @NonNull final AccountId receiver, @NonNull final PrivateKey senderKey) {
4548
return new TokenTransferRequest(TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE,
46-
TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION, tokenId, serials, sender, receiver, senderKey);
49+
TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION, tokenId, serials, null, sender, receiver, senderKey);
4750
}
4851

49-
52+
public static TokenTransferRequest of(@NonNull final TokenId tokenId, @NonNull final AccountId sender,
53+
@NonNull final AccountId receiver, @NonNull final PrivateKey senderKey, @NonNull final Long amount) {
54+
return new TokenTransferRequest(TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE,
55+
TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION, tokenId, List.of(), amount, sender, receiver, senderKey);
56+
}
5057
}

hiero-enterprise-base/src/test/java/com/openelements/hiero/base/test/ProtocolLayerClientTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,6 @@ void testNullParams() {
5555
Assertions.assertThrows(NullPointerException.class, () -> client.executeTokenCreateTransaction(null));
5656
Assertions.assertThrows(NullPointerException.class, () -> client.executeBurnTokenTransaction(null));
5757
Assertions.assertThrows(NullPointerException.class, () -> client.executeMintTokenTransaction(null));
58-
Assertions.assertThrows(NullPointerException.class, () -> client.executeTransferTransactionForNft(null));
58+
Assertions.assertThrows(NullPointerException.class, () -> client.executeTransferTransaction(null));
5959
}
6060
}

0 commit comments

Comments
 (0)