From 698938ad3cda5393e536590f0d35febf81e4648a Mon Sep 17 00:00:00 2001 From: grapebaba <281165273@qq.com> Date: Wed, 12 Apr 2023 11:15:13 +0800 Subject: [PATCH] feat: align with 0.29.2 Signed-off-by: grapebaba <281165273@qq.com> --- .gitignore | 3 +- README.md | 6 +- build.gradle | 2 +- docs/quickstart.md | 4 +- .../JsonRpcTransactionBuilderIntTests.java | 76 +- .../java/io/sui/QueryClientImplIntTests.java | 405 +-- .../java/io/sui/SuiIntTests.java | 1271 ++++--- src/main/java/io/sui/Sui.java | 704 ++-- src/main/java/io/sui/bcsgen/ChangeEpoch.java | 10 +- src/main/java/io/sui/bcsgen/Command.java | 51 +- .../io/sui/bcsgen/ExecutionFailureStatus.java | 128 + src/main/java/io/sui/bcsgen/MovePackage.java | 22 +- src/main/java/io/sui/bcsgen/TraitHelpers.java | 100 +- src/main/java/io/sui/bcsgen/TypeOrigin.java | 20 +- src/main/java/io/sui/clients/BuilderArg.java | 186 +- .../java/io/sui/clients/CallArgObjVec.java | 79 +- .../java/io/sui/clients/ExecutionClient.java | 14 +- .../io/sui/clients/ExecutionClientImpl.java | 19 +- .../java/io/sui/clients/FaucetClient.java | 43 +- .../sui/clients/HttpForbiddenException.java | 36 +- .../clients/JsonRpcTransactionBuilder.java | 57 +- .../sui/clients/LocalTransactionBuilder.java | 3214 ++++++++--------- .../MismatchedObjectArgumentException.java | 49 +- .../NotSupportedArgumentException.java | 14 +- .../io/sui/clients/OkhttpFaucetClient.java | 70 +- ...RecipientsAndAmountsMismatchException.java | 44 +- .../ProgrammableTransactionBuilder.java | 797 +++- src/main/java/io/sui/clients/QueryClient.java | 72 +- .../java/io/sui/clients/QueryClientImpl.java | 103 +- .../java/io/sui/clients/TransactionBlock.java | 1148 +++++- .../io/sui/clients/TransactionBuilder.java | 17 +- .../java/io/sui/crypto/AbstractKeyStore.java | 2 + .../java/io/sui/crypto/ED25519KeyPair.java | 8 +- src/main/java/io/sui/crypto/KeyResponse.java | 25 + src/main/java/io/sui/crypto/KeyStore.java | 20 + .../java/io/sui/crypto/SECP256K1KeyPair.java | 28 +- .../SignatureSchemeNotSupportedException.java | 4 +- .../java/io/sui/jsonrpc/GsonJsonHandler.java | 133 +- src/main/java/io/sui/jsonrpc/JsonHandler.java | 9 + .../java/io/sui/models/FaucetCoinInfo.java | 127 +- .../java/io/sui/models/FaucetResponse.java | 103 +- .../java/io/sui/models/events/EventQuery.java | 7 +- .../models/objects/CheckpointedObjectId.java | 102 +- .../io/sui/models/objects/MoveModule.java | 4 +- .../models/objects/MoveNormalizedType.java | 15 +- .../sui/models/objects/ObjectDataFilter.java | 176 +- .../sui/models/objects/ObjectDataOptions.java | 224 +- .../io/sui/models/objects/ObjectResponse.java | 176 +- .../models/objects/ObjectResponseQuery.java | 96 +- .../objects/PaginatedObjectsResponse.java | 127 +- .../io/sui/models/objects/SuiObjectData.java | 200 +- .../sui/models/objects/SuiObjectResponse.java | 109 +- .../objects/SuiObjectResponseError.java | 153 +- .../io/sui/models/objects/SuiParsedData.java | 177 +- .../io/sui/models/objects/SuiRawData.java | 69 +- .../PaginatedTransactionResponse.java | 44 +- .../transactions/ParsedMergeCoinResponse.java | 16 +- .../transactions/ParsedPublishResponse.java | 16 +- .../transactions/ParsedSplitCoinResponse.java | 22 +- .../io/sui/models/transactions/StructTag.java | 5 +- .../TransactionBlockResponse.java | 6 +- .../TransactionBlockResponseOptions.java | 8 +- .../TransactionBlockResponseQuery.java | 96 +- .../models/transactions/TransactionBytes.java | 16 +- .../transactions/TransactionFilter.java | 62 +- .../io/sui/crypto/ED25519KeyPairTest.java | 9 +- .../io/sui/crypto/FileBasedKeyStoreTest.java | 34 +- .../io/sui/crypto/SECP256K1KeyPairTest.java | 8 +- .../java/io/sui/crypto/SuiKeyPairTest.java | 2 +- src/test/resources/config/sui.keystore | 14 +- 70 files changed, 7592 insertions(+), 3624 deletions(-) diff --git a/.gitignore b/.gitignore index bf8e1c6..0445578 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ site _site bin .vscode -*.DS_Store \ No newline at end of file +*.DS_Store +src/integrationTest/sui.keystore \ No newline at end of file diff --git a/README.md b/README.md index 215276f..98cd7e9 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ upcoming TestNet launch. ## Using -The latest 0.4.1 version tested with sui devnet-0.24.0 version. +The latest 0.4.2 version tested with sui devnet-0.24.0 version. ### Maven @@ -27,7 +27,7 @@ The latest 0.4.1 version tested with sui devnet-0.24.0 version. me.grapebaba sui4j -0.4.1 +0.4.2 ``` @@ -35,7 +35,7 @@ The latest 0.4.1 version tested with sui devnet-0.24.0 version. ```groovy // https://mvnrepository.com/artifact/me.grapebaba/sui4j -implementation 'me.grapebaba:sui4j:0.4.1' +implementation 'me.grapebaba:sui4j:0.4.2' ``` ## Building Locally diff --git a/build.gradle b/build.gradle index 2593457..0003f12 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { group 'me.grapebaba' -version '0.4.1' +version '0.4.2' repositories { mavenCentral() diff --git a/docs/quickstart.md b/docs/quickstart.md index d0e88d9..a6ffa45 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -7,7 +7,7 @@ me.grapebaba sui4j -0.4.1 +0.4.2 ``` @@ -15,7 +15,7 @@ ```groovy // https://mvnrepository.com/artifact/me.grapebaba/sui4j -implementation 'me.grapebaba:sui4j:0.4.1' +implementation 'me.grapebaba:sui4j:0.4.2' ``` ## Use Sui4j diff --git a/src/integrationTest/java/io/sui/JsonRpcTransactionBuilderIntTests.java b/src/integrationTest/java/io/sui/JsonRpcTransactionBuilderIntTests.java index 112d9f1..07bae62 100644 --- a/src/integrationTest/java/io/sui/JsonRpcTransactionBuilderIntTests.java +++ b/src/integrationTest/java/io/sui/JsonRpcTransactionBuilderIntTests.java @@ -338,7 +338,7 @@ void batchTransaction() throws ExecutionException, InterruptedException { void moveCall() throws ExecutionException, InterruptedException { final TypeTag.StructType structType = new TypeTag.StructType(); StructTag structTag = new StructTag(); - structTag.setAddress("0x2"); + structTag.setAddress("0x0000000000000000000000000000000000000002"); structTag.setModule("sui"); structTag.setName("SUI"); structType.setStructTag(structTag); @@ -388,41 +388,41 @@ void moveCall() throws ExecutionException, InterruptedException { System.out.println(future1.get()); } - /** - * Publish. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test publish.") - void publish() throws ExecutionException, InterruptedException { - CompletableFuture res = - transactionBuilder.publish( - "0xea79464d86786b7a7a63e3f13f798f29f5e65947", - Lists.newArrayList( - "oRzrCwYAAAAKAQAIAggMAxQuBEICBUQrB2+IAQj3ASgKnwIKDKkCkwEN" - + "vAMEAAABAQECAQMABAgAAwYCAAENBAAABQABAAAHAgEAAAgDAQAACQQFAAAK" - + "BgEAAAsEBwABDgIIAAMPCQUAAhALAQEICAoCBggAAwABBwgBAQcIAAEGCAAB" - + "BQMHCAADBwgBAQMBCAIBBggBAQgAAQkAB2NvdW50ZXIGb2JqZWN0CHRyYW5z" - + "ZmVyCnR4X2NvbnRleHQHQ291bnRlcgxhc3NlcnRfdmFsdWUJVHhDb250ZXh0" - + "BmNyZWF0ZQlpbmNyZW1lbnQFb3duZXIJc2V0X3ZhbHVlBXZhbHVlAmlkA1VJ" - + "RANuZXcGc2VuZGVyDHNoYXJlX29iamVjdAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAIAAgMMCAIJBQsDAAEEAAEJCwAQABQLASED" - + "CAYAAAAAAAAAACcCAQEEAAEJCgARBgsALhEHBgAAAAAAAAAAEgA4AAICAQQA" - + "AQkKABAAFAYBAAAAAAAAABYLAA8AFQIDAQAAAQQLABABFAIEAQQAAREKABAB" - + "FAsCLhEHIQMMCwABBgAAAAAAAAAAJwsBCwAPABUCBQEAAAEECwAQABQCAAIAAQA="), - "0x05f71eb5dc69224ef8e3a4c13917c799190237d9", - 100L); - CompletableFuture future = new CompletableFuture<>(); - res.whenComplete( - (transactionResponse, throwable) -> { - if (throwable != null) { - future.complete(throwable); - } else { - future.complete(transactionResponse); - } - }); - System.out.println(future.get()); - } + // /** + // * Publish. + // * + // * @throws ExecutionException the execution exception + // * @throws InterruptedException the interrupted exception + // */ + // @Test + // @DisplayName("Test publish.") + // void publish() throws ExecutionException, InterruptedException { + // CompletableFuture res = + // transactionBuilder.publish( + // "0xea79464d86786b7a7a63e3f13f798f29f5e65947", + // Lists.newArrayList( + // "oRzrCwYAAAAKAQAIAggMAxQuBEICBUQrB2+IAQj3ASgKnwIKDKkCkwEN" + // + "vAMEAAABAQECAQMABAgAAwYCAAENBAAABQABAAAHAgEAAAgDAQAACQQFAAAK" + // + "BgEAAAsEBwABDgIIAAMPCQUAAhALAQEICAoCBggAAwABBwgBAQcIAAEGCAAB" + // + "BQMHCAADBwgBAQMBCAIBBggBAQgAAQkAB2NvdW50ZXIGb2JqZWN0CHRyYW5z" + // + "ZmVyCnR4X2NvbnRleHQHQ291bnRlcgxhc3NlcnRfdmFsdWUJVHhDb250ZXh0" + // + "BmNyZWF0ZQlpbmNyZW1lbnQFb3duZXIJc2V0X3ZhbHVlBXZhbHVlAmlkA1VJ" + // + "RANuZXcGc2VuZGVyDHNoYXJlX29iamVjdAAAAAAAAAAAAAAAAAAAAAAAAAAA" + // + "AAAAAAAAAAAAAAAAAAAAAAAAAAIAAgMMCAIJBQsDAAEEAAEJCwAQABQLASED" + // + "CAYAAAAAAAAAACcCAQEEAAEJCgARBgsALhEHBgAAAAAAAAAAEgA4AAICAQQA" + // + "AQkKABAAFAYBAAAAAAAAABYLAA8AFQIDAQAAAQQLABABFAIEAQQAAREKABAB" + // + "FAsCLhEHIQMMCwABBgAAAAAAAAAAJwsBCwAPABUCBQEAAAEECwAQABQCAAIAAQA="), + // "0x05f71eb5dc69224ef8e3a4c13917c799190237d9", + // 100L); + // CompletableFuture future = new CompletableFuture<>(); + // res.whenComplete( + // (transactionResponse, throwable) -> { + // if (throwable != null) { + // future.complete(throwable); + // } else { + // future.complete(transactionResponse); + // } + // }); + // System.out.println(future.get()); + // } } diff --git a/src/integrationTest/java/io/sui/QueryClientImplIntTests.java b/src/integrationTest/java/io/sui/QueryClientImplIntTests.java index 2ca2030..91392cc 100644 --- a/src/integrationTest/java/io/sui/QueryClientImplIntTests.java +++ b/src/integrationTest/java/io/sui/QueryClientImplIntTests.java @@ -18,44 +18,41 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import io.sui.clients.QueryClient; import io.sui.clients.QueryClientImpl; import io.sui.jsonrpc.GsonJsonHandler; import io.sui.jsonrpc.JsonHandler; -import io.sui.jsonrpc.JsonRpc20Response.Error.ErrorCode; import io.sui.jsonrpc.JsonRpcClientProvider; import io.sui.jsonrpc.OkHttpJsonRpcClientProvider; -import io.sui.models.SuiApiException; import io.sui.models.events.EventQuery.TransactionEventQuery; import io.sui.models.events.PaginatedEvents; -import io.sui.models.objects.Balance; import io.sui.models.objects.CheckpointContents; import io.sui.models.objects.CheckpointSummary; import io.sui.models.objects.CoinMetadata; import io.sui.models.objects.CommitteeInfoResponse; import io.sui.models.objects.MoveFunctionArgType; +import io.sui.models.objects.MoveModule; import io.sui.models.objects.MoveNormalizedFunction; import io.sui.models.objects.MoveNormalizedModule; import io.sui.models.objects.MoveNormalizedStruct; +import io.sui.models.objects.ObjectDataFilter; +import io.sui.models.objects.ObjectDataFilter.MoveModuleFilter; +import io.sui.models.objects.ObjectDataFilter.StructTypeFilter; +import io.sui.models.objects.ObjectDataOptions; import io.sui.models.objects.ObjectResponse; -import io.sui.models.objects.PaginatedCoins; -import io.sui.models.objects.SuiObjectInfo; +import io.sui.models.objects.ObjectResponseQuery; +import io.sui.models.objects.PaginatedObjectsResponse; import io.sui.models.objects.SuiSystemState; import io.sui.models.objects.ValidatorMetadata; -import io.sui.models.transactions.PaginatedTransactionDigests; -import io.sui.models.transactions.TransactionQuery; -import io.sui.models.transactions.TransactionQuery.AllQuery; -import io.sui.models.transactions.TransactionQuery.FromAddressQuery; -import io.sui.models.transactions.TransactionResponse; -import io.sui.models.transactions.TransactionResponseOptions; +import io.sui.models.transactions.PaginatedTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; +import io.sui.models.transactions.TransactionBlockResponseQuery; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -70,6 +67,8 @@ class QueryClientImplIntTests { private static final String BASE_URL = "http://localhost:9000"; + private static final String BASE_FAUCET_URL = "http://localhost:9123"; + private static final String TEST_KEY_STORE_PATH = System.getProperty("user.home") + "/.sui/sui_config/sui.keystore"; @@ -77,123 +76,74 @@ class QueryClientImplIntTests { private static QueryClient client; - private static Sui sui; - /** Before all. */ @BeforeAll static void beforeAll() { JsonRpcClientProvider jsonRpcClientProvider = new OkHttpJsonRpcClientProvider(BASE_URL, jsonHandler); client = new QueryClientImpl(jsonRpcClientProvider); - sui = new Sui(BASE_URL, TEST_KEY_STORE_PATH, true); - } - - /** - * Gets first address. - * - * @return the first address - */ - static Optional getFirstAddress() { - final Optional sender = - sui.addresses().stream() - .filter( - s -> { - try { - return sui.getObjectsOwnedByAddress(s).get().size() > 1; - } catch (InterruptedException | ExecutionException e) { - return false; - } - }) - .findFirst(); - if (!sender.isPresent()) { - Assertions.fail(); - } - return sender; - } - - /** - * Gets object. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getObject returns existing move object.") - void getObjectExistingMoveObject() throws ExecutionException, InterruptedException { - CompletableFuture res = - client.getObject("0x342950ba2451c2f27ed128e591c2b4551e5177c2"); - ObjectResponse response = res.get(); - System.out.println(response); - // assertEquals(ObjectStatus.Exists, response.getStatus()); - // SuiObject suiObject = (SuiObject) response.getDetails(); - // SuiData.MoveObject moveObject = (SuiData.MoveObject) suiObject.getData(); - // assertEquals("0x2::coin::Coin<0x2::sui::SUI>", moveObject.getType()); - // SuiObjectOwner.AddressOwner addressOwner = (SuiObjectOwner.AddressOwner) - // suiObject.getOwner(); - // assertEquals("0xea79464d86786b7a7a63e3f13f798f29f5e65947", - // addressOwner.getAddressOwner()); - // assertEquals(BigInteger.valueOf(100000000000000L), moveObject.getFields().get("balance")); - // SuiObjectRef suiObjectRef = suiObject.getReference(); - // assertEquals("bWkh6f80oGFCtsPtS3//66LvAvqGJTOVJtKmUJAd5l0=", suiObjectRef.getDigest()); } /** - * Gets object no exist. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getObject returns non existing object.") - void getObjectNoExist() throws ExecutionException, InterruptedException { - CompletableFuture res = - client.getObject("0xa204b49f2a65eb3d418ccae864b331c524c2fa76"); - - ObjectResponse response = res.get(); - System.out.println(response); - // assertEquals(ObjectStatus.NotExists, response.getStatus()); - // ObjectIdResponseDetails objectIdResponseDetails = - // (ObjectIdResponseDetails) response.getDetails(); - // assertEquals( - // "0xa204b49f2a65eb3d418ccae864b331c524c2fa76", objectIdResponseDetails.getObjectId()); - } - - /** - * Gets object invalid params. + * Gets objects owned by address is not empty. * * @throws ExecutionException the execution exception * @throws InterruptedException the interrupted exception */ @Test - @DisplayName("Test getObject with invalid params.") - void getObjectInvalidParams() throws ExecutionException, InterruptedException { - CompletableFuture res = client.getObject(""); - - CompletableFuture completableFuture = new CompletableFuture<>(); + @DisplayName("Test getObjectsOwnedByAddress returns not empty list.") + void getObjectsOwnedByAddressIsNotEmpty() throws ExecutionException, InterruptedException { + ObjectDataFilter.StructTypeFilter filter = new StructTypeFilter(); + filter.setStructType("0x2::coin::Coin<0x2::sui::SUI>"); + ObjectResponseQuery query = new ObjectResponseQuery(); + query.setFilter(filter); + ObjectDataOptions objectDataOptions = new ObjectDataOptions(); + objectDataOptions.setShowOwner(true); + objectDataOptions.setShowPreviousTransaction(true); + query.setOptions(objectDataOptions); + CompletableFuture res = + client.getObjectsOwnedByAddress( + "0xb43d0468fbc80c81931b73a4b9ef4663e671b65a07ae5b336a0e7d8a70ac0646", + query, + null, + null, + null); + CompletableFuture future = new CompletableFuture<>(); res.whenComplete( - (getObjectResponse, throwable) -> { + (paginatedObjectsResponse, throwable) -> { if (throwable != null) { - completableFuture.complete(throwable); + future.complete(throwable); + } else { + future.complete(paginatedObjectsResponse); } }); + System.out.println(future.get()); - assertEquals( - ErrorCode.INVALID_PARAMS, ((SuiApiException) completableFuture.get()).getError().getCode()); - } - - /** - * Gets objects owned by address is not empty. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getObjectsOwnedByAddress returns not empty list.") - void getObjectsOwnedByAddressIsNotEmpty() throws ExecutionException, InterruptedException { - CompletableFuture> res = - client.getObjectsOwnedByAddress("0xea79464d86786b7a7a63e3f13f798f29f5e65947"); - List response = res.get(); - System.out.println(response); + ObjectDataFilter.MoveModuleFilter moduleFilter = new MoveModuleFilter(); + MoveModule moveModule = new MoveModule(); + moveModule.setModule("coin"); + moveModule.setSuiPackage("0x0000000000000000000000000000000000000002"); + moduleFilter.setMoveModule(moveModule); + ObjectResponseQuery query1 = new ObjectResponseQuery(); + query1.setFilter(moduleFilter); + query1.setOptions(objectDataOptions); + CompletableFuture res1 = + client.getObjectsOwnedByAddress( + "0xb43d0468fbc80c81931b73a4b9ef4663e671b65a07ae5b336a0e7d8a70ac0646", + query1, + null, + null, + null); + CompletableFuture future1 = new CompletableFuture<>(); + res1.whenComplete( + (paginatedObjectsResponse, throwable) -> { + if (throwable != null) { + future1.complete(throwable); + } else { + future1.complete(paginatedObjectsResponse); + } + }); + System.out.println(future1.get()); // assertTrue(response.size() > 0); // assertEquals( // "0xea79464d86786b7a7a63e3f13f798f29f5e65947", @@ -203,48 +153,6 @@ void getObjectsOwnedByAddressIsNotEmpty() throws ExecutionException, Interrupted // response.get(0).getPreviousTransaction()); } - /** - * Gets objects owned by object is empty. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getObjectsOwnedByObject returns empty list.") - void getObjectsOwnedByObjectIsEmpty() throws ExecutionException, InterruptedException { - CompletableFuture> res = - client.getObjectsOwnedByObject("0xde2952390ab3d0cfbb0a0602532480ed5ec99cf3"); - List response = res.get(); - System.out.println(response); - // assertEquals(0, response.size()); - } - - /** - * Gets raw object existing move object. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getRawObject returns existing move object.") - void getRawObjectExistingMoveObject() throws ExecutionException, InterruptedException { - CompletableFuture res = - client.getRawObject("0x342950ba2451c2f27ed128e591c2b4551e5177c2"); - ObjectResponse response = res.get(); - System.out.println(response); - // assertEquals(ObjectStatus.Exists, response.getStatus()); - // SuiObject suiObject = (SuiObject) response.getDetails(); - // SuiData.MoveObject moveObject = (SuiData.MoveObject) suiObject.getData(); - // assertEquals("0x2::coin::Coin<0x2::sui::SUI>", moveObject.getType()); - // SuiObjectOwner.AddressOwner addressOwner = (SuiObjectOwner.AddressOwner) - // suiObject.getOwner(); - // assertEquals("0xea79464d86786b7a7a63e3f13f798f29f5e65947", - // addressOwner.getAddressOwner()); - // assertEquals("NClQuiRRwvJ+0SjlkcK0VR5Rd8LQN3oQ81oAAA==", moveObject.getBcs_bytes()); - // SuiObjectRef suiObjectRef = suiObject.getReference(); - // assertEquals("QZMMmu37jER7FFU3+HhbdwIyZyOwwThNAa07vSsPBGw=", suiObjectRef.getDigest()); - } - /** * Gets total transaction number. * @@ -252,9 +160,9 @@ void getRawObjectExistingMoveObject() throws ExecutionException, InterruptedExce * @throws InterruptedException the interrupted exception */ @Test - @DisplayName("Test getTotalTransactionNumber.") + @DisplayName("Test getTotalTransactionBlocks.") void getTotalTransactionNumber() throws ExecutionException, InterruptedException { - CompletableFuture res = client.getTotalTransactionNumber(); + CompletableFuture res = client.getTotalTransactionBlocks(); System.out.println(res.get()); // assertEquals(2L, res.get()); } @@ -266,17 +174,17 @@ void getTotalTransactionNumber() throws ExecutionException, InterruptedException * @throws InterruptedException the interrupted exception */ @Test - @DisplayName("Test getTransaction.") + @DisplayName("Test getTransactionBlock.") void getTransaction() throws ExecutionException, InterruptedException { - TransactionResponseOptions options = new TransactionResponseOptions(); + TransactionBlockResponseOptions options = new TransactionBlockResponseOptions(); options.setShowEffects(true); options.setShowEvents(true); options.setShowObjectChanges(true); options.setShowInput(true); - CompletableFuture res = - client.getTransaction("2zcrJHVMnqjQ47iauQsSqdDzpJVKzTrrohu4mYcGr2JG", options); - TransactionResponse transactionResponse = res.get(); - System.out.println(transactionResponse); + CompletableFuture res = + client.getTransactionBlock("2zcrJHVMnqjQ47iauQsSqdDzpJVKzTrrohu4mYcGr2JG", options); + TransactionBlockResponse transactionBlockResponse = res.get(); + System.out.println(transactionBlockResponse); // TransactionResponse transactionResponse = res.get(); // System.out.println(transactionResponse); // assertEquals(1, @@ -292,10 +200,12 @@ void getTransaction() throws ExecutionException, InterruptedException { // "3Dda4/74LXf6GmOxMxp3qdbW/WdQ6/8EHobZ1LvSyYk=", // transactionResponse.getCertificate().getTransactionDigest()); // - // assertEquals(1, transactionResponse.getCertificate().getData().getTransactions().size()); + // assertEquals(1, + // transactionResponse.getCertificate().getData().queryTransactionBlocks().size()); // MoveCall call = // ((TransactionKind.CallTransactionKind) - // transactionResponse.getCertificate().getData().getTransactions().get(0)) + // + // transactionResponse.getCertificate().getData().queryTransactionBlocks().get(0)) // .getCall(); // assertEquals("devnet_nft", call.getModule()); // assertEquals("mint", call.getFunction()); @@ -345,13 +255,13 @@ void getTransaction() throws ExecutionException, InterruptedException { @Test @DisplayName("Test getTransactionAuthSigners.") void getTransactionAuthSigners() throws ExecutionException, InterruptedException { - TransactionResponseOptions options = new TransactionResponseOptions(); + TransactionBlockResponseOptions options = new TransactionBlockResponseOptions(); options.setShowEffects(true); options.setShowEvents(true); options.setShowObjectChanges(true); options.setShowInput(true); - CompletableFuture res = - client.getTransaction("49rpBTf2KUkf4aroydtZGAb5rsLGYoutoEPowNu3962q", options); + CompletableFuture res = + client.getTransactionBlock("49rpBTf2KUkf4aroydtZGAb5rsLGYoutoEPowNu3962q", options); CompletableFuture future = new CompletableFuture<>(); res.whenComplete( (transactionResponse, throwable) -> { @@ -364,21 +274,6 @@ void getTransactionAuthSigners() throws ExecutionException, InterruptedException System.out.println(future.get()); } - /** - * Gets transactions in range. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getTransactionsInRange.") - void getTransactionsInRange() throws ExecutionException, InterruptedException { - CompletableFuture> res = client.getTransactionsInRange(0L, 100L); - System.out.println(res.get()); - // assertEquals(2, res.get().size()); - // assertEquals("GN9sW4hBVNFIc83VIfyn/J1n4a9tU9sQVq3+UkfgEKU=", res.get().get(1)); - } - /** * Gets sui system state. * @@ -544,18 +439,22 @@ void tryGetPastObject() throws ExecutionException, InterruptedException { * @throws InterruptedException the interrupted exception */ @Test - @DisplayName("Test getTransactions.") - void getTransactions() throws ExecutionException, InterruptedException { - TransactionQuery query = AllQuery.All; - CompletableFuture res = - client.getTransactions(query, null, 10, false); - System.out.println(res.get()); + @DisplayName("Test queryTransactionBlocks.") + void queryTransactionBlocks() throws ExecutionException, InterruptedException { + TransactionBlockResponseQuery query = new TransactionBlockResponseQuery(); + CompletableFuture res = + client.queryTransactionBlocks(query, null, 10, false); - FromAddressQuery query1 = new FromAddressQuery(); - query1.setFromAddress("0xea79464d86786b7a7a63e3f13f798f29f5e65947"); - CompletableFuture res1 = - client.getTransactions(query1, null, 10, false); - System.out.println(res1.get()); + CompletableFuture future = new CompletableFuture<>(); + res.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + System.out.println(future.get()); } /** @@ -571,66 +470,66 @@ void getCoinMetadata() throws ExecutionException, InterruptedException { System.out.println(res.get()); } - /** - * Gets all balances. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getAllBalances.") - void getAllBalances() throws ExecutionException, InterruptedException { - Optional address = getFirstAddress(); - CompletableFuture> res = client.getAllBalances(address.get()); - System.out.println(res.get()); - List balances = res.get(); - assertTrue(balances.size() != 0); - } - - /** - * Gets all coins. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getAllCoins.") - void getAllCoins() throws ExecutionException, InterruptedException { - Optional address = getFirstAddress(); - CompletableFuture res = client.getAllCoins(address.get(), null, 10); - System.out.println(res.get()); - assertNotNull(res.get()); - } - - /** - * Gets coins. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getCoins.") - void getCoins() throws ExecutionException, InterruptedException { - Optional address = getFirstAddress(); - CompletableFuture res = - client.getCoins(address.get(), QueryClient.DEFAULT_COIN_TYPE, null, 10); - System.out.println(res.get()); - } - - /** - * Gets balance. - * - * @throws ExecutionException the execution exception - * @throws InterruptedException the interrupted exception - */ - @Test - @DisplayName("Test getBalance.") - void getBalance() throws ExecutionException, InterruptedException { - Optional address = getFirstAddress(); - CompletableFuture res = - client.getBalance(address.get(), QueryClient.DEFAULT_COIN_TYPE); - System.out.println(res.get()); - } + // /** + // * Gets all balances. + // * + // * @throws ExecutionException the execution exception + // * @throws InterruptedException the interrupted exception + // */ + // @Test + // @DisplayName("Test getAllBalances.") + // void getAllBalances() throws ExecutionException, InterruptedException { + // Optional address = getFirstAddress(); + // CompletableFuture> res = client.getAllBalances(address.get()); + // System.out.println(res.get()); + // List balances = res.get(); + // assertTrue(balances.size() != 0); + // } + + // /** + // * Gets all coins. + // * + // * @throws ExecutionException the execution exception + // * @throws InterruptedException the interrupted exception + // */ + // @Test + // @DisplayName("Test getAllCoins.") + // void getAllCoins() throws ExecutionException, InterruptedException { + // Optional address = getFirstAddress(); + // CompletableFuture res = client.getAllCoins(address.get(), null, 10); + // System.out.println(res.get()); + // assertNotNull(res.get()); + // } + + // /** + // * Gets coins. + // * + // * @throws ExecutionException the execution exception + // * @throws InterruptedException the interrupted exception + // */ + // @Test + // @DisplayName("Test getCoins.") + // void getCoins() throws ExecutionException, InterruptedException { + // Optional address = getFirstAddress(); + // CompletableFuture res = + // client.getCoins(address.get(), QueryClient.DEFAULT_COIN_TYPE, null, 10); + // System.out.println(res.get()); + // } + + // /** + // * Gets balance. + // * + // * @throws ExecutionException the execution exception + // * @throws InterruptedException the interrupted exception + // */ + // @Test + // @DisplayName("Test getBalance.") + // void getBalance() throws ExecutionException, InterruptedException { + // Optional address = getFirstAddress(); + // CompletableFuture res = + // client.getBalance(address.get(), QueryClient.DEFAULT_COIN_TYPE); + // System.out.println(res.get()); + // } /** * Gets checkpoint contents. diff --git a/src/integrationTest/java/io/sui/SuiIntTests.java b/src/integrationTest/java/io/sui/SuiIntTests.java index 6a78fea..81eb52c 100644 --- a/src/integrationTest/java/io/sui/SuiIntTests.java +++ b/src/integrationTest/java/io/sui/SuiIntTests.java @@ -15,6 +15,7 @@ */ package io.sui; + // // import static org.junit.jupiter.api.Assertions.assertNotNull; // @@ -38,643 +39,633 @@ // import java.util.List; // import java.util.Optional; // import java.util.concurrent.CompletableFuture; -// import java.util.concurrent.ExecutionException; -// import org.junit.jupiter.api.Assertions; -// import org.junit.jupiter.api.BeforeAll; -// import org.junit.jupiter.api.DisplayName; -// import org.junit.jupiter.api.Test; -// -/// ** -// * The type Sui int tests. -// * -// * @author grapebaba -// * @since 2022.11 -// */ -// public class SuiIntTests { -// -// private static final String BASE_URL = "http://localhost:9000"; -// -// private static final String TEST_KEY_STORE_PATH = -// System.getProperty("user.home") + "/.sui/sui_config/sui.keystore"; -// -// private static Sui sui; -// -// /** Before all. */ -// @BeforeAll -// static void beforeAll() { -// sui = new Sui(BASE_URL, TEST_KEY_STORE_PATH, true); -// } -// -// /** -// * Gets objects owned by address. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test getObjectsOwnedByAddress.") -// void getObjectsOwnedByAddress() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List response = res.get(); -// System.out.println(response); -// } -// -// /** -// * Transfer sui. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @SuppressWarnings("checkstyle:CommentsIndentation") -// @Test -// @DisplayName("Test transferSui.") -//// void transferSui() throws ExecutionException, InterruptedException { -//// final String scep256k1sender = -//// sui.addresses().stream() -//// .filter(s -> sui.getByAddress(s) instanceof SECP256K1KeyPair) -//// .findFirst() -//// .get(); -//// final String ed25519sender = -//// sui.addresses().stream() -//// .filter(s -> sui.getByAddress(s) instanceof ED25519KeyPair) -//// .findFirst() -//// .get(); -//// CompletableFuture> res = sui.getObjectsOwnedByAddress(ed25519sender); -//// List objects = res.get(); -//// String coinObjectId = objects.get(0).getObjectId(); -//// -//// // ED25519 KEY -//// CompletableFuture res2 = -//// sui.transferSui( -//// ed25519sender, -//// coinObjectId, -//// 2000L, -//// scep256k1sender, -//// 20000L, -//// ExecuteTransactionRequestType.WaitForLocalExecution); -//// CompletableFuture future = new CompletableFuture<>(); -//// res2.whenComplete( -//// (transactionResponse, throwable) -> { -//// if (throwable != null) { -//// future.complete(throwable); -//// } else { -//// future.complete(transactionResponse); -//// } -//// }); -//// -//// System.out.println(future.get()); -//// assertNotNull( -//// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -//// .getEffectsCert() -//// .getCertificate() -//// .getTransactionDigest()); -//// -//// CompletableFuture> res1 = sui.getObjectsOwnedByAddress(scep256k1sender); -//// List objects1 = res1.get(); -//// String coinObjectId1 = objects1.get(0).getObjectId(); -//// // SCEP256K1 KEY -//// CompletableFuture res3 = -//// sui.transferSui( -//// scep256k1sender, -//// coinObjectId1, -//// 1000L, -//// ed25519sender, -//// 10000L, -//// ExecuteTransactionRequestType.WaitForLocalExecution); -//// CompletableFuture future1 = new CompletableFuture<>(); -//// res3.whenComplete( -//// (transactionResponse, throwable) -> { -//// if (throwable != null) { -//// future1.complete(throwable); -//// } else { -//// future1.complete(transactionResponse); -//// } -//// }); -//// -//// System.out.println(future1.get()); -//// assertNotNull( -//// ((ExecuteTransactionResponse.EffectsCertResponse) future1.get()) -//// .getEffectsCert() -//// .getCertificate() -//// .getTransactionDigest()); -//// } -// -// /** -// * Move call. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test moveCall.") -// void moveCall() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture res = -// sui.moveCall( -// sender.get(), -// "0x0000000000000000000000000000000000000002", -// "devnet_nft", -// "mint", -// Lists.newArrayList(), -// Lists.newArrayList( -// "Example NFT", -// "An example NFT.", -// "ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty"), -// null, -// 2000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Batch transaction. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test batchTransaction.") -// void batchTransaction() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// -// RPCTransactionRequestParams.MoveCallParams moveCallParams = new MoveCallParams(); -// moveCallParams.setArguments( -// Lists.newArrayList( -// "Example NFT", -// "An example NFT.", -// "ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty")); -// moveCallParams.setTypeArguments(Lists.newArrayList()); -// moveCallParams.setPackageObjectId("0x0000000000000000000000000000000000000002"); -// moveCallParams.setModule("devnet_nft"); -// moveCallParams.setFunction("mint"); -// RPCTransactionRequestParams.MoveCallRequestParams moveCallRequestParams = -// new MoveCallRequestParams(); -// moveCallRequestParams.setMoveCallRequestParams(moveCallParams); -// -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// String coinObjectId = objects.get(0).getObjectId(); -// List addresses = new ArrayList<>(sui.addresses()); -// RPCTransactionRequestParams.TransferObjectParams transferObjectParams = -// new TransferObjectParams(); -// transferObjectParams.setObjectId(coinObjectId); -// transferObjectParams.setRecipient(addresses.get(3)); -// RPCTransactionRequestParams.TransferObjectRequestParams transferObjectRequestParams = -// new TransferObjectRequestParams(); -// transferObjectRequestParams.setTransferObjectRequestParams(transferObjectParams); -// CompletableFuture res1 = -// sui.batchTransaction( -// sender.get(), -// Lists.newArrayList(moveCallRequestParams, transferObjectRequestParams), -// null, -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Pay sui. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test paySui.") -// void paySui() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// String coinObjectId = objects.get(0).getObjectId(); -// List addresses = new ArrayList<>(sui.addresses()); -// CompletableFuture res1 = -// sui.paySui( -// sender.get(), -// Lists.newArrayList(coinObjectId), -// Lists.newArrayList(addresses.get(4), addresses.get(5)), -// Lists.newArrayList(1000L, 1000L), -// 500L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Split coin. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test splitCoin.") -// void splitCoin() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// String coinObjectId = objects.get(0).getObjectId(); -// CompletableFuture res1 = -// sui.splitCoin( -// sender.get(), -// coinObjectId, -// Lists.newArrayList(100000L, 200000L, 100000L), -// null, -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Split coin equal. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test splitCoinEqual.") -// void splitCoinEqual() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// String coinObjectId = objects.get(0).getObjectId(); -// String gasCoinObjectId = objects.get(1).getObjectId(); -// CompletableFuture res1 = -// sui.splitCoinEqual( -// sender.get(), -// coinObjectId, -// 5L, -// null, -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Merge coins. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test mergeCoins.") -// void mergeCoins() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// String primaryCoinObjectId = objects.get(0).getObjectId(); -// String toMergeCoinObjectId = objects.get(1).getObjectId(); -// CompletableFuture res1 = -// sui.mergeCoins( -// sender.get(), -// primaryCoinObjectId, -// toMergeCoinObjectId, -// null, -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Pay all sui. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test payAllSui.") -// void payAllSui() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// if (!sender.isPresent()) { -// Assertions.fail(); -// } -// CompletableFuture> res = sui.getObjectsOwnedByAddress(sender.get()); -// List objects = res.get(); -// List addresses = new ArrayList<>(sui.addresses()); -// String coinObjectId = objects.get(0).getObjectId(); -// CompletableFuture res1 = -// sui.payAllSui( -// sender.get(), -// Lists.newArrayList(coinObjectId), -// addresses.get(6), -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// /** -// * Transfer object. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test transferObject.") -// void transferObject() throws ExecutionException, InterruptedException { -// final Optional sender = -// sui.addresses().stream() -// .filter( -// s -> { -// try { -// return sui.getObjectsOwnedByAddress(s).get().size() > 1; -// } catch (InterruptedException | ExecutionException e) { -// return false; -// } -// }) -// .findFirst(); -// -// if (sender.isPresent()) { -// final Optional receipt = -// sui.addresses().stream().filter(s -> !s.equals(sender.get())).findFirst(); -// if (receipt.isPresent()) { -// List objects = sui.getObjectsOwnedByAddress(sender.get()).get(); -// CompletableFuture res = -// sui.transferObject( -// sender.get(), -// objects.get(0).getObjectId(), -// receipt.get(), -// null, -// 3000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// -// System.out.println(res.get()); -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) res.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } else { -// Assertions.fail(); -// } -// } else { -// Assertions.fail(); -// } -// } -// -// /** -// * Publish. -// * -// * @throws ExecutionException the execution exception -// * @throws InterruptedException the interrupted exception -// */ -// @Test -// @DisplayName("Test publish.") -// void publish() throws ExecutionException, InterruptedException { -// -// CompletableFuture res1 = -// sui.publish( -// sui.addresses().first(), -// Lists.newArrayList( -// "oRzrCwYAAAAKAQAIAggMAxQuBEICBUQrB2+IAQj3ASgKnwIKDKkCkwEN" -// + "vAMEAAABAQECAQMABAgAAwYCAAENBAAABQABAAAHAgEAAAgDAQAACQQFAAAK" -// + "BgEAAAsEBwABDgIIAAMPCQUAAhALAQEICAoCBggAAwABBwgBAQcIAAEGCAAB" -// + "BQMHCAADBwgBAQMBCAIBBggBAQgAAQkAB2NvdW50ZXIGb2JqZWN0CHRyYW5z" -// + "ZmVyCnR4X2NvbnRleHQHQ291bnRlcgxhc3NlcnRfdmFsdWUJVHhDb250ZXh0" -// + "BmNyZWF0ZQlpbmNyZW1lbnQFb3duZXIJc2V0X3ZhbHVlBXZhbHVlAmlkA1VJ" -// + "RANuZXcGc2VuZGVyDHNoYXJlX29iamVjdAAAAAAAAAAAAAAAAAAAAAAAAAAA" -// + "AAAAAAAAAAAAAAAAAAAAAAAAAAIAAgMMCAIJBQsDAAEEAAEJCwAQABQLASED" -// + "CAYAAAAAAAAAACcCAQEEAAEJCgARBgsALhEHBgAAAAAAAAAAEgA4AAICAQQA" -// + "AQkKABAAFAYBAAAAAAAAABYLAA8AFQIDAQAAAQQLABABFAIEAQQAAREKABAB" -// + "FAsCLhEHIQMMCwABBgAAAAAAAAAAJwsBCwAPABUCBQEAAAEECwAQABQCAAIAAQA="), -// null, -// 5000L, -// ExecuteTransactionRequestType.WaitForLocalExecution); -// CompletableFuture future = new CompletableFuture<>(); -// res1.whenComplete( -// (transactionResponse, throwable) -> { -// if (throwable != null) { -// future.complete(throwable); -// } else { -// future.complete(transactionResponse); -// } -// }); -// -// System.out.println(future.get()); -// -// assertNotNull( -// ((ExecuteTransactionResponse.EffectsCertResponse) future.get()) -// .getEffectsCert() -// .getCertificate() -// .getTransactionDigest()); -// } -// -// @Test -// @DisplayName("Test subscribeEvent.") -// void subscribeEvent() throws ExecutionException, InterruptedException { -// EventTypeEventFilter eventFilter = new EventTypeEventFilter(); -// eventFilter.setEventType(EventType.CoinBalanceChange); -// Disposable disposable = -// sui.subscribeEvent( -// eventFilter, -// System.out::println, -// System.out::println); -// moveCall(); -// -// disposable.dispose(); -// } -// } + + +import com.google.common.collect.Lists; +import io.sui.crypto.KeyResponse; +import io.sui.crypto.SignatureScheme; +import io.sui.models.FaucetResponse; +import io.sui.models.objects.ObjectDataOptions; +import io.sui.models.objects.ObjectResponseQuery; +import io.sui.models.objects.PaginatedObjectsResponse; +import io.sui.models.objects.SuiObjectResponse; +import io.sui.models.transactions.ExecuteTransactionRequestType; +import io.sui.models.transactions.PaginatedTransactionResponse; +import io.sui.models.transactions.StructTag; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; +import io.sui.models.transactions.TransactionBlockResponseQuery; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * The type Sui int tests. + * + * @author grapebaba + * @since 2022.11 + */ +public class SuiIntTests { + + private static final String BASE_URL = "http://localhost:9000"; + + private static final String BASE_FAUCET_URL = "http://localhost:9123"; + // private static final String BASE_FAUCET_URL = "https://faucet.testnet.sui.io"; + + // private static final String TEST_KEY_STORE_PATH = + // System.getProperty("user.home") + "/.sui/sui_config/sui.keystore"; + + private static final String TEST_KEY_STORE_PATH = + Paths.get("src/integrationTest/sui.keystore").toAbsolutePath().toString(); + + private static Sui sui; + + /** Before all. */ + @BeforeAll + static void beforeAll() { + sui = new Sui(BASE_URL, BASE_FAUCET_URL, TEST_KEY_STORE_PATH, true); + } + + /** New address. */ + @Test + @DisplayName("Test newAddress.") + void newAddress() { + KeyResponse res1 = sui.newAddress(SignatureScheme.ED25519); + System.out.printf("mnemonic+address:%s%n", res1); + System.out.println(); + + KeyResponse res2 = sui.newAddress(SignatureScheme.ED25519); + System.out.printf("mnemonic+address:%s%n", res2); + System.out.println(); + + KeyResponse res3 = sui.newAddress(SignatureScheme.ED25519); + System.out.printf("mnemonic+address:%s%n", res3); + System.out.println(); + + KeyResponse res4 = sui.newAddress(SignatureScheme.Secp256k1); + System.out.printf("mnemonic+address:%s%n", res4); + System.out.println(); + + KeyResponse res5 = sui.newAddress(SignatureScheme.Secp256k1); + System.out.printf("mnemonic+address:%s%n", res5); + System.out.println(); + } + + /** Request sui from faucet. */ + @Test + @DisplayName("Test requestSuiFromFaucet.") + void requestSuiFromFaucet() { + sui.addresses() + .forEach( + s -> { + System.out.printf("address:%s%n", s); + CompletableFuture res = sui.requestSuiFromFaucet(s); + try { + System.out.printf("faucet response: %s%n%n", res.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + Assertions.fail(); + } + }); + } + + /** + * Gets objects owned by address. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test getObjectsOwnedByAddress.") + void getObjectsOwnedByAddress() throws ExecutionException, InterruptedException { + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress( + s, new ObjectResponseQuery(), null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + CompletableFuture res = + sui.getObjectsOwnedByAddress(sender.get(), new ObjectResponseQuery(), null, null, null); + System.out.printf("paginated objects:%s%n", res.get()); + } + + /** + * Transfer sui. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @SuppressWarnings("checkstyle:CommentsIndentation") + @Test + @DisplayName("Test transferSui.") + void transferSui() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + objectResponseQuery.setOptions(new ObjectDataOptions()); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + + final Optional recipient = + sui.addresses().stream().filter(s -> !s.equals(sender.get())).findFirst(); + if (!recipient.isPresent()) { + Assertions.fail(); + } + + TransactionBlockResponseOptions transactionBlockResponseOptions = + new TransactionBlockResponseOptions(); + transactionBlockResponseOptions.setShowEffects(true); + transactionBlockResponseOptions.setShowEvents(true); + transactionBlockResponseOptions.setShowInput(true); + transactionBlockResponseOptions.setShowObjectChanges(true); + CompletableFuture res2 = + sui.transferSui( + sender.get(), + null, + recipient.get(), + 2000L, + null, + 5000L, + null, + null, + transactionBlockResponseOptions, + ExecuteTransactionRequestType.WaitForLocalExecution); + CompletableFuture future = new CompletableFuture<>(); + res2.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + + System.out.println(future.get()); + } + + /** + * Move call. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test moveCall.") + void moveCall() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + final SuiObjectResponse suiObjectResponse = + sui.getObjectsOwnedByAddress(sender.get(), objectResponseQuery, null, null, null) + .get() + .getData() + .get(0); + TransactionBlockResponseOptions transactionBlockResponseOptions = + new TransactionBlockResponseOptions(); + transactionBlockResponseOptions.setShowEffects(true); + transactionBlockResponseOptions.setShowEvents(true); + transactionBlockResponseOptions.setShowInput(true); + transactionBlockResponseOptions.setShowObjectChanges(true); + + final io.sui.models.transactions.TypeTag.StructType structType = + new io.sui.models.transactions.TypeTag.StructType(); + io.sui.models.transactions.StructTag structTag = new StructTag(); + structTag.setAddress("0x02"); + structTag.setModule("sui"); + structTag.setName("SUI"); + structType.setStructTag(structTag); + CompletableFuture res = + sui.moveCall( + sender.get(), + "0x02", + "pay", + "split", + Lists.newArrayList(structType), + Lists.newArrayList(suiObjectResponse.getData().getObjectId(), 10000L), + null, + 10000L, + null, + null, + transactionBlockResponseOptions, + ExecuteTransactionRequestType.WaitForLocalExecution); + CompletableFuture future = new CompletableFuture<>(); + res.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + + System.out.println(future.get()); + } + + /** + * Merge coin. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test mergeCoin.") + void mergeCoin() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 3; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + + TransactionBlockResponseOptions transactionBlockResponseOptions = + new TransactionBlockResponseOptions(); + transactionBlockResponseOptions.setShowEffects(true); + transactionBlockResponseOptions.setShowEvents(true); + transactionBlockResponseOptions.setShowInput(true); + transactionBlockResponseOptions.setShowObjectChanges(true); + + String dest = + sui.getObjectsOwnedByAddress(sender.get(), objectResponseQuery, null, null, null) + .get() + .getData() + .get(0) + .getData() + .getObjectId(); + List source = + sui.getObjectsOwnedByAddress(sender.get(), objectResponseQuery, null, null, null).get() + .getData().subList(1, 2).stream() + .map(suiObjectResponse -> suiObjectResponse.getData().getObjectId()) + .collect(Collectors.toList()); + CompletableFuture res = + sui.mergeCoin( + sender.get(), + dest, + source, + null, + 5000L, + null, + null, + transactionBlockResponseOptions, + ExecuteTransactionRequestType.WaitForLocalExecution); + CompletableFuture future = new CompletableFuture<>(); + res.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + + System.out.println(future.get()); + } + + /** + * Transfer object. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test transferObject.") + void transferObjects() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + objectResponseQuery.setOptions(new ObjectDataOptions()); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + + if (sender.isPresent()) { + final Optional receipt = + sui.addresses().stream().filter(s -> !s.equals(sender.get())).findFirst(); + if (receipt.isPresent()) { + List objects = + sui.getObjectsOwnedByAddress(sender.get(), objectResponseQuery, null, null, null) + .get() + .getData(); + TransactionBlockResponseOptions transactionBlockResponseOptions = + new TransactionBlockResponseOptions(); + transactionBlockResponseOptions.setShowEffects(true); + transactionBlockResponseOptions.setShowEvents(true); + transactionBlockResponseOptions.setShowInput(true); + transactionBlockResponseOptions.setShowObjectChanges(true); + CompletableFuture res = + sui.transferObjects( + sender.get(), + Lists.newArrayList(objects.get(0).getData().getObjectId()), + receipt.get(), + null, + 3000L, + null, + null, + transactionBlockResponseOptions, + ExecuteTransactionRequestType.WaitForLocalExecution); + CompletableFuture future = new CompletableFuture<>(); + res.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + System.out.println(future.get()); + + } else { + Assertions.fail(); + } + } else { + Assertions.fail(); + } + } + + /** + * Publish. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test publish.") + void publish() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + objectResponseQuery.setOptions(new ObjectDataOptions()); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + TransactionBlockResponseOptions transactionBlockResponseOptions = + new TransactionBlockResponseOptions(); + transactionBlockResponseOptions.setShowEffects(true); + transactionBlockResponseOptions.setShowEvents(true); + transactionBlockResponseOptions.setShowInput(true); + transactionBlockResponseOptions.setShowObjectChanges(true); + CompletableFuture res1 = + sui.publish( + sender.get(), + Lists.newArrayList( + "oRzrCwYAAAAKAQAUAhQsA0BJBIkBEgWbAWcHggLNAgjPBGAGrwXCAwrxCC0MngnUAQAMAR4B" + + "JAIRAh0CHwIlAiYCJwIoAAACAAABDAAAAwQAAQQHAQAAAgYHAAMCDAEIAQQIBAAFBQwABwcCAAkJ" + + "BwAAFgABAAEcARUBAAEjFBUBAAIpCwwAAwoNAQEIAxoJCgEIBBoSEwAFDgYHAQIGIREBAQwGJREB" + + "AQgHIg4PAAgXBAUBAgkbCxYACwMHAwUIBAgIEAgHAgwBDAkIAggABwgIAAILBQEIAQgHAQgAAQYJ" + + "AAEBAgkABwgIAQgHAQgBAgYIBwcICAELBQEJAAEKAgEIBAMHCwUBCQAKCAQKCAQBBggIAQUBCwUB" + + "CAECCQAFAQcICAEIBgEJAAELAwEJAAEICQVCT0FSUwRCb2FyB0Rpc3BsYXkITWV0YWRhdGEGT3B0" + + "aW9uCVB1Ymxpc2hlcgZTdHJpbmcJVHhDb250ZXh0A1VJRANVcmwMYWRkX211bHRpcGxlA2FnZQVi" + + "b2FycwVidXllcgVjbGFpbQdjcmVhdG9yC2Rlc2NyaXB0aW9uB2Rpc3BsYXkLZHVtbXlfZmllbGQI" + + "ZnVsbF91cmwCaWQHaW1nX3VybARpbml0E2lzX29uZV90aW1lX3dpdG5lc3MIbWV0YWRhdGEEbmFt" + + "ZQNuZXcVbmV3X3Vuc2FmZV9mcm9tX2J5dGVzBG5vbmUGb2JqZWN0Bm9wdGlvbgdwYWNrYWdlBXBy" + + "aWNlD3B1YmxpY190cmFuc2ZlcgZzZW5kZXIEc29tZQZzdHJpbmcIdHJhbnNmZXIKdHhfY29udGV4" + + "dAV0eXBlcwN1cmwEdXRmOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgMI" + + "AAAAAAAAAAAKAgUEbmFtZQoCDAtkZXNjcmlwdGlvbgoCCAdpbWdfdXJsCgIIB2NyZWF0b3IKAgYF" + + "cHJpY2UKAgwLcHJvamVjdF91cmwKAgQDYWdlCgIGBWJ1eWVyCgIJCGZ1bGxfdXJsCgIODWVzY2Fw" + + "ZV9zeW50YXgKAgcGe25hbWV9CgI7OlVuaXF1ZSBCb2FyIGZyb20gdGhlIEJvYXJzIGNvbGxlY3Rp" + + "b24gd2l0aCB7bmFtZX0gYW5kIHtpZH0KAiEgaHR0cHM6Ly9nZXQtYS1ib2FyLmNvbS97aW1nX3Vy" + + "bH0KAgoJe2NyZWF0b3J9CgIIB3twcmljZX0KAhgXaHR0cHM6Ly9nZXQtYS1ib2FyLmNvbS8KAg8O" + + "e21ldGFkYXRhLmFnZX0KAggHe2J1eWVyfQoCCwp7ZnVsbF91cmx9CgIJCFx7bmFtZVx9CgIKCWZp" + + "cnN0LnBuZwoCCwpGaXJzdCBCb2FyCgImJUZpcnN0IEJvYXIgZnJvbSB0aGUgQm9hcnMgY29sbGVj" + + "dGlvbiEKAgYFQ2hyaXMKAiAfaHR0cHM6Ly9nZXQtYS1ib2FyLmZ1bGx1cmwuY29tLwACARIBAQIJ" + + "FAgGFQgEGQgEEAgEDwsDAQgEIAsDAQgEGAgCDQUTCAkCAgELAwAAAAACXw4AOAAEBAUICwEBBwAn" + + "CwAKATgBDAMOAwoBOAIMAg0CBwERAwcCEQMHAxEDBwQRAwcFEQMHBhEDBwcRAwcIEQMHCREDBwoR" + + "A0AMCgAAAAAAAAAHCxEDBwwRAwcNEQMHDhEDBw8RAwcQEQMHEREDBxIRAwcTEQMHFBEDQAwKAAAA" + + "AAAAADgDCwIKAS4RCjgECwMKAS4RCjgFCgERBgcVEQMHFhEDBxcRAwcYEQM4BjgHBgoAAAAAAAAA" + + "EgIKAS4RCgcZEQwSAQsBLhEKOAgCAA=="), + Lists.newArrayList( + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002"), + null, + 10000L, + null, + null, + transactionBlockResponseOptions, + ExecuteTransactionRequestType.WaitForLocalExecution); + CompletableFuture future = new CompletableFuture<>(); + res1.whenComplete( + (transactionResponse, throwable) -> { + if (throwable != null) { + future.complete(throwable); + } else { + future.complete(transactionResponse); + } + }); + + System.out.println(future.get()); + } + + /** + * Gets total transaction number. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test getTotalTransactionBlocks.") + void getTotalTransactionBlocks() throws ExecutionException, InterruptedException { + CompletableFuture res = sui.getTotalTransactionBlocks(); + System.out.printf("total transaction blocks:%d%n", res.get()); + } + + /** + * Query transaction blocks. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test queryTransactionBlocks.") + void queryTransactionBlocks() throws ExecutionException, InterruptedException { + TransactionBlockResponseQuery query = new TransactionBlockResponseQuery(); + CompletableFuture res = + sui.queryTransactionBlocks(query, null, 10, false); + + System.out.printf("paginated transaction blocks:%s%n", res.get()); + } + + /** + * Gets transaction block. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test getTransactionBlock.") + void getTransactionBlock() throws ExecutionException, InterruptedException { + TransactionBlockResponseQuery query = new TransactionBlockResponseQuery(); + CompletableFuture res = + sui.queryTransactionBlocks(query, null, 10, false); + + TransactionBlockResponseOptions options = new TransactionBlockResponseOptions(); + options.setShowInput(true); + options.setShowEffects(true); + CompletableFuture res1 = + sui.getTransactionBlock(res.get().getData().get(2).getDigest(), options); + System.out.printf("transaction block:%s%n", res1.get()); + } + + /** + * Multi get transaction blocks. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test multiGetTransactionBlocks.") + void multiGetTransactionBlocks() throws ExecutionException, InterruptedException { + TransactionBlockResponseQuery query = new TransactionBlockResponseQuery(); + CompletableFuture res = + sui.queryTransactionBlocks(query, null, 10, false); + + TransactionBlockResponseOptions options = new TransactionBlockResponseOptions(); + options.setShowInput(true); + options.setShowEffects(true); + CompletableFuture> res1 = + sui.multiGetTransactionBlocks( + Lists.newArrayList( + res.get().getData().get(0).getDigest(), res.get().getData().get(1).getDigest()), + options); + System.out.printf("transaction blocks:%s%n", res1.get()); + } + + /** + * Multi get objects. + * + * @throws ExecutionException the execution exception + * @throws InterruptedException the interrupted exception + */ + @Test + @DisplayName("Test multiGetObjects.") + void multiGetObjects() throws ExecutionException, InterruptedException { + ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + objectResponseQuery.setOptions(new ObjectDataOptions()); + final Optional sender = + sui.addresses().stream() + .filter( + s -> { + try { + return sui.getObjectsOwnedByAddress(s, objectResponseQuery, null, null, null) + .get() + .getData() + .size() + > 1; + } catch (InterruptedException | ExecutionException e) { + return false; + } + }) + .findFirst(); + if (!sender.isPresent()) { + Assertions.fail(); + } + List objects = + sui.getObjectsOwnedByAddress(sender.get(), objectResponseQuery, null, null, null).get() + .getData().stream() + .map(suiObjectResponse -> suiObjectResponse.getData().getObjectId()) + .collect(Collectors.toList()); + CompletableFuture> res1 = + sui.multiGetObjects(objects, new ObjectDataOptions()); + System.out.printf("object responses:%s%n", res1.get()); + } + + // @Test + // @DisplayName("Test subscribeEvent.") + // void subscribeEvent() throws ExecutionException, InterruptedException { + // EventTypeEventFilter eventFilter = new EventTypeEventFilter(); + // eventFilter.setEventType(EventType.CoinBalanceChange); + // Disposable disposable = + // sui.subscribeEvent( + // eventFilter, + // System.out::println, + // System.out::println); + // moveCall(); + // + // disposable.dispose(); + // } +} diff --git a/src/main/java/io/sui/Sui.java b/src/main/java/io/sui/Sui.java index fe44e6d..8c51365 100644 --- a/src/main/java/io/sui/Sui.java +++ b/src/main/java/io/sui/Sui.java @@ -17,21 +17,30 @@ package io.sui; +import com.google.common.collect.Lists; import com.novi.serde.SerializationError; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.functions.Consumer; +import io.sui.bcsgen.Argument; import io.sui.bcsgen.Intent; +import io.sui.bcsgen.SuiAddress; +import io.sui.bcsgen.SuiAddress.Builder; import io.sui.bcsgen.TransactionData; import io.sui.clients.BcsSerializationException; import io.sui.clients.EventClient; import io.sui.clients.EventClientImpl; import io.sui.clients.ExecutionClient; import io.sui.clients.ExecutionClientImpl; +import io.sui.clients.FaucetClient; import io.sui.clients.JsonRpcTransactionBuilder; +import io.sui.clients.LocalTransactionBuilder; +import io.sui.clients.OkhttpFaucetClient; import io.sui.clients.QueryClient; import io.sui.clients.QueryClientImpl; +import io.sui.clients.TransactionBlock; import io.sui.clients.TransactionBuilder; import io.sui.crypto.FileBasedKeyStore; +import io.sui.crypto.KeyResponse; import io.sui.crypto.KeyStore; import io.sui.crypto.SignatureScheme; import io.sui.crypto.SigningException; @@ -40,6 +49,7 @@ import io.sui.jsonrpc.JsonHandler; import io.sui.jsonrpc.JsonRpcClientProvider; import io.sui.jsonrpc.OkHttpJsonRpcClientProvider; +import io.sui.models.FaucetResponse; import io.sui.models.SuiApiException; import io.sui.models.events.EventEnvelope; import io.sui.models.events.EventFilter; @@ -55,27 +65,29 @@ import io.sui.models.objects.MoveNormalizedFunction; import io.sui.models.objects.MoveNormalizedModule; import io.sui.models.objects.MoveNormalizedStruct; +import io.sui.models.objects.ObjectDataOptions; import io.sui.models.objects.ObjectResponse; +import io.sui.models.objects.ObjectResponseQuery; import io.sui.models.objects.PaginatedCoins; -import io.sui.models.objects.SuiObjectInfo; +import io.sui.models.objects.PaginatedObjectsResponse; import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiObjectResponse; import io.sui.models.objects.SuiSystemState; import io.sui.models.objects.ValidatorMetadata; import io.sui.models.transactions.ExecuteTransactionRequestType; -import io.sui.models.transactions.ExecuteTransactionResponse; -import io.sui.models.transactions.PaginatedTransactionDigests; -import io.sui.models.transactions.RPCTransactionRequestParams; +import io.sui.models.transactions.PaginatedTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; +import io.sui.models.transactions.TransactionBlockResponseQuery; import io.sui.models.transactions.TransactionBytes; import io.sui.models.transactions.TransactionEffects; -import io.sui.models.transactions.TransactionQuery; -import io.sui.models.transactions.TransactionResponse; -import io.sui.models.transactions.TransactionResponseOptions; import io.sui.models.transactions.TypeTag; import java.util.List; import java.util.Map; import java.util.NavigableSet; import java.util.concurrent.CompletableFuture; import java.util.function.Function; +import org.bouncycastle.jcajce.provider.digest.Blake2b.Blake2b256; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; @@ -97,292 +109,389 @@ public class Sui { private final EventClient eventClient; + private final FaucetClient faucetClient; + /** * Instantiates a new Sui. * - * @param rpcEndpoint the rpc endpoint + * @param fullNodeEndpoint the full node endpoint + * @param faucetEndpoint the faucet endpoint * @param keyStorePath the key store path */ - public Sui(String rpcEndpoint, String keyStorePath) { - this(rpcEndpoint, keyStorePath, true); + public Sui(String fullNodeEndpoint, String faucetEndpoint, String keyStorePath) { + this(fullNodeEndpoint, faucetEndpoint, keyStorePath, true); } /** * Instantiates a new Sui. * - * @param rpcEndpoint the rpc endpoint + * @param fullNodeEndpoint the full node endpoint + * @param faucetEndpoint the faucet endpoint * @param keyStorePath the key store path * @param useLocalTransactionBuilder the use local transaction builder */ - public Sui(String rpcEndpoint, String keyStorePath, boolean useLocalTransactionBuilder) { + public Sui( + String fullNodeEndpoint, + String faucetEndpoint, + String keyStorePath, + boolean useLocalTransactionBuilder) { this.keyStore = new FileBasedKeyStore(keyStorePath); final JsonHandler jsonHandler = new GsonJsonHandler(); final JsonRpcClientProvider jsonRpcClientProvider = - new OkHttpJsonRpcClientProvider(rpcEndpoint, jsonHandler); + new OkHttpJsonRpcClientProvider(fullNodeEndpoint, jsonHandler); this.queryClient = new QueryClientImpl(jsonRpcClientProvider); - this.transactionBuilder = new JsonRpcTransactionBuilder(jsonRpcClientProvider); - // this.transactionBuilder = - // useLocalTransactionBuilder - // ? new LocalTransactionBuilder(this.queryClient) - // : new JsonRpcTransactionBuilder(jsonRpcClientProvider); + this.transactionBuilder = + useLocalTransactionBuilder + ? new LocalTransactionBuilder(this.queryClient) + : new JsonRpcTransactionBuilder(jsonRpcClientProvider); this.executionClient = new ExecutionClientImpl(jsonRpcClientProvider); this.eventClient = new EventClientImpl(jsonRpcClientProvider); + this.faucetClient = new OkhttpFaucetClient(faucetEndpoint, jsonHandler); } /** - * Transfer sui completable future. + * Request sui from faucet completable future. * - * @param signer the signer - * @param coin the coin - * @param gasBudget the gas budget - * @param recipient the recipient - * @param amount the amount - * @param requestType the request type + * @param address the address * @return the completable future */ - public CompletableFuture transferSui( - String signer, - String coin, - long gasBudget, - String recipient, - long amount, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .transferSui(signer, coin, gasBudget, recipient, amount) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); + public CompletableFuture requestSuiFromFaucet(String address) { + return this.faucetClient.requestSuiFromFaucet(address); } /** - * Move call completable future. + * New address key response. * - * @param signer the signer - * @param packageObjectId the package object id - * @param module the module - * @param function the function - * @param typeArguments the type arguments - * @param arguments the arguments - * @param gas the gas - * @param gasBudget the gas budget - * @param requestType the request type - * @return the completable future + * @param signatureScheme the signature scheme + * @return the key response */ - public CompletableFuture moveCall( - String signer, - String packageObjectId, - String module, - String function, - List typeArguments, - List arguments, - String gas, - long gasBudget, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .moveCall( - signer, packageObjectId, module, function, typeArguments, arguments, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); + public KeyResponse newAddress(SignatureScheme signatureScheme) { + return this.keyStore.generateNewKey(signatureScheme); } /** - * Batch transaction completable future. + * Transfer sui completable future. * - * @param signer the signer - * @param batchTransactionParams the batch transaction params + * @param sender the signer + * @param coin the coin + * @param recipient the recipient + * @param amount the amount * @param gas the gas * @param gasBudget the gas budget + * @param gasPrice the gas price + * @param expiration the expiration + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture batchTransaction( - String signer, - List batchTransactionParams, + public CompletableFuture transferSui( + String sender, + String coin, + String recipient, + Long amount, String gas, - long gasBudget, + Long gasBudget, + Long gasPrice, + Long expiration, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .batchTransaction(signer, batchTransactionParams, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - - /** - * Pay sui completable future. + return this.newTransactionBlock() + .thenCompose( + (Function>) + transactionBlock -> { + transactionBlock.setExpiration(expiration); + transactionBlock.setSender(sender); + return transactionBlock + .splitCoins(coin, Lists.newArrayList(amount)) + .thenCompose( + (Function>) + argument -> { + SuiAddress.Builder recipientAddressBuilder = new Builder(); + recipientAddressBuilder.value = + transactionBlock.geAddressBytes(recipient); + transactionBlock.transferObjects( + Lists.newArrayList(argument), + transactionBlock.pure(recipientAddressBuilder.build())); + CompletableFuture + transactionDataCompletableFuture = + transactionBlock + .setGasData( + gas != null + ? Lists.newArrayList(gas) + : Lists.newArrayList(), + sender, + gasBudget, + gasPrice) + .thenCompose( + (Function>) + unused -> transactionBlock.build()); + + return transactionDataCompletableFuture.thenCompose( + (Function< + TransactionData, + CompletableFuture>) + transactionData -> + executeTransaction( + sender, transactionData, + transactionBlockResponseOptions, requestType)); + }); + }); + } + + /** + * New transaction block completable future. * - * @param signer the signer - * @param inputCoins the input coins - * @param recipients the recipients - * @param amounts the amounts - * @param gasBudget the gas budget - * @param requestType the request type * @return the completable future */ - public CompletableFuture paySui( - String signer, - List inputCoins, - List recipients, - List amounts, - long gasBudget, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .paySui(signer, inputCoins, recipients, amounts, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); + public CompletableFuture newTransactionBlock() { + return CompletableFuture.completedFuture(new TransactionBlock(queryClient)); } /** - * Pay completable future. + * Move call completable future. * - * @param signer the signer - * @param inputCoins the input coins - * @param recipients the recipients - * @param amounts the amounts + * @param sender the signer + * @param packageObjectId the package object id + * @param module the module + * @param function the function + * @param typeArguments the type arguments + * @param arguments the arguments * @param gas the gas * @param gasBudget the gas budget + * @param gasPrice the gas price + * @param expiration the expiration + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture pay( - String signer, - List inputCoins, - List recipients, - List amounts, + public CompletableFuture moveCall( + String sender, + String packageObjectId, + String module, + String function, + List typeArguments, + List arguments, String gas, - long gasBudget, + Long gasBudget, + Long gasPrice, + Long expiration, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .pay(signer, inputCoins, recipients, amounts, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - - /** - * Merge coins completable future. - * - * @param signer the signer - * @param primaryCoin the primary coin - * @param toMergeCoin the to merge coin + return this.newTransactionBlock() + .thenCompose( + (Function>) + transactionBlock -> { + transactionBlock.setExpiration(expiration); + transactionBlock.setSender(sender); + return transactionBlock + .moveCall(packageObjectId, module, function, typeArguments, arguments) + .thenCompose( + (Function>) + argument -> { + CompletableFuture + transactionDataCompletableFuture = + transactionBlock + .setGasData( + gas != null + ? Lists.newArrayList(gas) + : Lists.newArrayList(), + sender, + gasBudget, + gasPrice) + .thenCompose( + (Function>) + unused -> transactionBlock.build()); + + return transactionDataCompletableFuture.thenCompose( + (Function< + TransactionData, + CompletableFuture>) + transactionData -> + executeTransaction( + sender, transactionData, + transactionBlockResponseOptions, requestType)); + }); + }); + } + + /** + * Merge coin completable future. + * + * @param sender the sender + * @param destCoin the dest coin + * @param sourceCoins the source coins * @param gas the gas * @param gasBudget the gas budget + * @param gasPrice the gas price + * @param expiration the expiration + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture mergeCoins( - String signer, - String primaryCoin, - String toMergeCoin, + public CompletableFuture mergeCoin( + String sender, + String destCoin, + List sourceCoins, String gas, - long gasBudget, + Long gasBudget, + Long gasPrice, + Long expiration, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .mergeCoins(signer, primaryCoin, toMergeCoin, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - - /** - * Split coin completable future. - * - * @param signer the signer - * @param coin the coin - * @param splitAmounts the split amounts - * @param gas the gas - * @param gasBudget the gas budget - * @param requestType the request type - * @return the completable future - */ - public CompletableFuture splitCoin( - String signer, - String coin, - List splitAmounts, - String gas, - long gasBudget, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .splitCoin(signer, coin, splitAmounts, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - - /** - * Pay all sui completable future. - * - * @param signer the signer - * @param inputCoins the input coins + return this.newTransactionBlock() + .thenCompose( + (Function>) + transactionBlock -> { + transactionBlock.setExpiration(expiration); + transactionBlock.setSender(sender); + return transactionBlock + .mergeCoins(destCoin, sourceCoins) + .thenCompose( + (Function>) + argument -> { + CompletableFuture + transactionDataCompletableFuture = + transactionBlock + .setGasData( + gas != null + ? Lists.newArrayList(gas) + : Lists.newArrayList(), + sender, + gasBudget, + gasPrice) + .thenCompose( + (Function>) + unused -> transactionBlock.build()); + + return transactionDataCompletableFuture.thenCompose( + (Function< + TransactionData, + CompletableFuture>) + transactionData -> + executeTransaction( + sender, transactionData, + transactionBlockResponseOptions, requestType)); + }); + }); + } + + /** + * Transfer objects completable future. + * + * @param sender the sender + * @param suiObjects the sui objects * @param recipient the recipient + * @param gas the gas * @param gasBudget the gas budget + * @param gasPrice the gas price + * @param expiration the expiration + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture payAllSui( - String signer, - List inputCoins, + public CompletableFuture transferObjects( + String sender, + List suiObjects, String recipient, - long gasBudget, + String gas, + Long gasBudget, + Long gasPrice, + Long expiration, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .payAllSui(signer, inputCoins, recipient, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); + return this.newTransactionBlock() + .thenCompose( + (Function>) + transactionBlock -> { + transactionBlock.setExpiration(expiration); + transactionBlock.setSender(sender); + return transactionBlock + .transferObjects(suiObjects, recipient) + .thenCompose( + (Function>) + argument -> { + CompletableFuture + transactionDataCompletableFuture = + transactionBlock + .setGasData( + gas != null + ? Lists.newArrayList(gas) + : Lists.newArrayList(), + sender, + gasBudget, + gasPrice) + .thenCompose( + (Function>) + unused -> transactionBlock.build()); + + return transactionDataCompletableFuture.thenCompose( + (Function< + TransactionData, + CompletableFuture>) + transactionData -> + executeTransaction( + sender, transactionData, + transactionBlockResponseOptions, requestType)); + }); + }); } /** * Publish completable future. * - * @param signer the signer + * @param sender the signer * @param compiledModules the compiled modules + * @param depIds the dep ids * @param gas the gas * @param gasBudget the gas budget + * @param gasPrice the gas price + * @param expiration the expiration + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture publish( - String signer, + public CompletableFuture publish( + String sender, List compiledModules, + List depIds, String gas, - long gasBudget, + Long gasBudget, + Long gasPrice, + Long expiration, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .publish(signer, compiledModules, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - /** - * Split coin equal completable future. - * - * @param signer the signer - * @param coin the coin - * @param splitCount the split count - * @param gas the gas - * @param gasBudget the gas budget - * @param requestType the request type - * @return the completable future - */ - public CompletableFuture splitCoinEqual( - String signer, - String coin, - long splitCount, - String gas, - long gasBudget, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .splitCoinEqual(signer, coin, splitCount, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); - } - - /** - * Transfer object completable future. - * - * @param signer the signer - * @param suiObject the sui object - * @param recipient the recipient - * @param gas the gas - * @param gasBudget the gas budget - * @param requestType the request type - * @return the completable future - */ - public CompletableFuture transferObject( - String signer, - String suiObject, - String recipient, - String gas, - long gasBudget, - ExecuteTransactionRequestType requestType) { - return this.transactionBuilder - .transferObject(signer, suiObject, recipient, gas, gasBudget) - .thenCompose(signAndExecuteTransactionFunction(signer, defaultIntent(), requestType)); + return this.newTransactionBlock() + .thenCompose( + (Function>) + transactionBlock -> { + transactionBlock.setExpiration(expiration); + transactionBlock.setSender(sender); + Argument result = transactionBlock.publish(compiledModules, depIds); + SuiAddress.Builder senderAddressBuilder = new Builder(); + senderAddressBuilder.value = transactionBlock.geAddressBytes(sender); + transactionBlock.transferObjects( + Lists.newArrayList(result), + transactionBlock.pure(senderAddressBuilder.build())); + + CompletableFuture transactionDataCompletableFuture = + transactionBlock + .setGasData( + gas != null ? Lists.newArrayList(gas) : Lists.newArrayList(), + sender, + gasBudget, + gasPrice) + .thenCompose( + (Function>) + unused -> transactionBlock.build()); + + return transactionDataCompletableFuture.thenCompose( + (Function>) + transactionData -> + executeTransaction( + sender, transactionData, + transactionBlockResponseOptions, requestType)); + }); } /** @@ -402,40 +511,31 @@ public Disposable subscribeEvent( * Gets object. * * @param id the id + * @param objectDataOptions the object data options * @return the object */ - public CompletableFuture getObject(String id) { - return queryClient.getObject(id); + public CompletableFuture getObject( + String id, ObjectDataOptions objectDataOptions) { + return queryClient.getObject(id, objectDataOptions); } /** * Gets objects owned by address. * * @param address the address + * @param query the query + * @param cursor the cursor + * @param limit the limit + * @param checkpointId the checkpoint id * @return the objects owned by address */ - public CompletableFuture> getObjectsOwnedByAddress(String address) { - return queryClient.getObjectsOwnedByAddress(address); - } - - /** - * Gets objects owned by object. - * - * @param objectId the object id - * @return the objects owned by object - */ - public CompletableFuture> getObjectsOwnedByObject(String objectId) { - return queryClient.getObjectsOwnedByObject(objectId); - } - - /** - * Gets raw object. - * - * @param id the id - * @return the raw object - */ - public CompletableFuture getRawObject(String id) { - return queryClient.getRawObject(id); + public CompletableFuture getObjectsOwnedByAddress( + String address, + ObjectResponseQuery query, + String cursor, + Integer limit, + String checkpointId) { + return queryClient.getObjectsOwnedByAddress(address, query, cursor, limit, checkpointId); } /** @@ -443,8 +543,8 @@ public CompletableFuture getRawObject(String id) { * * @return the total transaction number */ - public CompletableFuture getTotalTransactionNumber() { - return queryClient.getTotalTransactionNumber(); + public CompletableFuture getTotalTransactionBlocks() { + return queryClient.getTotalTransactionBlocks(); } /** @@ -454,31 +554,24 @@ public CompletableFuture getTotalTransactionNumber() { * @param options the options * @return the transaction */ - public CompletableFuture getTransaction( - String digest, TransactionResponseOptions options) { - return queryClient.getTransaction(digest, options); + public CompletableFuture getTransactionBlock( + String digest, TransactionBlockResponseOptions options) { + return queryClient.getTransactionBlock(digest, options); } - /** - * Gets transactions in range. - * - * @param start the start - * @param end the end - * @return the transactions in range - */ - public CompletableFuture> getTransactionsInRange(Long start, Long end) { - return queryClient.getTransactionsInRange(start, end); + public CompletableFuture queryTransactionBlocks( + TransactionBlockResponseQuery query, String cursor, Integer limit, boolean isDescOrder) { + return queryClient.queryTransactionBlocks(query, cursor, limit, isDescOrder); } - /** - * Gets the authority public keys that commits to the authority signature of the transaction. - * - * @param transactionDigest the digest - * @return the Transaction auth signers - */ - public CompletableFuture getTransactionAuthSigners( - String transactionDigest) { - return queryClient.getTransactionAuthSigners(transactionDigest); + public CompletableFuture> multiGetTransactionBlocks( + List digests, TransactionBlockResponseOptions options) { + return queryClient.multiGetTransactionBlocks(digests, options); + } + + public CompletableFuture> multiGetObjects( + List objectIds, ObjectDataOptions options) { + return queryClient.multiGetObjects(objectIds, options); } /** @@ -596,19 +689,19 @@ public CompletableFuture tryGetPastObject(String objectId, long return queryClient.tryGetPastObject(objectId, version); } - /** - * Gets transactions. - * - * @param query the query - * @param cursor the cursor - * @param limit the limit - * @param isDescOrder the is desc order - * @return the transactions - */ - public CompletableFuture getTransactions( - TransactionQuery query, String cursor, int limit, boolean isDescOrder) { - return queryClient.getTransactions(query, cursor, limit, isDescOrder); - } + // /** + // * Gets transactions. + // * + // * @param query the query + // * @param cursor the cursor + // * @param limit the limit + // * @param isDescOrder the is desc order + // * @return the transactions + // */ + // public CompletableFuture getTransactions( + // TransactionFilter query, String cursor, int limit, boolean isDescOrder) { + // return queryClient.queryTransactionBlocks(query, cursor, limit, isDescOrder); + // } /** * Gets coin metadata. @@ -633,10 +726,12 @@ public CompletableFuture getReferenceGasPrice() { * Gets object ref. * * @param id the id + * @param objectDataOptions the object data options * @return the object ref */ - public CompletableFuture getObjectRef(String id) { - return queryClient.getObjectRef(id); + public CompletableFuture getObjectRef( + String id, ObjectDataOptions objectDataOptions) { + return queryClient.getObjectRef(id, objectDataOptions); } /** @@ -771,12 +866,21 @@ public TransactionBuilder getTransactionBuilder() { * * @param signer the signer * @param transactionData the transaction data + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture executeTransaction( - String signer, TransactionData transactionData, ExecuteTransactionRequestType requestType) { - return this.executeTransaction(signer, transactionData, defaultIntent(), requestType); + public CompletableFuture executeTransaction( + String signer, + TransactionData transactionData, + TransactionBlockResponseOptions transactionBlockResponseOptions, + ExecuteTransactionRequestType requestType) { + return this.executeTransaction( + signer, + transactionData, + transactionDataIntent(), + transactionBlockResponseOptions, + requestType); } /** @@ -785,13 +889,15 @@ public CompletableFuture executeTransaction( * @param signer the signer * @param transactionData the transaction data * @param intent the intent + * @param transactionBlockResponseOptions the transaction response options * @param requestType the request type * @return the completable future */ - public CompletableFuture executeTransaction( + public CompletableFuture executeTransaction( String signer, TransactionData transactionData, Intent intent, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType) { final SuiKeyPair suiKeyPair = keyStore.getByAddress(signer); final byte[] publicKey = suiKeyPair.publicKeyBytes(); @@ -803,27 +909,41 @@ public CompletableFuture executeTransaction( txBytes = transactionData.bcsSerialize(); intentBytes = intent.bcsSerialize(); } catch (SerializationError e) { - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); future.completeExceptionally(new SuiApiException(new BcsSerializationException(e))); return future; } return signAndExecuteTransaction( - txBytes, intentBytes, requestType, suiKeyPair, publicKey, signatureScheme); + txBytes, + intentBytes, + transactionBlockResponseOptions, + requestType, + suiKeyPair, + publicKey, + signatureScheme); } - private CompletableFuture signAndExecuteTransaction( + private CompletableFuture signAndExecuteTransaction( byte[] transactionData, byte[] intentBytes, + TransactionBlockResponseOptions transactionBlockResponseOptions, ExecuteTransactionRequestType requestType, SuiKeyPair suiKeyPair, byte[] publicKey, SignatureScheme signatureScheme) { final byte[] signature; try { - signature = suiKeyPair.sign(Arrays.concatenate(intentBytes, transactionData)); + if ("0.28.0".equals(System.getenv("SUI_VERSION"))) { + signature = suiKeyPair.sign(Arrays.concatenate(intentBytes, transactionData)); + } else { + final Blake2b256 blake2b256 = new Blake2b256(); + final byte[] hash = blake2b256.digest(Arrays.concatenate(intentBytes, transactionData)); + signature = suiKeyPair.sign(hash); + } + } catch (SigningException e) { - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); future.completeExceptionally(new SuiApiException(e)); return future; } @@ -833,12 +953,18 @@ private CompletableFuture signAndExecuteTransaction( final String serializedSignature = Base64.toBase64String(serializedSignatureBytes); return executionClient.executeTransaction( - Base64.toBase64String(transactionData), serializedSignature, requestType); + Base64.toBase64String(transactionData), + Lists.newArrayList(serializedSignature), + transactionBlockResponseOptions, + requestType); } - private Function> + private Function> signAndExecuteTransactionFunction( - String signer, Intent intent, ExecuteTransactionRequestType requestType) { + String signer, + Intent intent, + TransactionBlockResponseOptions transactionBlockResponseOptions, + ExecuteTransactionRequestType requestType) { return transactionBytes -> { final SuiKeyPair suiKeyPair = keyStore.getByAddress(signer); final byte[] publicKey = suiKeyPair.publicKeyBytes(); @@ -854,17 +980,23 @@ private CompletableFuture signAndExecuteTransaction( : Base64.decode(transactionBytes.getTxBytes()); intentBytes = intent.bcsSerialize(); } catch (SerializationError e) { - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); future.completeExceptionally(new SuiApiException(new BcsSerializationException(e))); return future; } return signAndExecuteTransaction( - txBytes, intentBytes, requestType, suiKeyPair, publicKey, signatureScheme); + txBytes, + intentBytes, + transactionBlockResponseOptions, + requestType, + suiKeyPair, + publicKey, + signatureScheme); }; } - private Intent defaultIntent() { + private Intent transactionDataIntent() { final Intent.Builder intentBuilder = new Intent.Builder(); intentBuilder.app_id = 0; intentBuilder.scope = 0; diff --git a/src/main/java/io/sui/bcsgen/ChangeEpoch.java b/src/main/java/io/sui/bcsgen/ChangeEpoch.java index 2d5e2ce..d885335 100644 --- a/src/main/java/io/sui/bcsgen/ChangeEpoch.java +++ b/src/main/java/io/sui/bcsgen/ChangeEpoch.java @@ -8,9 +8,9 @@ public final class ChangeEpoch { public final @com.novi.serde.Unsigned Long computation_charge; public final @com.novi.serde.Unsigned Long storage_rebate; public final @com.novi.serde.Unsigned Long epoch_start_timestamp_ms; - public final java.util.List>>> system_packages; + public final java.util.List>, java.util.List>> system_packages; - public ChangeEpoch(@com.novi.serde.Unsigned Long epoch, ProtocolVersion protocol_version, @com.novi.serde.Unsigned Long storage_charge, @com.novi.serde.Unsigned Long computation_charge, @com.novi.serde.Unsigned Long storage_rebate, @com.novi.serde.Unsigned Long epoch_start_timestamp_ms, java.util.List>>> system_packages) { + public ChangeEpoch(@com.novi.serde.Unsigned Long epoch, ProtocolVersion protocol_version, @com.novi.serde.Unsigned Long storage_charge, @com.novi.serde.Unsigned Long computation_charge, @com.novi.serde.Unsigned Long storage_rebate, @com.novi.serde.Unsigned Long epoch_start_timestamp_ms, java.util.List>, java.util.List>> system_packages) { java.util.Objects.requireNonNull(epoch, "epoch must not be null"); java.util.Objects.requireNonNull(protocol_version, "protocol_version must not be null"); java.util.Objects.requireNonNull(storage_charge, "storage_charge must not be null"); @@ -35,7 +35,7 @@ public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serd serializer.serialize_u64(computation_charge); serializer.serialize_u64(storage_rebate); serializer.serialize_u64(epoch_start_timestamp_ms); - TraitHelpers.serialize_vector_tuple2_SequenceNumber_vector_vector_u8(system_packages, serializer); + TraitHelpers.serialize_vector_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(system_packages, serializer); serializer.decrease_container_depth(); } @@ -54,7 +54,7 @@ public static ChangeEpoch deserialize(com.novi.serde.Deserializer deserializer) builder.computation_charge = deserializer.deserialize_u64(); builder.storage_rebate = deserializer.deserialize_u64(); builder.epoch_start_timestamp_ms = deserializer.deserialize_u64(); - builder.system_packages = TraitHelpers.deserialize_vector_tuple2_SequenceNumber_vector_vector_u8(deserializer); + builder.system_packages = TraitHelpers.deserialize_vector_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(deserializer); deserializer.decrease_container_depth(); return builder.build(); } @@ -105,7 +105,7 @@ public static final class Builder { public @com.novi.serde.Unsigned Long computation_charge; public @com.novi.serde.Unsigned Long storage_rebate; public @com.novi.serde.Unsigned Long epoch_start_timestamp_ms; - public java.util.List>>> system_packages; + public java.util.List>, java.util.List>> system_packages; public ChangeEpoch build() { return new ChangeEpoch( diff --git a/src/main/java/io/sui/bcsgen/Command.java b/src/main/java/io/sui/bcsgen/Command.java index 02752d1..bab283e 100644 --- a/src/main/java/io/sui/bcsgen/Command.java +++ b/src/main/java/io/sui/bcsgen/Command.java @@ -10,7 +10,7 @@ public static Command deserialize(com.novi.serde.Deserializer deserializer) thro switch (index) { case 0: return MoveCall.load(deserializer); case 1: return TransferObjects.load(deserializer); - case 2: return SplitCoin.load(deserializer); + case 2: return SplitCoins.load(deserializer); case 3: return MergeCoins.load(deserializer); case 4: return Publish.load(deserializer); case 5: return MakeMoveVec.load(deserializer); @@ -144,11 +144,11 @@ public TransferObjects build() { } } - public static final class SplitCoin extends Command { + public static final class SplitCoins extends Command { public final Argument field0; - public final Argument field1; + public final java.util.List field1; - public SplitCoin(Argument field0, Argument field1) { + public SplitCoins(Argument field0, java.util.List field1) { java.util.Objects.requireNonNull(field0, "field0 must not be null"); java.util.Objects.requireNonNull(field1, "field1 must not be null"); this.field0 = field0; @@ -159,15 +159,15 @@ public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serd serializer.increase_container_depth(); serializer.serialize_variant_index(2); field0.serialize(serializer); - field1.serialize(serializer); + TraitHelpers.serialize_vector_Argument(field1, serializer); serializer.decrease_container_depth(); } - static SplitCoin load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + static SplitCoins load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { deserializer.increase_container_depth(); Builder builder = new Builder(); builder.field0 = Argument.deserialize(deserializer); - builder.field1 = Argument.deserialize(deserializer); + builder.field1 = TraitHelpers.deserialize_vector_Argument(deserializer); deserializer.decrease_container_depth(); return builder.build(); } @@ -176,7 +176,7 @@ public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; - SplitCoin other = (SplitCoin) obj; + SplitCoins other = (SplitCoins) obj; if (!java.util.Objects.equals(this.field0, other.field0)) { return false; } if (!java.util.Objects.equals(this.field1, other.field1)) { return false; } return true; @@ -191,10 +191,10 @@ public int hashCode() { public static final class Builder { public Argument field0; - public Argument field1; + public java.util.List field1; - public SplitCoin build() { - return new SplitCoin( + public SplitCoins build() { + return new SplitCoins( field0, field1 ); @@ -261,24 +261,29 @@ public MergeCoins build() { } public static final class Publish extends Command { - public final java.util.List> value; + public final java.util.List> field0; + public final java.util.List field1; - public Publish(java.util.List> value) { - java.util.Objects.requireNonNull(value, "value must not be null"); - this.value = value; + public Publish(java.util.List> field0, java.util.List field1) { + java.util.Objects.requireNonNull(field0, "field0 must not be null"); + java.util.Objects.requireNonNull(field1, "field1 must not be null"); + this.field0 = field0; + this.field1 = field1; } public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.increase_container_depth(); serializer.serialize_variant_index(4); - TraitHelpers.serialize_vector_vector_u8(value, serializer); + TraitHelpers.serialize_vector_vector_u8(field0, serializer); + TraitHelpers.serialize_vector_ObjectID(field1, serializer); serializer.decrease_container_depth(); } static Publish load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { deserializer.increase_container_depth(); Builder builder = new Builder(); - builder.value = TraitHelpers.deserialize_vector_vector_u8(deserializer); + builder.field0 = TraitHelpers.deserialize_vector_vector_u8(deserializer); + builder.field1 = TraitHelpers.deserialize_vector_ObjectID(deserializer); deserializer.decrease_container_depth(); return builder.build(); } @@ -288,22 +293,26 @@ public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; Publish other = (Publish) obj; - if (!java.util.Objects.equals(this.value, other.value)) { return false; } + if (!java.util.Objects.equals(this.field0, other.field0)) { return false; } + if (!java.util.Objects.equals(this.field1, other.field1)) { return false; } return true; } public int hashCode() { int value = 7; - value = 31 * value + (this.value != null ? this.value.hashCode() : 0); + value = 31 * value + (this.field0 != null ? this.field0.hashCode() : 0); + value = 31 * value + (this.field1 != null ? this.field1.hashCode() : 0); return value; } public static final class Builder { - public java.util.List> value; + public java.util.List> field0; + public java.util.List field1; public Publish build() { return new Publish( - value + field0, + field1 ); } } diff --git a/src/main/java/io/sui/bcsgen/ExecutionFailureStatus.java b/src/main/java/io/sui/bcsgen/ExecutionFailureStatus.java index 007caa6..1d12f95 100644 --- a/src/main/java/io/sui/bcsgen/ExecutionFailureStatus.java +++ b/src/main/java/io/sui/bcsgen/ExecutionFailureStatus.java @@ -33,6 +33,9 @@ public static ExecutionFailureStatus deserialize(com.novi.serde.Deserializer des case 22: return InvalidPublicFunctionReturnType.load(deserializer); case 23: return InvalidTransferObject.load(deserializer); case 24: return EffectsTooLarge.load(deserializer); + case 25: return PublishUpgradeMissingDependency.load(deserializer); + case 26: return PublishUpgradeDependencyDowngrade.load(deserializer); + case 27: return PackageUpgradeError.load(deserializer); default: throw new com.novi.serde.DeserializationError("Unknown variant index for ExecutionFailureStatus: " + index); } } @@ -1177,5 +1180,130 @@ public EffectsTooLarge build() { } } } + + public static final class PublishUpgradeMissingDependency extends ExecutionFailureStatus { + public PublishUpgradeMissingDependency() { + } + + public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + serializer.increase_container_depth(); + serializer.serialize_variant_index(25); + serializer.decrease_container_depth(); + } + + static PublishUpgradeMissingDependency load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + deserializer.increase_container_depth(); + Builder builder = new Builder(); + deserializer.decrease_container_depth(); + return builder.build(); + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + PublishUpgradeMissingDependency other = (PublishUpgradeMissingDependency) obj; + return true; + } + + public int hashCode() { + int value = 7; + return value; + } + + public static final class Builder { + public PublishUpgradeMissingDependency build() { + return new PublishUpgradeMissingDependency( + ); + } + } + } + + public static final class PublishUpgradeDependencyDowngrade extends ExecutionFailureStatus { + public PublishUpgradeDependencyDowngrade() { + } + + public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + serializer.increase_container_depth(); + serializer.serialize_variant_index(26); + serializer.decrease_container_depth(); + } + + static PublishUpgradeDependencyDowngrade load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + deserializer.increase_container_depth(); + Builder builder = new Builder(); + deserializer.decrease_container_depth(); + return builder.build(); + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + PublishUpgradeDependencyDowngrade other = (PublishUpgradeDependencyDowngrade) obj; + return true; + } + + public int hashCode() { + int value = 7; + return value; + } + + public static final class Builder { + public PublishUpgradeDependencyDowngrade build() { + return new PublishUpgradeDependencyDowngrade( + ); + } + } + } + + public static final class PackageUpgradeError extends ExecutionFailureStatus { + public final io.sui.bcsgen.PackageUpgradeError upgrade_error; + + public PackageUpgradeError(io.sui.bcsgen.PackageUpgradeError upgrade_error) { + java.util.Objects.requireNonNull(upgrade_error, "upgrade_error must not be null"); + this.upgrade_error = upgrade_error; + } + + public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + serializer.increase_container_depth(); + serializer.serialize_variant_index(27); + upgrade_error.serialize(serializer); + serializer.decrease_container_depth(); + } + + static PackageUpgradeError load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + deserializer.increase_container_depth(); + Builder builder = new Builder(); + builder.upgrade_error = io.sui.bcsgen.PackageUpgradeError.deserialize(deserializer); + deserializer.decrease_container_depth(); + return builder.build(); + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + PackageUpgradeError other = (PackageUpgradeError) obj; + if (!java.util.Objects.equals(this.upgrade_error, other.upgrade_error)) { return false; } + return true; + } + + public int hashCode() { + int value = 7; + value = 31 * value + (this.upgrade_error != null ? this.upgrade_error.hashCode() : 0); + return value; + } + + public static final class Builder { + public io.sui.bcsgen.PackageUpgradeError upgrade_error; + + public PackageUpgradeError build() { + return new PackageUpgradeError( + upgrade_error + ); + } + } + } } diff --git a/src/main/java/io/sui/bcsgen/MovePackage.java b/src/main/java/io/sui/bcsgen/MovePackage.java index bfd0db6..8b7bc99 100644 --- a/src/main/java/io/sui/bcsgen/MovePackage.java +++ b/src/main/java/io/sui/bcsgen/MovePackage.java @@ -5,14 +5,20 @@ public final class MovePackage { public final ObjectID id; public final SequenceNumber version; public final java.util.Map module_map; + public final java.util.List type_origin_table; + public final java.util.Map linkage_table; - public MovePackage(ObjectID id, SequenceNumber version, java.util.Map module_map) { + public MovePackage(ObjectID id, SequenceNumber version, java.util.Map module_map, java.util.List type_origin_table, java.util.Map linkage_table) { java.util.Objects.requireNonNull(id, "id must not be null"); java.util.Objects.requireNonNull(version, "version must not be null"); java.util.Objects.requireNonNull(module_map, "module_map must not be null"); + java.util.Objects.requireNonNull(type_origin_table, "type_origin_table must not be null"); + java.util.Objects.requireNonNull(linkage_table, "linkage_table must not be null"); this.id = id; this.version = version; this.module_map = module_map; + this.type_origin_table = type_origin_table; + this.linkage_table = linkage_table; } public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { @@ -20,6 +26,8 @@ public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serd id.serialize(serializer); version.serialize(serializer); TraitHelpers.serialize_map_str_to_bytes(module_map, serializer); + TraitHelpers.serialize_vector_TypeOrigin(type_origin_table, serializer); + TraitHelpers.serialize_map_ObjectID_to_UpgradeInfo(linkage_table, serializer); serializer.decrease_container_depth(); } @@ -35,6 +43,8 @@ public static MovePackage deserialize(com.novi.serde.Deserializer deserializer) builder.id = ObjectID.deserialize(deserializer); builder.version = SequenceNumber.deserialize(deserializer); builder.module_map = TraitHelpers.deserialize_map_str_to_bytes(deserializer); + builder.type_origin_table = TraitHelpers.deserialize_vector_TypeOrigin(deserializer); + builder.linkage_table = TraitHelpers.deserialize_map_ObjectID_to_UpgradeInfo(deserializer); deserializer.decrease_container_depth(); return builder.build(); } @@ -59,6 +69,8 @@ public boolean equals(Object obj) { if (!java.util.Objects.equals(this.id, other.id)) { return false; } if (!java.util.Objects.equals(this.version, other.version)) { return false; } if (!java.util.Objects.equals(this.module_map, other.module_map)) { return false; } + if (!java.util.Objects.equals(this.type_origin_table, other.type_origin_table)) { return false; } + if (!java.util.Objects.equals(this.linkage_table, other.linkage_table)) { return false; } return true; } @@ -67,6 +79,8 @@ public int hashCode() { value = 31 * value + (this.id != null ? this.id.hashCode() : 0); value = 31 * value + (this.version != null ? this.version.hashCode() : 0); value = 31 * value + (this.module_map != null ? this.module_map.hashCode() : 0); + value = 31 * value + (this.type_origin_table != null ? this.type_origin_table.hashCode() : 0); + value = 31 * value + (this.linkage_table != null ? this.linkage_table.hashCode() : 0); return value; } @@ -74,12 +88,16 @@ public static final class Builder { public ObjectID id; public SequenceNumber version; public java.util.Map module_map; + public java.util.List type_origin_table; + public java.util.Map linkage_table; public MovePackage build() { return new MovePackage( id, version, - module_map + module_map, + type_origin_table, + linkage_table ); } } diff --git a/src/main/java/io/sui/bcsgen/TraitHelpers.java b/src/main/java/io/sui/bcsgen/TraitHelpers.java index 52f1c17..e468958 100644 --- a/src/main/java/io/sui/bcsgen/TraitHelpers.java +++ b/src/main/java/io/sui/bcsgen/TraitHelpers.java @@ -18,6 +18,40 @@ static void serialize_array32_u8_array(java.util.@com.novi.serde.ArrayLen(length return obj; } + static void serialize_map_ObjectID_to_UpgradeInfo(java.util.Map value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + serializer.serialize_len(value.size()); + int[] offsets = new int[value.size()]; + int count = 0; + for (java.util.Map.Entry entry : value.entrySet()) { + offsets[count++] = serializer.get_buffer_offset(); + entry.getKey().serialize(serializer); + entry.getValue().serialize(serializer); + } + serializer.sort_map_entries(offsets); + } + + static java.util.Map deserialize_map_ObjectID_to_UpgradeInfo(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + long length = deserializer.deserialize_len(); + java.util.Map obj = new java.util.HashMap(); + int previous_key_start = 0; + int previous_key_end = 0; + for (long i = 0; i < length; i++) { + int key_start = deserializer.get_buffer_offset(); + ObjectID key = ObjectID.deserialize(deserializer); + int key_end = deserializer.get_buffer_offset(); + if (i > 0) { + deserializer.check_that_key_slices_are_increasing( + new com.novi.serde.Slice(previous_key_start, previous_key_end), + new com.novi.serde.Slice(key_start, key_end)); + } + previous_key_start = key_start; + previous_key_end = key_end; + UpgradeInfo value = UpgradeInfo.deserialize(deserializer); + obj.put(key, value); + } + return obj; + } + static void serialize_map_str_to_bytes(java.util.Map value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.serialize_len(value.size()); int[] offsets = new int[value.size()]; @@ -136,18 +170,6 @@ static com.novi.serde.Tuple2 deserialize_tuple2_Identifie ); } - static void serialize_tuple2_SequenceNumber_vector_vector_u8(com.novi.serde.Tuple2>> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { - value.field0.serialize(serializer); - TraitHelpers.serialize_vector_vector_u8(value.field1, serializer); - } - - static com.novi.serde.Tuple2>> deserialize_tuple2_SequenceNumber_vector_vector_u8(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { - return new com.novi.serde.Tuple2>>( - SequenceNumber.deserialize(deserializer), - TraitHelpers.deserialize_vector_vector_u8(deserializer) - ); - } - static void serialize_tuple3_ObjectID_SequenceNumber_ObjectDigest(com.novi.serde.Tuple3 value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { value.field0.serialize(serializer); value.field1.serialize(serializer); @@ -162,6 +184,20 @@ static com.novi.serde.Tuple3 deserialize ); } + static void serialize_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(com.novi.serde.Tuple3>, java.util.List> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + value.field0.serialize(serializer); + TraitHelpers.serialize_vector_vector_u8(value.field1, serializer); + TraitHelpers.serialize_vector_ObjectID(value.field2, serializer); + } + + static com.novi.serde.Tuple3>, java.util.List> deserialize_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + return new com.novi.serde.Tuple3>, java.util.List>( + SequenceNumber.deserialize(deserializer), + TraitHelpers.deserialize_vector_vector_u8(deserializer), + TraitHelpers.deserialize_vector_ObjectID(deserializer) + ); + } + static void serialize_vector_Argument(java.util.List value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.serialize_len(value.size()); for (Argument item : value) { @@ -290,6 +326,22 @@ static java.util.List deserialize_vector_ObjectID(com.novi.serde.Deser return obj; } + static void serialize_vector_TypeOrigin(java.util.List value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + serializer.serialize_len(value.size()); + for (TypeOrigin item : value) { + item.serialize(serializer); + } + } + + static java.util.List deserialize_vector_TypeOrigin(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + long length = deserializer.deserialize_len(); + java.util.List obj = new java.util.ArrayList((int) length); + for (long i = 0; i < length; i++) { + obj.add(TypeOrigin.deserialize(deserializer)); + } + return obj; + } + static void serialize_vector_TypeTag(java.util.List value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.serialize_len(value.size()); for (TypeTag item : value) { @@ -322,34 +374,34 @@ static java.util.List> deserialize_ return obj; } - static void serialize_vector_tuple2_SequenceNumber_vector_vector_u8(java.util.List>>> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + static void serialize_vector_tuple3_ObjectID_SequenceNumber_ObjectDigest(java.util.List> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.serialize_len(value.size()); - for (com.novi.serde.Tuple2>> item : value) { - TraitHelpers.serialize_tuple2_SequenceNumber_vector_vector_u8(item, serializer); + for (com.novi.serde.Tuple3 item : value) { + TraitHelpers.serialize_tuple3_ObjectID_SequenceNumber_ObjectDigest(item, serializer); } } - static java.util.List>>> deserialize_vector_tuple2_SequenceNumber_vector_vector_u8(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + static java.util.List> deserialize_vector_tuple3_ObjectID_SequenceNumber_ObjectDigest(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { long length = deserializer.deserialize_len(); - java.util.List>>> obj = new java.util.ArrayList>>>((int) length); + java.util.List> obj = new java.util.ArrayList>((int) length); for (long i = 0; i < length; i++) { - obj.add(TraitHelpers.deserialize_tuple2_SequenceNumber_vector_vector_u8(deserializer)); + obj.add(TraitHelpers.deserialize_tuple3_ObjectID_SequenceNumber_ObjectDigest(deserializer)); } return obj; } - static void serialize_vector_tuple3_ObjectID_SequenceNumber_ObjectDigest(java.util.List> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { + static void serialize_vector_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(java.util.List>, java.util.List>> value, com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.serialize_len(value.size()); - for (com.novi.serde.Tuple3 item : value) { - TraitHelpers.serialize_tuple3_ObjectID_SequenceNumber_ObjectDigest(item, serializer); + for (com.novi.serde.Tuple3>, java.util.List> item : value) { + TraitHelpers.serialize_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(item, serializer); } } - static java.util.List> deserialize_vector_tuple3_ObjectID_SequenceNumber_ObjectDigest(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { + static java.util.List>, java.util.List>> deserialize_vector_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError { long length = deserializer.deserialize_len(); - java.util.List> obj = new java.util.ArrayList>((int) length); + java.util.List>, java.util.List>> obj = new java.util.ArrayList>, java.util.List>>((int) length); for (long i = 0; i < length; i++) { - obj.add(TraitHelpers.deserialize_tuple3_ObjectID_SequenceNumber_ObjectDigest(deserializer)); + obj.add(TraitHelpers.deserialize_tuple3_SequenceNumber_vector_vector_u8_vector_ObjectID(deserializer)); } return obj; } diff --git a/src/main/java/io/sui/bcsgen/TypeOrigin.java b/src/main/java/io/sui/bcsgen/TypeOrigin.java index 64e784e..3c712dc 100644 --- a/src/main/java/io/sui/bcsgen/TypeOrigin.java +++ b/src/main/java/io/sui/bcsgen/TypeOrigin.java @@ -4,22 +4,22 @@ public final class TypeOrigin { public final String module_name; public final String struct_name; - public final ObjectID package; + public final ObjectID Package; - public TypeOrigin(String module_name, String struct_name, ObjectID package) { + public TypeOrigin(String module_name, String struct_name, ObjectID Package) { java.util.Objects.requireNonNull(module_name, "module_name must not be null"); java.util.Objects.requireNonNull(struct_name, "struct_name must not be null"); - java.util.Objects.requireNonNull(package, "package must not be null"); + java.util.Objects.requireNonNull(Package, "Package must not be null"); this.module_name = module_name; this.struct_name = struct_name; - this.package = package; + this.Package = Package; } public void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError { serializer.increase_container_depth(); serializer.serialize_str(module_name); serializer.serialize_str(struct_name); - package.serialize(serializer); + Package.serialize(serializer); serializer.decrease_container_depth(); } @@ -34,7 +34,7 @@ public static TypeOrigin deserialize(com.novi.serde.Deserializer deserializer) t Builder builder = new Builder(); builder.module_name = deserializer.deserialize_str(); builder.struct_name = deserializer.deserialize_str(); - builder.package = ObjectID.deserialize(deserializer); + builder.Package = ObjectID.deserialize(deserializer); deserializer.decrease_container_depth(); return builder.build(); } @@ -58,7 +58,7 @@ public boolean equals(Object obj) { TypeOrigin other = (TypeOrigin) obj; if (!java.util.Objects.equals(this.module_name, other.module_name)) { return false; } if (!java.util.Objects.equals(this.struct_name, other.struct_name)) { return false; } - if (!java.util.Objects.equals(this.package, other.package)) { return false; } + if (!java.util.Objects.equals(this.Package, other.Package)) { return false; } return true; } @@ -66,20 +66,20 @@ public int hashCode() { int value = 7; value = 31 * value + (this.module_name != null ? this.module_name.hashCode() : 0); value = 31 * value + (this.struct_name != null ? this.struct_name.hashCode() : 0); - value = 31 * value + (this.package != null ? this.package.hashCode() : 0); + value = 31 * value + (this.Package != null ? this.Package.hashCode() : 0); return value; } public static final class Builder { public String module_name; public String struct_name; - public ObjectID package; + public ObjectID Package; public TypeOrigin build() { return new TypeOrigin( module_name, struct_name, - package + Package ); } } diff --git a/src/main/java/io/sui/clients/BuilderArg.java b/src/main/java/io/sui/clients/BuilderArg.java index 938e4cb..c22b2e1 100644 --- a/src/main/java/io/sui/clients/BuilderArg.java +++ b/src/main/java/io/sui/clients/BuilderArg.java @@ -1,7 +1,181 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/18 - * Time: 09:50 - */public class BuilderArg { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + + +import io.sui.bcsgen.ObjectID; +import java.util.Arrays; +import java.util.Objects; + +/** + * The type Builder arg. + * + * @author grapebaba + * @since 2023.04 + */ +public abstract class BuilderArg { + + /** The type Object builder arg. */ + public static class ObjectBuilderArg extends BuilderArg { + + private ObjectID id; + + public ObjectBuilderArg(ObjectID id) { + this.id = id; + } + + /** + * Gets object id. + * + * @return the object id + */ + public ObjectID getId() { + return id; + } + + /** + * Sets object id. + * + * @param id the object id + */ + public void setId(ObjectID id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ObjectBuilderArg)) { + return false; + } + ObjectBuilderArg that = (ObjectBuilderArg) o; + return id.equals(that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "ObjectBuilderArg{" + "objectID=" + id + '}'; + } + } + + /** The type Pure builder arg. */ + public static class PureBuilderArg extends BuilderArg { + + private byte[] value; + + public PureBuilderArg(byte[] value) { + this.value = value; + } + + /** + * Get value byte [ ]. + * + * @return the byte [ ] + */ + public byte[] getValue() { + return value; + } + + /** + * Sets value. + * + * @param value the value + */ + public void setValue(byte[] value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PureBuilderArg)) { + return false; + } + PureBuilderArg that = (PureBuilderArg) o; + return Arrays.equals(value, that.value); + } + + @Override + public int hashCode() { + return Arrays.hashCode(value); + } + + @Override + public String toString() { + return "PureBuilderArg{" + "value=" + Arrays.toString(value) + '}'; + } + } + + /** The type Forced non unique pure builder arg. */ + public static class ForcedNonUniquePureBuilderArg extends BuilderArg { + + private int value; + + public ForcedNonUniquePureBuilderArg(int value) { + this.value = value; + } + + /** + * Gets value. + * + * @return the value + */ + public int getValue() { + return value; + } + + /** + * Sets value. + * + * @param value the value + */ + public void setValue(int value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ForcedNonUniquePureBuilderArg)) { + return false; + } + ForcedNonUniquePureBuilderArg that = (ForcedNonUniquePureBuilderArg) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "ForcedNonUniquePureBuilderArg{" + "value=" + value + '}'; + } + } } diff --git a/src/main/java/io/sui/clients/CallArgObjVec.java b/src/main/java/io/sui/clients/CallArgObjVec.java index 530c91c..30664a2 100644 --- a/src/main/java/io/sui/clients/CallArgObjVec.java +++ b/src/main/java/io/sui/clients/CallArgObjVec.java @@ -1,7 +1,74 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/4 - * Time: 17:13 - */public class CallArgObjVec { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + + +import com.novi.serde.SerializationError; +import com.novi.serde.Serializer; +import io.sui.bcsgen.CallArg; +import io.sui.bcsgen.ObjectArg; +import java.util.List; +import java.util.Objects; + +/** + * The type Call arg obj vec. + * + * @author grapebaba + * @since 2023.04 + */ +public class CallArgObjVec extends CallArg { + + private List objectArgs; + + @Override + public void serialize(Serializer serializer) throws SerializationError {} + + /** + * Gets object args. + * + * @return the object args + */ + public List getObjectArgs() { + return objectArgs; + } + + /** + * Sets object args. + * + * @param objectArgs the object args + */ + public void setObjectArgs(List objectArgs) { + this.objectArgs = objectArgs; + } + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CallArgObjVec)) { + return false; + } + CallArgObjVec that = (CallArgObjVec) o; + return objectArgs.equals(that.objectArgs); + } + + @Override + public int hashCode() { + return Objects.hash(objectArgs); + } } diff --git a/src/main/java/io/sui/clients/ExecutionClient.java b/src/main/java/io/sui/clients/ExecutionClient.java index 3eb9b48..aef1187 100644 --- a/src/main/java/io/sui/clients/ExecutionClient.java +++ b/src/main/java/io/sui/clients/ExecutionClient.java @@ -18,8 +18,10 @@ import io.sui.models.transactions.ExecuteTransactionRequestType; -import io.sui.models.transactions.ExecuteTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; import io.sui.models.transactions.TransactionEffects; +import java.util.List; import java.util.concurrent.CompletableFuture; /** @@ -42,10 +44,14 @@ public interface ExecutionClient { * Execute transaction completable future. * * @param txBytes the tx bytes - * @param serializedSignatureBytes the serialized signature bytes + * @param signatures the signatures + * @param transactionBlockResponseOptions the transaction block response options * @param requestType the request type * @return the completable future */ - CompletableFuture executeTransaction( - String txBytes, String serializedSignatureBytes, ExecuteTransactionRequestType requestType); + CompletableFuture executeTransaction( + String txBytes, + List signatures, + TransactionBlockResponseOptions transactionBlockResponseOptions, + ExecuteTransactionRequestType requestType); } diff --git a/src/main/java/io/sui/clients/ExecutionClientImpl.java b/src/main/java/io/sui/clients/ExecutionClientImpl.java index 05c9e8c..7b90c89 100644 --- a/src/main/java/io/sui/clients/ExecutionClientImpl.java +++ b/src/main/java/io/sui/clients/ExecutionClientImpl.java @@ -22,8 +22,10 @@ import io.sui.jsonrpc.JsonRpc20Request; import io.sui.jsonrpc.JsonRpcClientProvider; import io.sui.models.transactions.ExecuteTransactionRequestType; -import io.sui.models.transactions.ExecuteTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; import io.sui.models.transactions.TransactionEffects; +import java.util.List; import java.util.concurrent.CompletableFuture; /** @@ -55,15 +57,18 @@ public CompletableFuture dryRunTransaction(String txBytes) { } @Override - public CompletableFuture executeTransaction( - String txBytes, String serializedSignatureBytes, ExecuteTransactionRequestType requestType) { + public CompletableFuture executeTransaction( + String txBytes, + List signatures, + TransactionBlockResponseOptions transactionBlockResponseOptions, + ExecuteTransactionRequestType requestType) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_executeTransaction", - Lists.newArrayList(txBytes, serializedSignatureBytes, requestType)); + "sui_executeTransactionBlock", + Lists.newArrayList(txBytes, signatures, transactionBlockResponseOptions, requestType)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_executeTransaction", + "/sui_executeTransactionBlock", request, - new TypeToken() {}.getType()); + new TypeToken() {}.getType()); } } diff --git a/src/main/java/io/sui/clients/FaucetClient.java b/src/main/java/io/sui/clients/FaucetClient.java index ff40153..5f62079 100644 --- a/src/main/java/io/sui/clients/FaucetClient.java +++ b/src/main/java/io/sui/clients/FaucetClient.java @@ -1,7 +1,38 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/11 - * Time: 16:18 - */public interface FaucetClient { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + + +import io.sui.models.FaucetResponse; +import java.util.concurrent.CompletableFuture; + +/** + * The interface Faucet client. + * + * @author grapebaba + * @since 2023.04 + */ +public interface FaucetClient { + + /** + * Request sui from faucet completable future. + * + * @param address the address + * @return the completable future + */ + CompletableFuture requestSuiFromFaucet(String address); } diff --git a/src/main/java/io/sui/clients/HttpForbiddenException.java b/src/main/java/io/sui/clients/HttpForbiddenException.java index 210d243..a6d7ec2 100644 --- a/src/main/java/io/sui/clients/HttpForbiddenException.java +++ b/src/main/java/io/sui/clients/HttpForbiddenException.java @@ -1,7 +1,31 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/11 - * Time: 16:52 - */public class ForbiddenException { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + +/** + * The type Http forbidden exception. + * + * @author grapebaba + * @since 2023.04 + */ +public class HttpForbiddenException extends RuntimeException { + + /** Instantiates a new Http forbidden exception. */ + public HttpForbiddenException() { + super(); + } } diff --git a/src/main/java/io/sui/clients/JsonRpcTransactionBuilder.java b/src/main/java/io/sui/clients/JsonRpcTransactionBuilder.java index c64df4c..664bd14 100644 --- a/src/main/java/io/sui/clients/JsonRpcTransactionBuilder.java +++ b/src/main/java/io/sui/clients/JsonRpcTransactionBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -26,6 +26,7 @@ import io.sui.models.transactions.TypeTag; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; /** * The type Json rpc transaction builder. @@ -83,12 +84,19 @@ public CompletableFuture pay( List recipients, List amounts, String gas, - long gasBudget) { + Long gasBudget) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_pay", Lists.newArrayList(signer, inputCoins, recipients, amounts, gas, gasBudget)); + "unsafe_pay", + Lists.newArrayList( + signer, + inputCoins, + recipients, + amounts.stream().map(String::valueOf).collect(Collectors.toList()), + gas, + gasBudget)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_pay", request, new TypeToken() {}.getType()); + "/unsafe_pay", request, new TypeToken() {}.getType()); } @Override @@ -97,42 +105,49 @@ public CompletableFuture paySui( List inputCoins, List recipients, List amounts, - long gasBudget) { + Long gasBudget) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_paySui", Lists.newArrayList(signer, inputCoins, recipients, amounts, gasBudget)); + "unsafe_paySui", + Lists.newArrayList( + signer, + inputCoins, + recipients, + amounts.stream().map(String::valueOf).collect(Collectors.toList()), + gasBudget)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_paySui", request, new TypeToken() {}.getType()); + "/unsafe_paySui", request, new TypeToken() {}.getType()); } @Override public CompletableFuture payAllSui( - String signer, List inputCoins, String recipient, long gasBudget) { + String signer, List inputCoins, String recipient, Long gasBudget) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_payAllSui", Lists.newArrayList(signer, inputCoins, recipient, gasBudget)); + "unsafe_payAllSui", Lists.newArrayList(signer, inputCoins, recipient, gasBudget)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_payAllSui", request, new TypeToken() {}.getType()); + "/unsafe_payAllSui", request, new TypeToken() {}.getType()); } @Override public CompletableFuture transferSui( - String signer, String coin, long gasBudget, String recipient, long amount) { + String signer, String coin, Long gasBudget, String recipient, Long amount) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_transferSui", Lists.newArrayList(signer, coin, gasBudget, recipient, amount)); + "unsafe_transferSui", Lists.newArrayList(signer, coin, gasBudget, recipient, amount)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_transferSui", request, new TypeToken() {}.getType()); + "/unsafe_transferSui", request, new TypeToken() {}.getType()); } @Override public CompletableFuture transferObject( - String signer, String suiObject, String recipient, String gas, long gasBudget) { + String signer, String suiObject, String recipient, String gas, Long gasBudget) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_transferObject", Lists.newArrayList(signer, suiObject, gas, gasBudget, recipient)); + "unsafe_transferObject", + Lists.newArrayList(signer, suiObject, gas, gasBudget, recipient)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_transferObject", request, new TypeToken() {}.getType()); + "/unsafe_transferObject", request, new TypeToken() {}.getType()); } @Override @@ -177,11 +192,15 @@ public CompletableFuture moveCall( @Override public CompletableFuture publish( - String signer, List compiledModules, String gas, long gasBudget) { + String signer, + List compiledModules, + List depIds, + String gas, + Long gasBudget) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_publish", Lists.newArrayList(signer, compiledModules, gas, gasBudget)); + "unsafe_publish", Lists.newArrayList(signer, compiledModules, depIds, gas, gasBudget)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_publish", request, new TypeToken() {}.getType()); + "/unsafe_publish", request, new TypeToken() {}.getType()); } } diff --git a/src/main/java/io/sui/clients/LocalTransactionBuilder.java b/src/main/java/io/sui/clients/LocalTransactionBuilder.java index 4ea96af..f8c5091 100644 --- a/src/main/java/io/sui/clients/LocalTransactionBuilder.java +++ b/src/main/java/io/sui/clients/LocalTransactionBuilder.java @@ -16,1612 +16,1608 @@ package io.sui.clients; -// import static io.sui.models.objects.ObjectStatus.Exists; -// -// import com.google.common.collect.Iterables; -// import com.google.common.collect.Lists; -// import com.google.common.collect.Streams; -// import com.novi.serde.Bytes; -// import com.novi.serde.SerializationError; -// import com.novi.serde.Tuple3; -// import io.sui.bcsgen.AccountAddress; -// import io.sui.bcsgen.CallArg; -// import io.sui.bcsgen.CallArg.Object; -// import io.sui.bcsgen.CallArg.Pure; -// import io.sui.bcsgen.GasData; -// import io.sui.bcsgen.Identifier; -// import io.sui.bcsgen.MoveValue; -// import io.sui.bcsgen.MoveValue.Bool; -// import io.sui.bcsgen.MoveValue.U8; -// import io.sui.bcsgen.MoveValue.Vector; -// import io.sui.bcsgen.ObjectArg; -// import io.sui.bcsgen.ObjectArg.ImmOrOwnedObject; -// import io.sui.bcsgen.ObjectArg.SharedObject; -// import io.sui.bcsgen.ObjectDigest; -// import io.sui.bcsgen.ObjectID; -// import io.sui.bcsgen.SequenceNumber; -// import io.sui.bcsgen.StructTag; -// import io.sui.bcsgen.SuiAddress; -// import io.sui.bcsgen.TransactionData; -// import io.sui.bcsgen.TransactionData.V1; -// import io.sui.bcsgen.TransactionDataV1; -// import io.sui.bcsgen.TransactionExpiration; -// import io.sui.bcsgen.TransactionExpiration.None; -// import io.sui.bcsgen.TypeTag.bool; -// import io.sui.bcsgen.TypeTag.u128; -// import io.sui.bcsgen.TypeTag.u16; -// import io.sui.bcsgen.TypeTag.u256; -// import io.sui.bcsgen.TypeTag.u32; -// import io.sui.bcsgen.TypeTag.u64; -// import io.sui.bcsgen.TypeTag.u8; -// import io.sui.models.objects.MoveNormalizedFunction; -// import io.sui.models.objects.MoveNormalizedType; -// import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType; -// import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType.Struct; -// import io.sui.models.objects.MoveNormalizedType.TypeMoveNormalizedType; -// import io.sui.models.objects.ObjectResponse; -// import io.sui.models.objects.SuiData.MoveObject; -// import io.sui.models.objects.SuiObject; -// import io.sui.models.objects.SuiObjectInfo; -// import io.sui.models.objects.SuiObjectOwner; -// import io.sui.models.objects.SuiObjectRef; -// import io.sui.models.transactions.RPCTransactionRequestParams; -// import io.sui.models.transactions.RPCTransactionRequestParams.MoveCallParams; -// import io.sui.models.transactions.RPCTransactionRequestParams.MoveCallRequestParams; -// import io.sui.models.transactions.RPCTransactionRequestParams.TransferObjectParams; -// import io.sui.models.transactions.RPCTransactionRequestParams.TransferObjectRequestParams; -// import io.sui.models.transactions.TransactionBytes; -// import io.sui.models.transactions.TypeTag; -// import io.sui.models.transactions.TypeTag.StructType; -// import java.math.BigInteger; -// import java.nio.charset.StandardCharsets; -// import java.util.Arrays; -// import java.util.Collection; -// import java.util.List; -// import java.util.Optional; -// import java.util.concurrent.CompletableFuture; -// import java.util.function.BiFunction; -// import java.util.function.Function; -// import java.util.stream.Collectors; -// import java.util.stream.Stream; -// import org.apache.commons.lang3.ArrayUtils; -// import org.apache.commons.lang3.StringUtils; -// import org.bitcoinj.core.Base58; -// import org.bouncycastle.util.encoders.Base64; -// import org.bouncycastle.util.encoders.Hex; -// import org.jetbrains.annotations.NotNull; -// -/// ** -// * The type Local transaction builder. -// * -// * @author grapebaba -// * @since 2023.1 -// */ -// public class LocalTransactionBuilder implements TransactionBuilder { -// -// private static final Struct RESOLVED_ASCII_STR = new Struct(); -// private static final Struct RESOLVED_UTF8_STR = new Struct(); -// private static final Struct RESOLVED_SUI_ID = new Struct(); -// private static final String GAS_COIN_TYPE = "0x2::coin::Coin<0x2::sui::SUI>"; -// private static final String SUI_FRAMEWORK_ADDRESS = -// "0x0000000000000000000000000000000000000002"; -// -// static { -// RESOLVED_ASCII_STR.setAddress("0x1"); -// RESOLVED_ASCII_STR.setModule("ascii"); -// RESOLVED_ASCII_STR.setName("String"); -// -// RESOLVED_UTF8_STR.setAddress("0x1"); -// RESOLVED_UTF8_STR.setModule("string"); -// RESOLVED_UTF8_STR.setName("String"); -// -// RESOLVED_SUI_ID.setAddress("0x2"); -// RESOLVED_SUI_ID.setModule("object"); -// RESOLVED_SUI_ID.setName("ID"); -// } -// -// private final QueryClient queryClient; -// -// /** -// * Instantiates a new Local transaction builder. -// * -// * @param queryClient the query client -// */ -// public LocalTransactionBuilder(QueryClient queryClient) { -// this.queryClient = queryClient; -// } -// -// @Override -// public CompletableFuture splitCoin( -// String signer, String coin, List splitAmounts, String gas, long gasBudget) { -// return getCoinStructTag(coin) -// .thenCompose( -// (Function>) -// typeTag -> -// moveCall( -// signer, -// SUI_FRAMEWORK_ADDRESS, -// "pay", -// "split_vec", -// Lists.newArrayList(typeTag), -// Lists.newArrayList(coin, splitAmounts), -// gas, -// gasBudget)); -// } -// -// @Override -// public CompletableFuture splitCoinEqual( -// String signer, String coin, long splitCount, String gas, long gasBudget) { -// return getCoinStructTag(coin) -// .thenCompose( -// (Function>) -// typeTag -> -// moveCall( -// signer, -// SUI_FRAMEWORK_ADDRESS, -// "pay", -// "divide_and_keep", -// Lists.newArrayList(typeTag), -// Lists.newArrayList(coin, splitCount), -// gas, -// gasBudget)); -// } -// -// @Override -// public CompletableFuture mergeCoins( -// String signer, String primaryCoin, String toMergeCoin, String gas, long gasBudget) { -// return getCoinStructTag(toMergeCoin) -// .thenCompose( -// (Function>) -// typeTag -> -// moveCall( -// signer, -// SUI_FRAMEWORK_ADDRESS, -// "pay", -// "join", -// Lists.newArrayList(typeTag), -// Lists.newArrayList(primaryCoin, toMergeCoin), -// gas, -// gasBudget)); -// } -// -// @Override -// @SuppressWarnings("unchecked") -// public CompletableFuture pay( -// String signer, -// List inputCoins, -// List recipients, -// List amounts, -// String gas, -// long gasBudget) { -// if (StringUtils.isNotEmpty(gas) && inputCoins.contains(gas)) { -// throw new GasInPayCoinsException(); -// } -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function>) -// gasPrice -> selectGas(signer, gas, gasBudget, gasPrice, inputCoins)); -// -// if (inputCoins.isEmpty()) { -// throw new EmptyInputCoinsException(); -// } -// CompletableFuture[] coinRefFutures = -// (CompletableFuture[]) -// inputCoins.stream().map(queryClient::getObjectRef).toArray(CompletableFuture[]::new); -// -// return CompletableFuture.allOf( -// ArrayUtils.addAll(coinRefFutures, gasRefFuture, refGasPriceFuture)) -// .thenApply( -// unused -> { -// final SuiObjectRef objRef = gasRefFuture.join(); -// final long refGasPrice = refGasPriceFuture.join(); -// List coinRefs = -// Arrays.stream(coinRefFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// if (coinRefs.isEmpty()) { -// throw new SuiObjectNotFoundException(); -// } -// -// Pay.Builder payBuilder = new Pay.Builder(); -// payBuilder.amounts = amounts; -// payBuilder.coins = -// coinRefs.stream() -// .map(LocalTransactionBuilder.this::getObjectRef) -// .collect(Collectors.toList()); -// payBuilder.recipients = -// recipients.stream() -// .map( -// s -> { -// List recipientBytes = geAddressBytes(s); -// final SuiAddress.Builder recipientAddressBuilder = -// new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// return recipientAddressBuilder.build(); -// }) -// .collect(Collectors.toList()); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final SingleTransactionKind.Pay.Builder payKindBuilder = -// new SingleTransactionKind.Pay.Builder(); -// payKindBuilder.value = payBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = payKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(objRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(objRef); -// return transactionBytes; -// }); -// } -// -// @Override -// @SuppressWarnings("unchecked") -// public CompletableFuture paySui( -// String signer, -// List inputCoins, -// List recipients, -// List amounts, -// long gasBudget) { -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// -// if (inputCoins.isEmpty()) { -// throw new EmptyInputCoinsException(); -// } -// CompletableFuture[] coinRefFutures = -// (CompletableFuture[]) -// inputCoins.stream().map(queryClient::getObjectRef).toArray(CompletableFuture[]::new); -// -// return CompletableFuture.allOf(ArrayUtils.addAll(coinRefFutures, refGasPriceFuture)) -// .thenApply( -// unused -> { -// final long refGasPrice = refGasPriceFuture.join(); -// List coinRefs = -// Arrays.stream(coinRefFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// -// PaySui.Builder paySuiBuilder = new PaySui.Builder(); -// paySuiBuilder.amounts = amounts; -// paySuiBuilder.coins = -// coinRefs.stream() -// .map(LocalTransactionBuilder.this::getObjectRef) -// .collect(Collectors.toList()); -// paySuiBuilder.recipients = -// recipients.stream() -// .map( -// s -> { -// List recipientBytes = geAddressBytes(s); -// final SuiAddress.Builder recipientAddressBuilder = -// new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// return recipientAddressBuilder.build(); -// }) -// .collect(Collectors.toList()); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final SingleTransactionKind.PaySui.Builder paySuiKindBuilder = -// new SingleTransactionKind.PaySui.Builder(); -// paySuiKindBuilder.value = paySuiBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = paySuiKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(coinRefs.get(0))); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(coinRefs.get(0)); -// return transactionBytes; -// }); -// } -// -// @Override -// @SuppressWarnings("unchecked") -// public CompletableFuture payAllSui( -// String signer, List inputCoins, String recipient, long gasBudget) { -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// -// if (inputCoins.isEmpty()) { -// throw new EmptyInputCoinsException(); -// } -// CompletableFuture[] coinRefFutures = -// (CompletableFuture[]) -// inputCoins.stream().map(queryClient::getObjectRef).toArray(CompletableFuture[]::new); -// -// return CompletableFuture.allOf(ArrayUtils.addAll(coinRefFutures, refGasPriceFuture)) -// .thenApply( -// unused -> { -// final long refGasPrice = refGasPriceFuture.join(); -// List coinRefs = -// Arrays.stream(coinRefFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// if (coinRefs.isEmpty()) { -// throw new SuiObjectNotFoundException(); -// } -// List recipientBytes = geAddressBytes(recipient); -// final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// -// PayAllSui.Builder payAllSuiBuilder = new PayAllSui.Builder(); -// payAllSuiBuilder.recipient = recipientAddressBuilder.build(); -// payAllSuiBuilder.coins = -// coinRefs.stream() -// .map(LocalTransactionBuilder.this::getObjectRef) -// .collect(Collectors.toList()); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final SingleTransactionKind.PayAllSui.Builder payAllSuiKindBuilder = -// new SingleTransactionKind.PayAllSui.Builder(); -// payAllSuiKindBuilder.value = payAllSuiBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = payAllSuiKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(coinRefs.get(0))); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(coinRefs.get(0)); -// return transactionBytes; -// }); -// } -// -// @Override -// public CompletableFuture transferSui( -// String signer, String coin, long gasBudget, String recipient, long amount) { -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// CompletableFuture objRefFuture = queryClient.getObjectRef(coin); -// return CompletableFuture.allOf(refGasPriceFuture, objRefFuture) -// .thenApply( -// unused -> { -// final Long refGasPrice = refGasPriceFuture.join(); -// final SuiObjectRef objRef = objRefFuture.join(); -// -// List recipientBytes = geAddressBytes(recipient); -// final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// final Builder transferSuiBuilder = new Builder(); -// transferSuiBuilder.recipient = recipientAddressBuilder.build(); -// transferSuiBuilder.amount = Optional.of(amount); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final SingleTransactionKind.TransferSui.Builder transferSuiKindBuilder = -// new SingleTransactionKind.TransferSui.Builder(); -// transferSuiKindBuilder.value = transferSuiBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = transferSuiKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(objRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(objRef); -// return transactionBytes; -// }); -// } -// -// @Override -// public CompletableFuture transferObject( -// String signer, String suiObject, String recipient, String gas, long gasBudget) { -// CompletableFuture objRefFuture = queryClient.getObjectRef(suiObject); -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function>) -// gasPrice -> -// selectGas(signer, gas, gasBudget, gasPrice, Lists.newArrayList(suiObject))); -// return CompletableFuture.allOf(refGasPriceFuture, objRefFuture, gasRefFuture) -// .thenApply( -// unused -> { -// final Long refGasPrice = refGasPriceFuture.join(); -// final SuiObjectRef objRef = objRefFuture.join(); -// final SuiObjectRef gasRef = gasRefFuture.join(); -// -// List recipientBytes = geAddressBytes(recipient); -// final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// -// final TransferObject.Builder transferObjectBuilder = new TransferObject.Builder(); -// transferObjectBuilder.recipient = recipientAddressBuilder.build(); -// transferObjectBuilder.object_ref = getObjectRef(objRef); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final SingleTransactionKind.TransferObject.Builder transferObjectKindBuilder = -// new SingleTransactionKind.TransferObject.Builder(); -// transferObjectKindBuilder.value = transferObjectBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = transferObjectKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(gasRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(gasRef); -// return transactionBytes; -// }); -// } -// -// @Override -// @SuppressWarnings("unchecked") -// public CompletableFuture batchTransaction( -// String signer, -// List batchTransactionParams, -// String gas, -// long gasBudget) { -// CompletableFuture[] kindFutures = -// (CompletableFuture[]) -// batchTransactionParams.stream() -// .map( -// rpcTransactionRequestParams -> { -// if (rpcTransactionRequestParams instanceof TransferObjectRequestParams) { -// TransferObjectParams transferObjectParams = -// ((TransferObjectRequestParams) rpcTransactionRequestParams) -// .getTransferObjectRequestParams(); -// return queryClient -// .getObjectRef(transferObjectParams.getObjectId()) -// .thenApply( -// (Function) -// suiObjectRef -> { -// List recipientBytes = -// geAddressBytes(transferObjectParams.getRecipient()); -// final SuiAddress.Builder recipientAddressBuilder = -// new SuiAddress.Builder(); -// recipientAddressBuilder.value = recipientBytes; -// -// final TransferObject.Builder transferObjectBuilder = -// new TransferObject.Builder(); -// transferObjectBuilder.recipient = -// recipientAddressBuilder.build(); -// transferObjectBuilder.object_ref = -// getObjectRef(suiObjectRef); -// -// final SingleTransactionKind.TransferObject.Builder -// transferObjectKindBuilder = -// new SingleTransactionKind.TransferObject.Builder(); -// transferObjectKindBuilder.value = -// transferObjectBuilder.build(); -// -// return transferObjectKindBuilder.build(); -// }); -// } -// -// if (rpcTransactionRequestParams instanceof MoveCallRequestParams) { -// MoveCallParams moveCallParams = -// ((MoveCallRequestParams) rpcTransactionRequestParams) -// .getMoveCallRequestParams(); -// -// List bcsTypeArguments = -// moveCallParams.getTypeArguments().stream() -// .map(LocalTransactionBuilder.this::toBcsTypeTag) -// .collect(Collectors.toList()); -// -// return extractNormalizedFunctionParams( -// moveCallParams.getPackageObjectId(), -// moveCallParams.getModule(), -// moveCallParams.getFunction()) -// .thenCompose( -// (Function< -// List, -// CompletableFuture>) -// moveNormalizedTypes -> { -// if (moveNormalizedTypes.size() -// != moveCallParams.getArguments().size()) { -// throw new MoveCallArgSizeNotMatchException( -// moveNormalizedTypes.size(), -// moveCallParams.getArguments().size()); -// } -// CompletableFuture[] callArgFutures = -// (CompletableFuture[]) -// Streams.zip( -// moveNormalizedTypes.stream(), -// moveCallParams.getArguments().stream(), -// (BiFunction< -// MoveNormalizedType, -// java.lang.Object, -// CompletableFuture>) -// LocalTransactionBuilder.this -// ::toBcsCallArg) -// .toArray(CompletableFuture[]::new); -// return CompletableFuture.allOf(callArgFutures) -// .thenCompose( -// (Function< -// Void, -// CompletableFuture>) -// unused -> { -// List callArgs = -// Arrays.stream(callArgFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// List excludeObjects = -// callArgs.stream() -// .flatMap( -// (Function< -// CallArg, Stream>) -// callArg -> { -// if (callArg -// instanceof ObjVec) { -// return ((ObjVec) callArg) -// .value.stream(); -// } else if (callArg -// instanceof Object) { -// return Stream.of( -// ((Object) callArg) -// .value); -// } -// -// return Stream.empty(); -// }) -// .map( -// (Function< -// ObjectArg, -// Optional>) -// objectArg -> { -// if (objectArg -// instanceof -// SharedObject) { -// return Optional.of( -// toAddress( -// ((SharedObject) -// objectArg) -// .id -// .value -// .value)); -// } -// -// if (objectArg -// instanceof -// ImmOrOwnedObject) { -// return Optional.of( -// toAddress( -// ((ImmOrOwnedObject) -// objectArg) -// .value -// .field0 -// .value -// .value)); -// } -// -// return Optional.empty(); -// }) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.toList()); -// -// CompletableFuture refGasPriceFuture = -// queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function< -// Long, -// CompletableFuture< -// SuiObjectRef>>) -// gasPrice -> -// selectGas( -// signer, -// gas, -// gasBudget, -// gasPrice, -// excludeObjects)); -// return CompletableFuture.allOf( -// gasRefFuture, refGasPriceFuture) -// .thenApply( -// unused1 -> { -// Identifier.Builder moduleBuilder = -// new Identifier.Builder(); -// moduleBuilder.value = -// moveCallParams.getModule(); -// Identifier.Builder functionBuilder = -// new Identifier.Builder(); -// functionBuilder.value = -// moveCallParams.getFunction(); -// -// AccountAddress.Builder -// objectAddressBuilder = -// new AccountAddress.Builder(); -// objectAddressBuilder.value = -// geAddressBytes( -// moveCallParams -// .getPackageObjectId()); -// ObjectID.Builder objectIdBuilder = -// new ObjectID.Builder(); -// objectIdBuilder.value = -// objectAddressBuilder.build(); -// final MoveCall.Builder -// moveCallBuilder = -// new MoveCall.Builder(); -// moveCallBuilder.type_arguments = -// bcsTypeArguments; -// moveCallBuilder.arguments = callArgs; -// moveCallBuilder.Package = -// objectIdBuilder.build(); -// moveCallBuilder.module = -// moduleBuilder.build(); -// moveCallBuilder.function = -// functionBuilder.build(); -// -// final Call.Builder -// moveCallKindBuilder = -// new Call.Builder(); -// moveCallKindBuilder.value = -// moveCallBuilder.build(); -// -// return moveCallKindBuilder.build(); -// }); -// }); -// }); -// } -// throw new NotSupportedTransactionKindException(); -// }) -// .toArray(CompletableFuture[]::new); -// return CompletableFuture.allOf(kindFutures) -// .thenCompose( -// (Function>) -// unused -> { -// final List kinds = -// Arrays.stream(kindFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// -// List excludeObjects = -// kinds.stream() -// .map( -// singleTransactionKind -> { -// if (singleTransactionKind -// instanceof SingleTransactionKind.TransferObject) { -// -// return Lists.newArrayList( -// toAddress( -// ((SingleTransactionKind.TransferObject) -// singleTransactionKind) -// .value -// .object_ref -// .field0 -// .value -// .value)); -// } -// -// if (singleTransactionKind instanceof Call) { -// List callArgs = -// ((Call) singleTransactionKind).value.arguments; -// -// return callArgs.stream() -// .flatMap( -// (Function>) -// callArg -> { -// if (callArg instanceof ObjVec) { -// return ((ObjVec) callArg).value.stream(); -// } else if (callArg instanceof Object) { -// return Stream.of(((Object) callArg).value); -// } -// -// return Stream.empty(); -// }) -// .map( -// (Function>) -// objectArg -> { -// if (objectArg instanceof SharedObject) { -// return Optional.of( -// toAddress( -// ((SharedObject) objectArg) -// .id -// .value -// .value)); -// } -// -// if (objectArg instanceof ImmOrOwnedObject) { -// return Optional.of( -// toAddress( -// ((ImmOrOwnedObject) objectArg) -// .value -// .field0 -// .value -// .value)); -// } -// -// return Optional.empty(); -// }) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.toList()); -// } -// -// throw new NotSupportedTransactionKindException(); -// }) -// .flatMap(Collection::stream) -// .collect(Collectors.toList()); -// -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function>) -// gasPrice -> -// selectGas(signer, gas, gasBudget, gasPrice, excludeObjects)); -// return CompletableFuture.allOf(gasRefFuture, refGasPriceFuture) -// .thenApply( -// unused12 -> { -// final Batch.Builder batchBuilder = new Batch.Builder(); -// batchBuilder.value = kinds; -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = -// new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// final Long refGasPrice = refGasPriceFuture.join(); -// final SuiObjectRef gasRef = gasRefFuture.join(); -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(gasRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = batchBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = -// new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(gasRef); -// return transactionBytes; -// }); -// }); -// } -// -// @Override -// @SuppressWarnings("unchecked") -// public CompletableFuture moveCall( -// String signer, -// String packageObjectId, -// String module, -// String function, -// List typeArguments, -// List arguments, -// String gas, -// long gasBudget) { -// List bcsTypeArguments = -// typeArguments.stream().map(this::toBcsTypeTag).collect(Collectors.toList()); -// -// return extractNormalizedFunctionParams(packageObjectId, module, function) -// .thenCompose( -// (Function, CompletableFuture>) -// moveNormalizedTypes -> { -// if (moveNormalizedTypes.size() != arguments.size()) { -// throw new MoveCallArgSizeNotMatchException( -// moveNormalizedTypes.size(), arguments.size()); -// } -// CompletableFuture[] callArgFutures = -// (CompletableFuture[]) -// Streams.zip( -// moveNormalizedTypes.stream(), -// arguments.stream(), -// (BiFunction< -// MoveNormalizedType, -// java.lang.Object, -// CompletableFuture>) -// this::toBcsCallArg) -// .toArray(CompletableFuture[]::new); -// return CompletableFuture.allOf(callArgFutures) -// .thenCompose( -// (Function>) -// unused -> { -// List callArgs = -// Arrays.stream(callArgFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// List excludeObjects = -// callArgs.stream() -// .flatMap( -// (Function>) -// callArg -> { -// if (callArg instanceof ObjVec) { -// return ((ObjVec) callArg).value.stream(); -// } else if (callArg instanceof Object) { -// return Stream.of(((Object) callArg).value); -// } -// -// return Stream.empty(); -// }) -// .map( -// (Function>) -// objectArg -> { -// if (objectArg instanceof SharedObject) { -// return Optional.of( -// toAddress( -// ((SharedObject) objectArg) -// .id -// .value -// .value)); -// } -// -// if (objectArg instanceof ImmOrOwnedObject) { -// return Optional.of( -// toAddress( -// ((ImmOrOwnedObject) objectArg) -// .value -// .field0 -// .value -// .value)); -// } -// -// return Optional.empty(); -// }) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.toList()); -// -// CompletableFuture refGasPriceFuture = -// queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function>) -// gasPrice -> -// selectGas( -// signer, -// gas, -// gasBudget, -// gasPrice, -// excludeObjects)); -// -// return CompletableFuture.allOf(gasRefFuture, refGasPriceFuture) -// .thenApply( -// unused1 -> { -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = -// new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// Identifier.Builder moduleBuilder = -// new Identifier.Builder(); -// moduleBuilder.value = module; -// Identifier.Builder functionBuilder = -// new Identifier.Builder(); -// functionBuilder.value = function; -// -// AccountAddress.Builder objectAddressBuilder = -// new AccountAddress.Builder(); -// objectAddressBuilder.value = -// geAddressBytes(packageObjectId); -// ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); -// objectIdBuilder.value = objectAddressBuilder.build(); -// final MoveCall.Builder moveCallBuilder = -// new MoveCall.Builder(); -// moveCallBuilder.type_arguments = bcsTypeArguments; -// moveCallBuilder.arguments = callArgs; -// moveCallBuilder.Package = objectIdBuilder.build(); -// moveCallBuilder.module = moduleBuilder.build(); -// moveCallBuilder.function = functionBuilder.build(); -// -// final Call.Builder moveCallKindBuilder = -// new Call.Builder(); -// moveCallKindBuilder.value = moveCallBuilder.build(); -// -// final Single.Builder singleKindBuilder = -// new Single.Builder(); -// singleKindBuilder.value = moveCallKindBuilder.build(); -// -// long refGasPrice = refGasPriceFuture.join(); -// SuiObjectRef gasRef = gasRefFuture.join(); -// final GasData.Builder gasDataBuilder = -// new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = -// Lists.newArrayList(getObjectRef(gasRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = -// senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = -// gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = -// new None.Builder(); -// transactionDataV1Builder.expiration = -// expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = -// new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = -// new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(gasRef); -// return transactionBytes; -// }); -// }); -// }); -// } -// -// @Override -// public CompletableFuture publish( -// String signer, List compiledModules, String gas, long gasBudget) { -// CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); -// CompletableFuture gasRefFuture = -// refGasPriceFuture.thenCompose( -// (Function>) -// gasPrice -> selectGas(signer, gas, gasBudget, gasPrice, Lists.newArrayList())); -// return CompletableFuture.allOf(refGasPriceFuture, gasRefFuture) -// .thenApply( -// unused -> { -// final Long refGasPrice = refGasPriceFuture.join(); -// final SuiObjectRef objRef = gasRefFuture.join(); -// -// List senderBytes = geAddressBytes(signer); -// final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); -// senderAddressBuilder.value = senderBytes; -// -// MoveModulePublish.Builder moveModulePublishBuilder = new MoveModulePublish.Builder(); -// moveModulePublishBuilder.modules = -// compiledModules.stream() -// .map(s -> Bytes.valueOf(Base64.decode(s))) -// .collect(Collectors.toList()); -// final SingleTransactionKind.Publish.Builder publishKindBuilder = -// new SingleTransactionKind.Publish.Builder(); -// publishKindBuilder.value = moveModulePublishBuilder.build(); -// -// final Single.Builder singleKindBuilder = new Single.Builder(); -// singleKindBuilder.value = publishKindBuilder.build(); -// -// final GasData.Builder gasDataBuilder = new GasData.Builder(); -// gasDataBuilder.budget = gasBudget; -// gasDataBuilder.price = refGasPrice; -// gasDataBuilder.payment = Lists.newArrayList(getObjectRef(objRef)); -// gasDataBuilder.owner = senderAddressBuilder.build(); -// final TransactionDataV1.Builder transactionDataV1Builder = -// new TransactionDataV1.Builder(); -// transactionDataV1Builder.kind = singleKindBuilder.build(); -// transactionDataV1Builder.sender = senderAddressBuilder.build(); -// transactionDataV1Builder.gas_data = gasDataBuilder.build(); -// TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); -// transactionDataV1Builder.expiration = expirationBuilder.build(); -// -// final TransactionData.V1.Builder v1Builder = new V1.Builder(); -// v1Builder.value = transactionDataV1Builder.build(); -// -// final TransactionBytes transactionBytes = new TransactionBytes(); -// transactionBytes.setLocalTxBytes(v1Builder.build()); -// transactionBytes.setGas(objRef); -// return transactionBytes; -// }); -// } -// -// private CompletableFuture getCoinStructTag(String objectId) { -// return queryClient -// .getObject(objectId) -// .thenApply( -// objectResponse -> { -// String type = null; -// if (objectResponse.getDetails() instanceof SuiObjectInfo) { -// type = ((SuiObjectInfo) objectResponse.getDetails()).getType(); -// } -// -// if (objectResponse.getDetails() instanceof SuiObject) { -// if (((SuiObject) objectResponse.getDetails()).getData() instanceof MoveObject) { -// type = -// ((MoveObject) ((SuiObject) objectResponse.getDetails()).getData()).getType(); -// } -// } -// -// if (null == type) { -// throw new SuiObjectNotFoundException(); -// } -// -// if (!GAS_COIN_TYPE.equals(type)) { -// throw new ObjectIsNotCoinException(objectId); -// } -// -// io.sui.models.transactions.StructTag structTag = -// new io.sui.models.transactions.StructTag(); -// structTag.setAddress(SUI_FRAMEWORK_ADDRESS); -// structTag.setModule("sui"); -// structTag.setName("SUI"); -// structTag.setTypeParams(Lists.newArrayList()); -// -// StructType structType = new StructType(); -// structType.setStructTag(structTag); -// return structType; -// }); -// } -// -// @SuppressWarnings("unchecked") -// private CompletableFuture selectGas( -// String signer, String inputGas, long budget, long gasPrice, List excludeObjects) { -// if (StringUtils.isNotEmpty(inputGas)) { -// return queryClient.getObjectRef(inputGas); -// } else { -// return queryClient -// .getObjectsOwnedByAddress(signer) -// .thenCompose( -// (Function, CompletableFuture>) -// suiObjectInfos -> { -// CompletableFuture>[] gases = -// (CompletableFuture>[]) -// suiObjectInfos.stream() -// .map( -// suiObjectInfo -> { -// if (suiObjectInfo.getType().equals(GAS_COIN_TYPE)) { -// return queryClient -// .getObject(suiObjectInfo.getObjectId()) -// .thenCompose( -// (Function< -// ObjectResponse, -// CompletableFuture>>) -// objectResponse -> { -// final SuiObject suiObject = -// (SuiObject) objectResponse.getDetails(); -// final long balance = -// Long.parseLong( -// (String) -// ((MoveObject) suiObject.getData()) -// .getFields() -// .get("balance")); -// final long requiredGasAmount = -// BigInteger.valueOf(budget) -// .multiply( -// BigInteger.valueOf(gasPrice)) -// .longValue(); -// if (!excludeObjects.contains( -// suiObjectInfo.getObjectId()) -// && balance >= requiredGasAmount) { -// return CompletableFuture.completedFuture( -// Optional.of(suiObject.getReference())); -// } -// -// return CompletableFuture.completedFuture( -// Optional.empty()); -// }); -// } -// return CompletableFuture -// .>completedFuture( -// Optional.empty()); -// }) -// .toArray(CompletableFuture[]::new); -// -// return CompletableFuture.allOf(gases) -// .thenApply( -// unused -> { -// Optional> selected = -// Arrays.stream(gases) -// .map(CompletableFuture::join) -// .filter(Optional::isPresent) -// .findFirst(); -// -// if (!selected.isPresent()) { -// throw new GasNotFoundException(); -// } -// -// return selected.get().get(); -// }); -// }); -// } -// } -// -// private CompletableFuture> extractNormalizedFunctionParams( -// String packageObjectId, String module, String function) { -// CompletableFuture normalizedFunction = -// this.queryClient.getNormalizedMoveFunction(packageObjectId, module, function); -// return normalizedFunction.thenCompose( -// (Function>>) -// moveNormalizedFunction -> { -// final boolean hasTxContext = -// moveNormalizedFunction.getParameters().size() > 0 -// && isTxContext(Iterables.getLast(moveNormalizedFunction.getParameters())); -// return CompletableFuture.completedFuture( -// hasTxContext -// ? moveNormalizedFunction -// .getParameters() -// .subList(0, moveNormalizedFunction.getParameters().size() - 1) -// : moveNormalizedFunction.getParameters()); -// }); -// } -// -// private Optional toPureMoveValue( -// MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { -// final MoveValue moveValue; -// if (moveNormalizedType instanceof MoveNormalizedType.TypeMoveNormalizedType) { -// MoveNormalizedType.TypeMoveNormalizedType argType = -// (MoveNormalizedType.TypeMoveNormalizedType) moveNormalizedType; -// switch (argType) { -// case U8: -// checkArgType(moveNormalizedType, argVal, Byte.class); -// MoveValue.U8.Builder u8Builder = new MoveValue.U8.Builder(); -// u8Builder.value = (Byte) argVal; -// moveValue = u8Builder.build(); -// break; -// case U16: -// checkArgType(moveNormalizedType, argVal, Short.class); -// -// MoveValue.U16.Builder u16Builder = new MoveValue.U16.Builder(); -// u16Builder.value = (Short) argVal; -// moveValue = u16Builder.build(); -// break; -// case U32: -// checkArgType(moveNormalizedType, argVal, Integer.class); -// -// MoveValue.U32.Builder u32Builder = new MoveValue.U32.Builder(); -// u32Builder.value = (Integer) argVal; -// moveValue = u32Builder.build(); -// break; -// case U64: -// checkArgType(moveNormalizedType, argVal, Long.class); -// -// MoveValue.U64.Builder u64Builder = new MoveValue.U64.Builder(); -// u64Builder.value = (Long) argVal; -// moveValue = u64Builder.build(); -// break; -// case U128: -// checkArgType(moveNormalizedType, argVal, BigInteger.class); -// -// MoveValue.U128.Builder u128Builder = new MoveValue.U128.Builder(); -// u128Builder.value = (BigInteger) argVal; -// moveValue = u128Builder.build(); -// break; -// case U256: -// checkArgType(moveNormalizedType, argVal, byte[].class); -// -// MoveValue.U256.Builder u256Builder = new MoveValue.U256.Builder(); -// u256Builder.value = Arrays.asList(ArrayUtils.toObject((byte[]) argVal)); -// moveValue = u256Builder.build(); -// break; -// case Bool: -// checkArgType(moveNormalizedType, argVal, Boolean.class); -// -// MoveValue.Bool.Builder boolBuilder = new Bool.Builder(); -// boolBuilder.value = (Boolean) argVal; -// moveValue = boolBuilder.build(); -// break; -// case Address: -// checkArgType(moveNormalizedType, argVal, String.class); -// -// AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); -// addressBuilder.value = geAddressBytes((String) argVal); -// MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); -// addressValueBuilder.value = addressBuilder.build(); -// moveValue = addressValueBuilder.build(); -// break; -// default: -// throw new NotSupportedMoveNormalizedTypeException(); -// } -// -// return Optional.of(moveValue); -// } -// -// if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { -// final Struct argStruct = -// ((MoveNormalizedType.MoveNormalizedStructType) moveNormalizedType).getStruct(); -// if (argStruct.equals(RESOLVED_ASCII_STR)) { -// checkArgType(moveNormalizedType, argVal, String.class); -// -// MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); -// vectorBuilder.value = -// Arrays.stream( -// ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.US_ASCII))) -// .map( -// (Function) -// b -> { -// U8.Builder u8Builder = new U8.Builder(); -// u8Builder.value = b; -// return u8Builder.build(); -// }) -// .collect(Collectors.toList()); -// moveValue = vectorBuilder.build(); -// -// return Optional.of(moveValue); -// } else if (argStruct.equals(RESOLVED_UTF8_STR)) { -// checkArgType(moveNormalizedType, argVal, String.class); -// -// MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); -// vectorBuilder.value = -// Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) -// .map( -// (Function) -// b -> { -// U8.Builder u8Builder = new U8.Builder(); -// u8Builder.value = b; -// return u8Builder.build(); -// }) -// .collect(Collectors.toList()); -// moveValue = vectorBuilder.build(); -// -// return Optional.of(moveValue); -// } else if (argStruct.equals(RESOLVED_SUI_ID)) { -// checkArgType(moveNormalizedType, argVal, String.class); -// -// AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); -// addressBuilder.value = geAddressBytes((String) argVal); -// MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); -// addressValueBuilder.value = addressBuilder.build(); -// moveValue = addressValueBuilder.build(); -// -// return Optional.of(moveValue); -// } -// } -// -// if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { -// if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) moveNormalizedType).getVector() -// == TypeMoveNormalizedType.U8) { -// checkArgType(moveNormalizedType, argVal, String.class); -// -// MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); -// vectorBuilder.value = -// Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) -// .map( -// (Function) -// b -> { -// U8.Builder u8Builder = new U8.Builder(); -// u8Builder.value = b; -// return u8Builder.build(); -// }) -// .collect(Collectors.toList()); -// moveValue = vectorBuilder.build(); -// -// return Optional.of(moveValue); -// } -// -// if (!(argVal instanceof List)) { -// throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); -// } -// -// List objects = (List) argVal; -// List pureMoveValues = -// objects.stream() -// .map( -// object -> -// toPureMoveValue( -// ((MoveNormalizedType.VectorReferenceMoveNormalizedType) -// moveNormalizedType) -// .getVector(), -// object)) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.toList()); -// -// if (pureMoveValues.isEmpty()) { -// // ObjVec TYPE will be handled later -// return Optional.empty(); -// } -// -// MoveValue.Vector.Builder moveValueVectorBuilder = new Vector.Builder(); -// moveValueVectorBuilder.value = pureMoveValues; -// -// return Optional.of(moveValueVectorBuilder.build()); -// } -// -// return Optional.empty(); -// } -// -// @SuppressWarnings("unchecked") -// private CompletableFuture toBcsCallArg( -// MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { -// final Optional pureMoveValue = toPureMoveValue(moveNormalizedType, argVal); -// if (pureMoveValue.isPresent()) { -// final CallArg.Pure.Builder pureBuilder = getPureBuilder(pureMoveValue.get()); -// return CompletableFuture.completedFuture(pureBuilder.build()); -// } -// -// if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { -// -// if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) moveNormalizedType).getVector() -// instanceof MoveNormalizedType.MoveNormalizedStructType) { -// checkArgType(moveNormalizedType, argVal, List.class); -// -// CompletableFuture[] objectArgFutures = -// (CompletableFuture[]) -// Arrays.stream((String[]) argVal) -// .map(this::newObjectArg) -// .toArray(CompletableFuture[]::new); -// -// return CompletableFuture.allOf(objectArgFutures) -// .thenApply( -// unused -> { -// final CallArg.ObjVec.Builder objVecBuilder = new ObjVec.Builder(); -// objVecBuilder.value = -// Arrays.stream(objectArgFutures) -// .map(CompletableFuture::join) -// .collect(Collectors.toList()); -// return objVecBuilder.build(); -// }); -// } -// } -// -// final Optional structOptional = -// extractStruct(moveNormalizedType).map(MoveNormalizedStructType::getStruct); -// -// if (structOptional.isPresent() -// || (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedTypeParameterType)) { -// checkArgType(moveNormalizedType, argVal, String.class); -// -// return newObjectArg((String) argVal) -// .thenApply( -// objectArg -> { -// final Object.Builder objectBuilder = new Object.Builder(); -// objectBuilder.value = objectArg; -// return objectBuilder.build(); -// }); -// } -// -// throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); -// } -// -// private CompletableFuture newObjectArg(String objectId) { -// return queryClient -// .getObject(objectId) -// .thenApply( -// objectResponse -> { -// if (Exists != objectResponse.getStatus()) { -// throw new SuiObjectNotFoundException(); -// } -// final SuiObjectOwner owner = ((SuiObject) objectResponse.getDetails()).getOwner(); -// if (owner instanceof SuiObjectOwner.SharedOwner) { -// AccountAddress.Builder accountAddressBuilder = new AccountAddress.Builder(); -// accountAddressBuilder.value = geAddressBytes(objectId); -// ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); -// objectIdBuilder.value = accountAddressBuilder.build(); -// SequenceNumber.Builder seqBuilder = new SequenceNumber.Builder(); -// seqBuilder.value = -// ((SuiObjectOwner.SharedOwner) owner).getShared().getInitial_shared_version(); -// SharedObject.Builder sharedObjectBuilder = new SharedObject.Builder(); -// sharedObjectBuilder.id = objectIdBuilder.build(); -// sharedObjectBuilder.initial_shared_version = seqBuilder.build(); -// sharedObjectBuilder.mutable = true; -// return sharedObjectBuilder.build(); -// } -// -// ImmOrOwnedObject.Builder immOrOwnedObjectBuilder = new ImmOrOwnedObject.Builder(); -// immOrOwnedObjectBuilder.value = getObjectRef(objectResponse.getObjectRef()); -// return immOrOwnedObjectBuilder.build(); -// }); -// } -// -// private void checkArgType( -// MoveNormalizedType moveNormalizedType, java.lang.Object argVal, Class expectedArgClass) { -// if (!expectedArgClass.isInstance(argVal)) { -// throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); -// } -// } -// -// @NotNull -// private Pure.Builder getPureBuilder(MoveValue moveValue) { -// final Pure.Builder pureBuilder = new Pure.Builder(); -// try { -// pureBuilder.value = Arrays.asList(ArrayUtils.toObject(moveValue.bcsSerialize())); -// } catch (SerializationError e) { -// throw new BcsSerializationException(e); -// } -// return pureBuilder; -// } -// -// private boolean isTxContext(MoveNormalizedType moveNormalizedType) { -// if (moveNormalizedType instanceof MoveNormalizedType.MutableReferenceMoveNormalizedType) { -// final MoveNormalizedType mutableRefMoveNormalizedType = -// ((MoveNormalizedType.MutableReferenceMoveNormalizedType) moveNormalizedType) -// .getMutableReference(); -// if (mutableRefMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { -// final Struct struct = ((MoveNormalizedStructType) mutableRefMoveNormalizedType).getStruct(); -// return struct.getAddress().equals("0x2") -// && struct.getModule().equals("tx_context") -// && struct.getName().equals("TxContext"); -// } else { -// return false; -// } -// } else { -// return false; -// } -// } -// -// private Optional extractStruct(MoveNormalizedType moveNormalizedType) { -// if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { -// return Optional.of((MoveNormalizedStructType) moveNormalizedType); -// } else if (moveNormalizedType instanceof MoveNormalizedType.ReferenceMoveNormalizedType) { -// final MoveNormalizedType refMoveNormalizedType = -// ((MoveNormalizedType.ReferenceMoveNormalizedType) moveNormalizedType).getReference(); -// if (refMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { -// return Optional.of((MoveNormalizedStructType) refMoveNormalizedType); -// } -// } else if (moveNormalizedType -// instanceof MoveNormalizedType.MutableReferenceMoveNormalizedType) { -// final MoveNormalizedType mutableRefMoveNormalizedType = -// ((MoveNormalizedType.MutableReferenceMoveNormalizedType) moveNormalizedType) -// .getMutableReference(); -// if (mutableRefMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { -// return Optional.of((MoveNormalizedStructType) mutableRefMoveNormalizedType); -// } -// } -// -// return Optional.empty(); -// } -// -// @NotNull -// private List geAddressBytes(String address) { -// return Arrays.asList(ArrayUtils.toObject(Hex.decode(StringUtils.removeStart(address, "0x")))); -// } -// -// private String toAddress(List addressBytes) { -// return StringUtils.prependIfMissing( -// Hex.toHexString(ArrayUtils.toPrimitive(addressBytes.toArray(new Byte[0]))), "0x"); -// } -// -// private Tuple3 getObjectRef(SuiObjectRef objRef) { -// AccountAddress.Builder coinAddressBuilder = new AccountAddress.Builder(); -// coinAddressBuilder.value = geAddressBytes(objRef.getObjectId()); -// -// ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); -// objectIdBuilder.value = coinAddressBuilder.build(); -// -// SequenceNumber.Builder sequenceNumberBuilder = new SequenceNumber.Builder(); -// sequenceNumberBuilder.value = objRef.getVersion(); -// Sha3Digest.Builder sha3DigestBuilder = new Sha3Digest.Builder(); -// sha3DigestBuilder.value = Bytes.valueOf(Base58.decode(objRef.getDigest())); -// ObjectDigest.Builder objectDigestBuilder = new ObjectDigest.Builder(); -// objectDigestBuilder.value = sha3DigestBuilder.build(); -// -// return new Tuple3<>( -// objectIdBuilder.build(), sequenceNumberBuilder.build(), objectDigestBuilder.build()); -// } -// -// private io.sui.bcsgen.TypeTag toBcsTypeTag(TypeTag typeTag) { -// if (typeTag instanceof TypeTag.SimpleType) { -// switch ((TypeTag.SimpleType) typeTag) { -// case u8: -// io.sui.bcsgen.TypeTag.u8.Builder u8builder = new u8.Builder(); -// return u8builder.build(); -// case u16: -// io.sui.bcsgen.TypeTag.u16.Builder u16builder = new u16.Builder(); -// return u16builder.build(); -// case u32: -// io.sui.bcsgen.TypeTag.u32.Builder u32builder = new u32.Builder(); -// return u32builder.build(); -// case u64: -// io.sui.bcsgen.TypeTag.u64.Builder u64builder = new u64.Builder(); -// return u64builder.build(); -// case bool: -// io.sui.bcsgen.TypeTag.bool.Builder boolBuilder = new bool.Builder(); -// return boolBuilder.build(); -// case u128: -// io.sui.bcsgen.TypeTag.u128.Builder u128builder = new u128.Builder(); -// return u128builder.build(); -// case u256: -// io.sui.bcsgen.TypeTag.u256.Builder u256builder = new u256.Builder(); -// return u256builder.build(); -// case signer: -// io.sui.bcsgen.TypeTag.signer.Builder signerBuilder = -// new io.sui.bcsgen.TypeTag.signer.Builder(); -// return signerBuilder.build(); -// case address: -// io.sui.bcsgen.TypeTag.address.Builder addressBuilder = -// new io.sui.bcsgen.TypeTag.address.Builder(); -// return addressBuilder.build(); -// default: -// throw new NotSupportedTypeTagException(); -// } -// } else if (typeTag instanceof TypeTag.VectorType) { -// io.sui.bcsgen.TypeTag.vector.Builder vectorBuilder = -// new io.sui.bcsgen.TypeTag.vector.Builder(); -// vectorBuilder.value = toBcsTypeTag(((TypeTag.VectorType) typeTag).getTypeTag()); -// return vectorBuilder.build(); -// } else { -// AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); -// addressBuilder.value = -// geAddressBytes(((TypeTag.StructType) typeTag).getStructTag().getAddress()); -// Identifier.Builder moduleBuilder = new Identifier.Builder(); -// moduleBuilder.value = ((TypeTag.StructType) typeTag).getStructTag().getModule(); -// Identifier.Builder nameBuilder = new Identifier.Builder(); -// nameBuilder.value = ((TypeTag.StructType) typeTag).getStructTag().getName(); -// -// StructTag.Builder structTagBuilder = new StructTag.Builder(); -// structTagBuilder.address = addressBuilder.build(); -// structTagBuilder.module = moduleBuilder.build(); -// structTagBuilder.name = nameBuilder.build(); -// structTagBuilder.type_args = -// ((TypeTag.StructType) typeTag) -// .getStructTag().getTypeParams().stream() -// .map(this::toBcsTypeTag) -// .collect(Collectors.toList()); -// io.sui.bcsgen.TypeTag.struct.Builder structbuilder = -// new io.sui.bcsgen.TypeTag.struct.Builder(); -// structbuilder.value = structTagBuilder.build(); -// return structbuilder.build(); -// } -// } -// } +import static io.sui.models.transactions.TypeTag.SimpleType.u8; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.novi.serde.Bytes; +import com.novi.serde.DeserializationError; +import com.novi.serde.SerializationError; +import com.novi.serde.Tuple3; +import io.sui.bcsgen.AccountAddress; +import io.sui.bcsgen.CallArg.Pure; +import io.sui.bcsgen.Digest; +import io.sui.bcsgen.GasCoin; +import io.sui.bcsgen.GasData; +import io.sui.bcsgen.Identifier; +import io.sui.bcsgen.MoveValue; +import io.sui.bcsgen.MoveValue.Bool; +import io.sui.bcsgen.MoveValue.U8; +import io.sui.bcsgen.MoveValue.Vector; +import io.sui.bcsgen.ObjectDigest; +import io.sui.bcsgen.ObjectID; +import io.sui.bcsgen.ProgrammableTransaction; +import io.sui.bcsgen.SequenceNumber; +import io.sui.bcsgen.StructTag; +import io.sui.bcsgen.SuiAddress; +import io.sui.bcsgen.TransactionData; +import io.sui.bcsgen.TransactionData.V1; +import io.sui.bcsgen.TransactionDataV1; +import io.sui.bcsgen.TransactionExpiration; +import io.sui.bcsgen.TransactionExpiration.None; +import io.sui.bcsgen.TransactionKind; +import io.sui.bcsgen.TransactionKind.ProgrammableTransaction.Builder; +import io.sui.bcsgen.TypeTag.bool; +import io.sui.bcsgen.TypeTag.u128; +import io.sui.bcsgen.TypeTag.u16; +import io.sui.bcsgen.TypeTag.u256; +import io.sui.bcsgen.TypeTag.u32; +import io.sui.bcsgen.TypeTag.u64; +import io.sui.bcsgen.TypeTag.u8; +import io.sui.models.objects.MoveNormalizedFunction; +import io.sui.models.objects.MoveNormalizedType; +import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType; +import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType.Struct; +import io.sui.models.objects.MoveNormalizedType.TypeMoveNormalizedType; +import io.sui.models.objects.ObjectDataOptions; +import io.sui.models.objects.ObjectResponseQuery; +import io.sui.models.objects.PaginatedObjectsResponse; +import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiRawData; +import io.sui.models.transactions.RPCTransactionRequestParams; +import io.sui.models.transactions.TransactionBytes; +import io.sui.models.transactions.TypeTag; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bitcoinj.core.Base58; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.jetbrains.annotations.NotNull; + +/** + * The type Local transaction builder. + * + * @author grapebaba + * @since 2023.1 + */ +public class LocalTransactionBuilder implements TransactionBuilder { + + private static final Struct RESOLVED_ASCII_STR = new Struct(); + private static final Struct RESOLVED_UTF8_STR = new Struct(); + private static final Struct RESOLVED_SUI_ID = new Struct(); + private static final String GAS_COIN_TYPE = "0x2::coin::Coin<0x2::sui::SUI>"; + private static final String SUI_FRAMEWORK_ADDRESS = "0x0000000000000000000000000000000000000002"; + + static { + RESOLVED_ASCII_STR.setAddress("0x1"); + RESOLVED_ASCII_STR.setModule("ascii"); + RESOLVED_ASCII_STR.setName("String"); + + RESOLVED_UTF8_STR.setAddress("0x1"); + RESOLVED_UTF8_STR.setModule("string"); + RESOLVED_UTF8_STR.setName("String"); + + RESOLVED_SUI_ID.setAddress("0x2"); + RESOLVED_SUI_ID.setModule("object"); + RESOLVED_SUI_ID.setName("ID"); + } + + private final QueryClient queryClient; + + /** + * Instantiates a new Local transaction builder. + * + * @param queryClient the query client + */ + public LocalTransactionBuilder(QueryClient queryClient) { + this.queryClient = queryClient; + } + + @Override + public CompletableFuture splitCoin( + String signer, String coin, List splitAmounts, String gas, long gasBudget) { + return null; + } + + @Override + public CompletableFuture splitCoinEqual( + String signer, String coin, long splitCount, String gas, long gasBudget) { + return null; + } + + @Override + public CompletableFuture mergeCoins( + String signer, String primaryCoin, String toMergeCoin, String gas, long gasBudget) { + return null; + } + + // @Override + // public CompletableFuture splitCoin( + // String signer, String coin, List splitAmounts, String gas, long gasBudget) { + // return getCoinStructTag(coin) + // .thenCompose( + // (Function>) + // typeTag -> + // moveCall( + // signer, + // SUI_FRAMEWORK_ADDRESS, + // "pay", + // "split_vec", + // Lists.newArrayList(typeTag), + // Lists.newArrayList(coin, splitAmounts), + // gas, + // gasBudget)); + // } + // + // @Override + // public CompletableFuture splitCoinEqual( + // String signer, String coin, long splitCount, String gas, long gasBudget) { + // return getCoinStructTag(coin) + // .thenCompose( + // (Function>) + // typeTag -> + // moveCall( + // signer, + // SUI_FRAMEWORK_ADDRESS, + // "pay", + // "divide_and_keep", + // Lists.newArrayList(typeTag), + // Lists.newArrayList(coin, splitCount), + // gas, + // gasBudget)); + // } + // + // @Override + // public CompletableFuture mergeCoins( + // String signer, String primaryCoin, String toMergeCoin, String gas, long gasBudget) { + // return getCoinStructTag(toMergeCoin) + // .thenCompose( + // (Function>) + // typeTag -> + // moveCall( + // signer, + // SUI_FRAMEWORK_ADDRESS, + // "pay", + // "join", + // Lists.newArrayList(typeTag), + // Lists.newArrayList(primaryCoin, toMergeCoin), + // gas, + // gasBudget)); + // } + + @Override + @SuppressWarnings("unchecked") + public CompletableFuture pay( + String signer, + List inputCoins, + List recipients, + List amounts, + String gas, + Long gasBudget) { + if (StringUtils.isNotEmpty(gas) && inputCoins.contains(gas)) { + throw new GasInPayCoinsException(); + } + if (inputCoins.isEmpty()) { + throw new EmptyInputCoinsException(); + } + + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + CompletableFuture gasRefFuture = + refGasPriceFuture.thenCompose( + (Function>) + gasPrice -> selectGas(signer, gas, gasBudget, gasPrice, inputCoins)); + + CompletableFuture[] coinRefFutures = + (CompletableFuture[]) + inputCoins.stream() + .map((String id) -> queryClient.getObjectRef(id, new ObjectDataOptions())) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf( + ArrayUtils.addAll(coinRefFutures, gasRefFuture, refGasPriceFuture)) + .thenApply( + unused -> { + final SuiObjectRef objRef = gasRefFuture.join(); + final long refGasPrice = refGasPriceFuture.join(); + List coinRefs = + Arrays.stream(coinRefFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + if (coinRefs.isEmpty()) { + throw new SuiObjectNotFoundException(); + } + + List> coins = + coinRefs.stream() + .map(LocalTransactionBuilder.this::getObjectRef) + .collect(Collectors.toList()); + List recs = + recipients.stream() + .map( + s -> { + List recipientBytes = geAddressBytes(s); + final SuiAddress.Builder recipientAddressBuilder = + new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + return recipientAddressBuilder.build(); + }) + .collect(Collectors.toList()); + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + TransactionData transactionData = + ProgrammableTransactionBuilder.newPay( + senderAddressBuilder.build(), + coins, + recs, + amounts, + getObjectRef(objRef), + gasBudget, + refGasPrice); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(transactionData); + return transactionBytes; + }); + } + + @Override + @SuppressWarnings("unchecked") + public CompletableFuture paySui( + String signer, + List inputCoins, + List recipients, + List amounts, + Long gasBudget) { + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + + if (inputCoins.isEmpty()) { + throw new EmptyInputCoinsException(); + } + CompletableFuture[] coinRefFutures = + (CompletableFuture[]) + inputCoins.stream() + .map((String id) -> queryClient.getObjectRef(id, new ObjectDataOptions())) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(ArrayUtils.addAll(coinRefFutures, refGasPriceFuture)) + .thenApply( + unused -> { + final long refGasPrice = refGasPriceFuture.join(); + List coinRefs = + Arrays.stream(coinRefFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + + List> coins = + coinRefs.stream() + .map(LocalTransactionBuilder.this::getObjectRef) + .collect(Collectors.toList()); + List recs = + recipients.stream() + .map( + s -> { + List recipientBytes = geAddressBytes(s); + final SuiAddress.Builder recipientAddressBuilder = + new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + return recipientAddressBuilder.build(); + }) + .collect(Collectors.toList()); + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + Tuple3 gasRef = coins.remove(0); + + TransactionData transactionData = + ProgrammableTransactionBuilder.newPaySui( + senderAddressBuilder.build(), + coins, + recs, + amounts, + gasRef, + gasBudget, + refGasPrice); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(transactionData); + return transactionBytes; + }); + } + + @Override + @SuppressWarnings("unchecked") + public CompletableFuture payAllSui( + String signer, List inputCoins, String recipient, Long gasBudget) { + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + + if (inputCoins.isEmpty()) { + throw new EmptyInputCoinsException(); + } + CompletableFuture[] coinRefFutures = + (CompletableFuture[]) + inputCoins.stream() + .map((String id) -> queryClient.getObjectRef(id, new ObjectDataOptions())) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(ArrayUtils.addAll(coinRefFutures, refGasPriceFuture)) + .thenApply( + unused -> { + final long refGasPrice = refGasPriceFuture.join(); + List coinRefs = + Arrays.stream(coinRefFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + if (coinRefs.isEmpty()) { + throw new SuiObjectNotFoundException(); + } + List recipientBytes = geAddressBytes(recipient); + final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + + List> coins = + coinRefs.stream() + .map(LocalTransactionBuilder.this::getObjectRef) + .collect(Collectors.toList()); + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + Tuple3 gasRef = coins.remove(0); + + TransactionData transactionData = + ProgrammableTransactionBuilder.newPayAllSui( + senderAddressBuilder.build(), + coins, + recipientAddressBuilder.build(), + gasRef, + gasBudget, + refGasPrice); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(transactionData); + return transactionBytes; + }); + } + + @Override + public CompletableFuture transferSui( + String signer, String coin, Long gasBudget, String recipient, Long amount) { + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + CompletableFuture objRefFuture = + queryClient.getObjectRef(coin, new ObjectDataOptions()); + return CompletableFuture.allOf(refGasPriceFuture, objRefFuture) + .thenApply( + unused -> { + final Long refGasPrice = refGasPriceFuture.join(); + final SuiObjectRef objRef = objRefFuture.join(); + + List recipientBytes = geAddressBytes(recipient); + final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + TransactionData transactionData = + ProgrammableTransactionBuilder.newTransferSui( + recipientAddressBuilder.build(), + senderAddressBuilder.build(), + amount, + getObjectRef(objRef), + gasBudget, + refGasPrice); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(transactionData); + return transactionBytes; + }); + } + + @Override + public CompletableFuture transferObject( + String signer, String suiObject, String recipient, String gas, Long gasBudget) { + CompletableFuture objRefFuture = + queryClient.getObjectRef(suiObject, new ObjectDataOptions()); + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + CompletableFuture gasRefFuture = + refGasPriceFuture.thenCompose( + (Function>) + gasPrice -> + selectGas(signer, gas, gasBudget, gasPrice, Lists.newArrayList(suiObject))); + return CompletableFuture.allOf(refGasPriceFuture, objRefFuture, gasRefFuture) + .thenApply( + unused -> { + final Long refGasPrice = refGasPriceFuture.join(); + final SuiObjectRef objRef = objRefFuture.join(); + final SuiObjectRef gasRef = gasRefFuture.join(); + + List recipientBytes = geAddressBytes(recipient); + final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + programmableTransactionBuilder.transferObject( + recipientAddressBuilder.build(), getObjectRef(objRef)); + ProgrammableTransaction programmableTransaction = + programmableTransactionBuilder.build(); + TransactionKind.ProgrammableTransaction.Builder builder = new Builder(); + builder.value = programmableTransaction; + + final GasData.Builder gasDataBuilder = new GasData.Builder(); + gasDataBuilder.budget = gasBudget; + gasDataBuilder.price = refGasPrice; + gasDataBuilder.payment = Lists.newArrayList(getObjectRef(gasRef)); + gasDataBuilder.owner = senderAddressBuilder.build(); + final TransactionDataV1.Builder transactionDataV1Builder = + new TransactionDataV1.Builder(); + transactionDataV1Builder.kind = builder.build(); + transactionDataV1Builder.sender = senderAddressBuilder.build(); + transactionDataV1Builder.gas_data = gasDataBuilder.build(); + TransactionExpiration.None.Builder expirationBuilder = new None.Builder(); + transactionDataV1Builder.expiration = expirationBuilder.build(); + + final TransactionData.V1.Builder v1Builder = new V1.Builder(); + v1Builder.value = transactionDataV1Builder.build(); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(v1Builder.build()); + return transactionBytes; + }); + } + + @Override + public CompletableFuture batchTransaction( + String signer, + List batchTransactionParams, + String gas, + long gasBudget) { + return null; + } + + @Override + public CompletableFuture moveCall( + String signer, + String packageObjectId, + String module, + String function, + List typeArguments, + List arguments, + String gas, + long gasBudget) { + return null; + } + + // @Override + // @SuppressWarnings("unchecked") + // public CompletableFuture batchTransaction( + // String signer, + // List batchTransactionParams, + // String gas, + // long gasBudget) { + // CompletableFuture[] kindFutures = + // (CompletableFuture[]) + // batchTransactionParams.stream() + // .map( + // rpcTransactionRequestParams -> { + // if (rpcTransactionRequestParams instanceof TransferObjectRequestParams) { + // TransferObjectParams transferObjectParams = + // ((TransferObjectRequestParams) rpcTransactionRequestParams) + // .getTransferObjectRequestParams(); + // return queryClient + // .getObjectRef(transferObjectParams.getObjectId()) + // .thenApply( + // (Function) + // suiObjectRef -> { + // List recipientBytes = + // geAddressBytes(transferObjectParams.getRecipient()); + // final SuiAddress.Builder recipientAddressBuilder = + // new SuiAddress.Builder(); + // recipientAddressBuilder.value = recipientBytes; + // + // final TransferObject.Builder transferObjectBuilder = + // new TransferObject.Builder(); + // transferObjectBuilder.recipient = + // recipientAddressBuilder.build(); + // transferObjectBuilder.object_ref = + // getObjectRef(suiObjectRef); + // + // final SingleTransactionKind.TransferObject.Builder + // transferObjectKindBuilder = + // new SingleTransactionKind.TransferObject.Builder(); + // transferObjectKindBuilder.value = + // transferObjectBuilder.build(); + // + // return transferObjectKindBuilder.build(); + // }); + // } + // + // if (rpcTransactionRequestParams instanceof MoveCallRequestParams) { + // MoveCallParams moveCallParams = + // ((MoveCallRequestParams) rpcTransactionRequestParams) + // .getMoveCallRequestParams(); + // + // List bcsTypeArguments = + // moveCallParams.getTypeArguments().stream() + // .map(LocalTransactionBuilder.this::toBcsTypeTag) + // .collect(Collectors.toList()); + // + // return extractNormalizedFunctionParams( + // moveCallParams.getPackageObjectId(), + // moveCallParams.getModule(), + // moveCallParams.getFunction()) + // .thenCompose( + // (Function< + // List, + // CompletableFuture>) + // moveNormalizedTypes -> { + // if (moveNormalizedTypes.size() + // != moveCallParams.getArguments().size()) { + // throw new MoveCallArgSizeNotMatchException( + // moveNormalizedTypes.size(), + // moveCallParams.getArguments().size()); + // } + // CompletableFuture[] callArgFutures = + // (CompletableFuture[]) + // Streams.zip( + // moveNormalizedTypes.stream(), + // moveCallParams.getArguments().stream(), + // (BiFunction< + // MoveNormalizedType, + // java.lang.Object, + // CompletableFuture>) + // LocalTransactionBuilder.this + // ::toBcsCallArg) + // .toArray(CompletableFuture[]::new); + // return CompletableFuture.allOf(callArgFutures) + // .thenCompose( + // (Function< + // Void, + // CompletableFuture>) + // unused -> { + // List callArgs = + // Arrays.stream(callArgFutures) + // .map(CompletableFuture::join) + // .collect(Collectors.toList()); + // List excludeObjects = + // callArgs.stream() + // .flatMap( + // (Function< + // CallArg, Stream>) + // callArg -> { + // if (callArg + // instanceof ObjVec) { + // return ((ObjVec) + // callArg) + // .value.stream(); + // } else if (callArg + // instanceof Object) { + // return Stream.of( + // ((Object) callArg) + // .value); + // } + // + // return Stream.empty(); + // }) + // .map( + // (Function< + // ObjectArg, + // Optional>) + // objectArg -> { + // if (objectArg + // instanceof + // SharedObject) { + // return Optional.of( + // toAddress( + // ((SharedObject) + // objectArg) + // .id + // .value + // .value)); + // } + // + // if (objectArg + // instanceof + // ImmOrOwnedObject) { + // return Optional.of( + // toAddress( + // + // ((ImmOrOwnedObject) + // objectArg) + // .value + // .field0 + // .value + // .value)); + // } + // + // return Optional.empty(); + // }) + // .filter(Optional::isPresent) + // .map(Optional::get) + // .collect(Collectors.toList()); + // + // CompletableFuture refGasPriceFuture = + // queryClient.getReferenceGasPrice(); + // CompletableFuture gasRefFuture + // = + // refGasPriceFuture.thenCompose( + // (Function< + // Long, + // CompletableFuture< + // SuiObjectRef>>) + // gasPrice -> + // selectGas( + // signer, + // gas, + // gasBudget, + // gasPrice, + // excludeObjects)); + // return CompletableFuture.allOf( + // gasRefFuture, refGasPriceFuture) + // .thenApply( + // unused1 -> { + // Identifier.Builder moduleBuilder = + // new Identifier.Builder(); + // moduleBuilder.value = + // moveCallParams.getModule(); + // Identifier.Builder functionBuilder + // = + // new Identifier.Builder(); + // functionBuilder.value = + // moveCallParams.getFunction(); + // + // AccountAddress.Builder + // objectAddressBuilder = + // new AccountAddress.Builder(); + // objectAddressBuilder.value = + // geAddressBytes( + // moveCallParams + // + // .getPackageObjectId()); + // ObjectID.Builder objectIdBuilder = + // new ObjectID.Builder(); + // objectIdBuilder.value = + // objectAddressBuilder.build(); + // final MoveCall.Builder + // moveCallBuilder = + // new MoveCall.Builder(); + // moveCallBuilder.type_arguments = + // bcsTypeArguments; + // moveCallBuilder.arguments = + // callArgs; + // moveCallBuilder.Package = + // objectIdBuilder.build(); + // moveCallBuilder.module = + // moduleBuilder.build(); + // moveCallBuilder.function = + // functionBuilder.build(); + // + // final Call.Builder + // moveCallKindBuilder = + // new Call.Builder(); + // moveCallKindBuilder.value = + // moveCallBuilder.build(); + // + // return + // moveCallKindBuilder.build(); + // }); + // }); + // }); + // } + // throw new NotSupportedTransactionKindException(); + // }) + // .toArray(CompletableFuture[]::new); + // return CompletableFuture.allOf(kindFutures) + // .thenCompose( + // (Function>) + // unused -> { + // final List kinds = + // Arrays.stream(kindFutures) + // .map(CompletableFuture::join) + // .collect(Collectors.toList()); + // + // List excludeObjects = + // kinds.stream() + // .map( + // singleTransactionKind -> { + // if (singleTransactionKind + // instanceof SingleTransactionKind.TransferObject) { + // + // return Lists.newArrayList( + // toAddress( + // ((SingleTransactionKind.TransferObject) + // singleTransactionKind) + // .value + // .object_ref + // .field0 + // .value + // .value)); + // } + // + // if (singleTransactionKind instanceof Call) { + // List callArgs = + // ((Call) singleTransactionKind).value.arguments; + // + // return callArgs.stream() + // .flatMap( + // (Function>) + // callArg -> { + // if (callArg instanceof ObjVec) { + // return ((ObjVec) callArg).value.stream(); + // } else if (callArg instanceof Object) { + // return Stream.of(((Object) callArg).value); + // } + // + // return Stream.empty(); + // }) + // .map( + // (Function>) + // objectArg -> { + // if (objectArg instanceof SharedObject) { + // return Optional.of( + // toAddress( + // ((SharedObject) objectArg) + // .id + // .value + // .value)); + // } + // + // if (objectArg instanceof ImmOrOwnedObject) { + // return Optional.of( + // toAddress( + // ((ImmOrOwnedObject) objectArg) + // .value + // .field0 + // .value + // .value)); + // } + // + // return Optional.empty(); + // }) + // .filter(Optional::isPresent) + // .map(Optional::get) + // .collect(Collectors.toList()); + // } + // + // throw new NotSupportedTransactionKindException(); + // }) + // .flatMap(Collection::stream) + // .collect(Collectors.toList()); + // + // CompletableFuture refGasPriceFuture = + // queryClient.getReferenceGasPrice(); + // CompletableFuture gasRefFuture = + // refGasPriceFuture.thenCompose( + // (Function>) + // gasPrice -> + // selectGas(signer, gas, gasBudget, gasPrice, excludeObjects)); + // return CompletableFuture.allOf(gasRefFuture, refGasPriceFuture) + // .thenApply( + // unused12 -> { + // final Batch.Builder batchBuilder = new Batch.Builder(); + // batchBuilder.value = kinds; + // + // List senderBytes = geAddressBytes(signer); + // final SuiAddress.Builder senderAddressBuilder = + // new SuiAddress.Builder(); + // senderAddressBuilder.value = senderBytes; + // + // final Long refGasPrice = refGasPriceFuture.join(); + // final SuiObjectRef gasRef = gasRefFuture.join(); + // final GasData.Builder gasDataBuilder = new GasData.Builder(); + // gasDataBuilder.budget = gasBudget; + // gasDataBuilder.price = refGasPrice; + // gasDataBuilder.payment = Lists.newArrayList(getObjectRef(gasRef)); + // gasDataBuilder.owner = senderAddressBuilder.build(); + // final TransactionDataV1.Builder transactionDataV1Builder = + // new TransactionDataV1.Builder(); + // transactionDataV1Builder.kind = batchBuilder.build(); + // transactionDataV1Builder.sender = senderAddressBuilder.build(); + // transactionDataV1Builder.gas_data = gasDataBuilder.build(); + // TransactionExpiration.None.Builder expirationBuilder = + // new None.Builder(); + // transactionDataV1Builder.expiration = expirationBuilder.build(); + // + // final TransactionData.V1.Builder v1Builder = new V1.Builder(); + // v1Builder.value = transactionDataV1Builder.build(); + // + // final TransactionBytes transactionBytes = new TransactionBytes(); + // transactionBytes.setLocalTxBytes(v1Builder.build()); + // transactionBytes.setGas(gasRef); + // return transactionBytes; + // }); + // }); + // } + + @Override + // public CompletableFuture moveCall( + // String signer, + // String packageObjectId, + // String module, + // String function, + // List typeArguments, + // List arguments, + // String gas, + // long gasBudget) { + // List bcsTypeArguments = + // typeArguments.stream().map(this::toBcsTypeTag).collect(Collectors.toList()); + // + // return extractNormalizedFunctionParams(packageObjectId, module, function) + // .thenCompose( + // (Function, CompletableFuture>) + // moveNormalizedTypes -> { + // if (moveNormalizedTypes.size() != arguments.size()) { + // throw new MoveCallArgSizeNotMatchException( + // moveNormalizedTypes.size(), arguments.size()); + // } + // CompletableFuture[] callArgFutures = + // (CompletableFuture[]) + // Streams.zip( + // moveNormalizedTypes.stream(), + // arguments.stream(), + // (BiFunction< + // MoveNormalizedType, + // Object, + // + // CompletableFuture>) + // this::toBcsCallArg) + // .toArray(CompletableFuture[]::new); + // return CompletableFuture.allOf(callArgFutures) + // .thenCompose( + // (Function>) + // unused -> { + // List callArgs = + // Arrays.stream(callArgFutures) + // .map(CompletableFuture::join) + // .collect(Collectors.toList()); + // List excludeObjects = + // callArgs.stream() + // .flatMap( + // (Function>) + // callArg -> { + // if (callArg instanceof ObjVec) { + // return ((ObjVec) callArg).value.stream(); + // } else if (callArg instanceof Object) { + // return Stream.of(((Object) callArg).value); + // } + // + // return Stream.empty(); + // }) + // .map( + // (Function>) + // objectArg -> { + // if (objectArg instanceof SharedObject) { + // return Optional.of( + // toAddress( + // ((SharedObject) objectArg) + // .id + // .value + // .value)); + // } + // + // if (objectArg instanceof ImmOrOwnedObject) { + // return Optional.of( + // toAddress( + // ((ImmOrOwnedObject) objectArg) + // .value + // .field0 + // .value + // .value)); + // } + // + // return Optional.empty(); + // }) + // .filter(Optional::isPresent) + // .map(Optional::get) + // .collect(Collectors.toList()); + // + // CompletableFuture refGasPriceFuture = + // queryClient.getReferenceGasPrice(); + // CompletableFuture gasRefFuture = + // refGasPriceFuture.thenCompose( + // (Function>) + // gasPrice -> + // selectGas( + // signer, + // gas, + // gasBudget, + // gasPrice, + // excludeObjects)); + // + // return CompletableFuture.allOf(gasRefFuture, refGasPriceFuture) + // .thenApply( + // unused1 -> { + // List senderBytes = geAddressBytes(signer); + // final SuiAddress.Builder senderAddressBuilder = + // new SuiAddress.Builder(); + // senderAddressBuilder.value = senderBytes; + // + // Identifier.Builder moduleBuilder = + // new Identifier.Builder(); + // moduleBuilder.value = module; + // Identifier.Builder functionBuilder = + // new Identifier.Builder(); + // functionBuilder.value = function; + // + // AccountAddress.Builder objectAddressBuilder = + // new AccountAddress.Builder(); + // objectAddressBuilder.value = + // geAddressBytes(packageObjectId); + // ObjectID.Builder objectIdBuilder = new + // ObjectID.Builder(); + // objectIdBuilder.value = objectAddressBuilder.build(); + // final MoveCall.Builder moveCallBuilder = + // new MoveCall.Builder(); + // moveCallBuilder.type_arguments = bcsTypeArguments; + // moveCallBuilder.arguments = callArgs; + // moveCallBuilder.Package = objectIdBuilder.build(); + // moveCallBuilder.module = moduleBuilder.build(); + // moveCallBuilder.function = functionBuilder.build(); + // + // final Call.Builder moveCallKindBuilder = + // new Call.Builder(); + // moveCallKindBuilder.value = moveCallBuilder.build(); + // + // final Single.Builder singleKindBuilder = + // new Single.Builder(); + // singleKindBuilder.value = moveCallKindBuilder.build(); + // + // long refGasPrice = refGasPriceFuture.join(); + // SuiObjectRef gasRef = gasRefFuture.join(); + // final GasData.Builder gasDataBuilder = + // new GasData.Builder(); + // gasDataBuilder.budget = gasBudget; + // gasDataBuilder.price = refGasPrice; + // gasDataBuilder.payment = + // Lists.newArrayList(getObjectRef(gasRef)); + // gasDataBuilder.owner = senderAddressBuilder.build(); + // final TransactionDataV1.Builder + // transactionDataV1Builder = + // new TransactionDataV1.Builder(); + // transactionDataV1Builder.kind = + // singleKindBuilder.build(); + // transactionDataV1Builder.sender = + // senderAddressBuilder.build(); + // transactionDataV1Builder.gas_data = + // gasDataBuilder.build(); + // TransactionExpiration.None.Builder expirationBuilder = + // new None.Builder(); + // transactionDataV1Builder.expiration = + // expirationBuilder.build(); + // + // final TransactionData.V1.Builder v1Builder = + // new V1.Builder(); + // v1Builder.value = transactionDataV1Builder.build(); + // + // final TransactionBytes transactionBytes = + // new TransactionBytes(); + // transactionBytes.setLocalTxBytes(v1Builder.build()); + // transactionBytes.setGas(gasRef); + // return transactionBytes; + // }); + // }); + // }); + // } + + @SuppressWarnings("unchecked") + public CompletableFuture publish( + String signer, + List compiledModules, + List depIds, + String gas, + Long gasBudget) { + CompletableFuture refGasPriceFuture = queryClient.getReferenceGasPrice(); + CompletableFuture gasRefFuture = + refGasPriceFuture.thenCompose( + (Function>) + gasPrice -> selectGas(signer, gas, gasBudget, gasPrice, Lists.newArrayList())); + + return CompletableFuture.allOf(refGasPriceFuture, gasRefFuture) + .thenApply( + unused -> { + final Long refGasPrice = refGasPriceFuture.join(); + final SuiObjectRef objRef = gasRefFuture.join(); + + List depIdObjects = + depIds != null + ? depIds.stream() + .map( + objectId -> { + AccountAddress.Builder accountAddressBuilder = + new AccountAddress.Builder(); + accountAddressBuilder.value = geAddressBytes(objectId); + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = accountAddressBuilder.build(); + return objectIdBuilder.build(); + }) + .collect(Collectors.toList()) + : Lists.newArrayList(); + + List senderBytes = geAddressBytes(signer); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + + List> modules = + compiledModules.stream() + .map(s -> Arrays.asList(ArrayUtils.toObject(Base64.decode(s)))) + .collect(Collectors.toList()); + TransactionData transactionData = + ProgrammableTransactionBuilder.newModule( + senderAddressBuilder.build(), + Lists.newArrayList(getObjectRef(objRef)), + modules, + depIdObjects, + gasBudget, + refGasPrice); + + final TransactionBytes transactionBytes = new TransactionBytes(); + transactionBytes.setLocalTxBytes(transactionData); + return transactionBytes; + }); + } + + // private CompletableFuture getCoinStructTag(String objectId) { + // return queryClient + // .getObject(objectId) + // .thenApply( + // objectResponse -> { + // String type = null; + // if (objectResponse.getDetails() instanceof SuiObjectInfo) { + // type = ((SuiObjectInfo) objectResponse.getDetails()).getType(); + // } + // + // if (objectResponse.getDetails() instanceof SuiObject) { + // if (((SuiObject) objectResponse.getDetails()).getData() instanceof MoveObject) { + // type = + // ((MoveObject) ((SuiObject) + // objectResponse.getDetails()).getData()).getType(); + // } + // } + // + // if (null == type) { + // throw new SuiObjectNotFoundException(); + // } + // + // if (!GAS_COIN_TYPE.equals(type)) { + // throw new ObjectIsNotCoinException(objectId); + // } + // + // io.sui.models.transactions.StructTag structTag = + // new io.sui.models.transactions.StructTag(); + // structTag.setAddress(SUI_FRAMEWORK_ADDRESS); + // structTag.setModule("sui"); + // structTag.setName("SUI"); + // structTag.setTypeParams(Lists.newArrayList()); + // + // StructType structType = new StructType(); + // structType.setStructTag(structTag); + // return structType; + // }); + // } + + @SuppressWarnings("unchecked") + private CompletableFuture selectGas( + String signer, String inputGas, Long budget, Long gasPrice, List excludeObjects) { + if (StringUtils.isNotEmpty(inputGas)) { + return queryClient.getObjectRef(inputGas, new ObjectDataOptions()); + } else { + final ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + ObjectDataOptions objectDataOptions = new ObjectDataOptions(); + objectDataOptions.setShowPreviousTransaction(true); + objectDataOptions.setShowOwner(true); + objectDataOptions.setShowContent(true); + objectDataOptions.setShowStorageRebate(true); + objectDataOptions.setShowBcs(true); + objectResponseQuery.setOptions(objectDataOptions); + return queryClient + .getObjectsOwnedByAddress(signer, objectResponseQuery, null, null, null) + .thenCompose( + (Function>) + paginatedObjectsResponse -> { + CompletableFuture>[] gases = + (CompletableFuture>[]) + paginatedObjectsResponse.getData().stream() + .map( + objectResponse -> { + if (objectResponse.getError() == null + && objectResponse + .getData() + .getType() + .equals(GAS_COIN_TYPE)) { + GasCoin gasCoin; + try { + gasCoin = + GasCoin.bcsDeserialize( + Base64.decode( + ((SuiRawData.MoveObject) + objectResponse.getData().getBcs()) + .getBcsBytes())); + } catch (DeserializationError e) { + throw new BcsSerializationException(e); + } + final long requiredGasAmount = + BigInteger.valueOf(budget) + .multiply(BigInteger.valueOf(gasPrice)) + .longValue(); + + if (!excludeObjects.contains( + objectResponse.getData().getObjectId()) + && gasCoin.value.balance.value >= requiredGasAmount) { + return CompletableFuture.completedFuture( + Optional.of(objectResponse.getData().getRef())); + } + + return CompletableFuture.completedFuture(Optional.empty()); + } + return CompletableFuture + .>completedFuture( + Optional.empty()); + }) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(gases) + .thenApply( + unused -> { + Optional> selected = + Arrays.stream(gases) + .map(CompletableFuture::join) + .filter(Optional::isPresent) + .findFirst(); + + if (!selected.isPresent()) { + throw new GasNotFoundException(); + } + + return selected.get().get(); + }); + }); + } + } + + private CompletableFuture> extractNormalizedFunctionParams( + String packageObjectId, String module, String function) { + CompletableFuture normalizedFunction = + this.queryClient.getNormalizedMoveFunction(packageObjectId, module, function); + return normalizedFunction.thenCompose( + (Function>>) + moveNormalizedFunction -> { + final boolean hasTxContext = + moveNormalizedFunction.getParameters().size() > 0 + && isTxContext(Iterables.getLast(moveNormalizedFunction.getParameters())); + return CompletableFuture.completedFuture( + hasTxContext + ? moveNormalizedFunction + .getParameters() + .subList(0, moveNormalizedFunction.getParameters().size() - 1) + : moveNormalizedFunction.getParameters()); + }); + } + + private Optional toPureMoveValue( + MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { + final MoveValue moveValue; + if (moveNormalizedType instanceof MoveNormalizedType.TypeMoveNormalizedType) { + MoveNormalizedType.TypeMoveNormalizedType argType = + (MoveNormalizedType.TypeMoveNormalizedType) moveNormalizedType; + switch (argType) { + case U8: + checkArgType(moveNormalizedType, argVal, Byte.class); + MoveValue.U8.Builder u8Builder = new MoveValue.U8.Builder(); + u8Builder.value = (Byte) argVal; + moveValue = u8Builder.build(); + break; + case U16: + checkArgType(moveNormalizedType, argVal, Short.class); + + MoveValue.U16.Builder u16Builder = new MoveValue.U16.Builder(); + u16Builder.value = (Short) argVal; + moveValue = u16Builder.build(); + break; + case U32: + checkArgType(moveNormalizedType, argVal, Integer.class); + + MoveValue.U32.Builder u32Builder = new MoveValue.U32.Builder(); + u32Builder.value = (Integer) argVal; + moveValue = u32Builder.build(); + break; + case U64: + checkArgType(moveNormalizedType, argVal, Long.class); + + MoveValue.U64.Builder u64Builder = new MoveValue.U64.Builder(); + u64Builder.value = (Long) argVal; + moveValue = u64Builder.build(); + break; + case U128: + checkArgType(moveNormalizedType, argVal, BigInteger.class); + + MoveValue.U128.Builder u128Builder = new MoveValue.U128.Builder(); + u128Builder.value = (BigInteger) argVal; + moveValue = u128Builder.build(); + break; + case U256: + checkArgType(moveNormalizedType, argVal, byte[].class); + + MoveValue.U256.Builder u256Builder = new MoveValue.U256.Builder(); + u256Builder.value = Arrays.asList(ArrayUtils.toObject((byte[]) argVal)); + moveValue = u256Builder.build(); + break; + case Bool: + checkArgType(moveNormalizedType, argVal, Boolean.class); + + MoveValue.Bool.Builder boolBuilder = new Bool.Builder(); + boolBuilder.value = (Boolean) argVal; + moveValue = boolBuilder.build(); + break; + case Address: + checkArgType(moveNormalizedType, argVal, String.class); + + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = geAddressBytes((String) argVal); + MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); + addressValueBuilder.value = addressBuilder.build(); + moveValue = addressValueBuilder.build(); + break; + default: + throw new NotSupportedMoveNormalizedTypeException(); + } + + return Optional.of(moveValue); + } + + if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + final Struct argStruct = + ((MoveNormalizedType.MoveNormalizedStructType) moveNormalizedType).getStruct(); + if (argStruct.equals(RESOLVED_ASCII_STR)) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream( + ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.US_ASCII))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } else if (argStruct.equals(RESOLVED_UTF8_STR)) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } else if (argStruct.equals(RESOLVED_SUI_ID)) { + checkArgType(moveNormalizedType, argVal, String.class); + + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = geAddressBytes((String) argVal); + MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); + addressValueBuilder.value = addressBuilder.build(); + moveValue = addressValueBuilder.build(); + + return Optional.of(moveValue); + } + } + + if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { + if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) moveNormalizedType).getVector() + == TypeMoveNormalizedType.U8) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } + + if (!(argVal instanceof List)) { + throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + } + + List objects = (List) argVal; + List pureMoveValues = + objects.stream() + .map( + object -> + toPureMoveValue( + ((MoveNormalizedType.VectorReferenceMoveNormalizedType) + moveNormalizedType) + .getVector(), + object)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + if (pureMoveValues.isEmpty()) { + // ObjVec TYPE will be handled later + return Optional.empty(); + } + + MoveValue.Vector.Builder moveValueVectorBuilder = new Vector.Builder(); + moveValueVectorBuilder.value = pureMoveValues; + + return Optional.of(moveValueVectorBuilder.build()); + } + + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + // private CompletableFuture toBcsCallArg( + // MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { + // final Optional pureMoveValue = toPureMoveValue(moveNormalizedType, argVal); + // if (pureMoveValue.isPresent()) { + // final CallArg.Pure.Builder pureBuilder = getPureBuilder(pureMoveValue.get()); + // return CompletableFuture.completedFuture(pureBuilder.build()); + // } + // + // if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { + // + // if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) + // moveNormalizedType).getVector() + // instanceof MoveNormalizedType.MoveNormalizedStructType) { + // checkArgType(moveNormalizedType, argVal, List.class); + // + // CompletableFuture[] objectArgFutures = + // (CompletableFuture[]) + // Arrays.stream((String[]) argVal) + // .map(this::newObjectArg) + // .toArray(CompletableFuture[]::new); + // + // return CompletableFuture.allOf(objectArgFutures) + // .thenApply( + // unused -> { + // final CallArg.ObjVec.Builder objVecBuilder = new ObjVec.Builder(); + // objVecBuilder.value = + // Arrays.stream(objectArgFutures) + // .map(CompletableFuture::join) + // .collect(Collectors.toList()); + // return objVecBuilder.build(); + // }); + // } + // } + // + // final Optional structOptional = + // extractStruct(moveNormalizedType).map(MoveNormalizedStructType::getStruct); + // + // if (structOptional.isPresent() + // || (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedTypeParameterType)) { + // checkArgType(moveNormalizedType, argVal, String.class); + // + // return newObjectArg((String) argVal) + // .thenApply( + // objectArg -> { + // final Object.Builder objectBuilder = new Object.Builder(); + // objectBuilder.value = objectArg; + // return objectBuilder.build(); + // }); + // } + // + // throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + // } + // + // private CompletableFuture newObjectArg(String objectId) { + // return queryClient + // .getObject(objectId) + // .thenApply( + // objectResponse -> { + // if (Exists != objectResponse.getStatus()) { + // throw new SuiObjectNotFoundException(); + // } + // final SuiObjectOwner owner = ((SuiObject) objectResponse.getDetails()).getOwner(); + // if (owner instanceof SuiObjectOwner.SharedOwner) { + // AccountAddress.Builder accountAddressBuilder = new AccountAddress.Builder(); + // accountAddressBuilder.value = geAddressBytes(objectId); + // ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + // objectIdBuilder.value = accountAddressBuilder.build(); + // SequenceNumber.Builder seqBuilder = new SequenceNumber.Builder(); + // seqBuilder.value = + // ((SuiObjectOwner.SharedOwner) + // owner).getShared().getInitial_shared_version(); + // SharedObject.Builder sharedObjectBuilder = new SharedObject.Builder(); + // sharedObjectBuilder.id = objectIdBuilder.build(); + // sharedObjectBuilder.initial_shared_version = seqBuilder.build(); + // sharedObjectBuilder.mutable = true; + // return sharedObjectBuilder.build(); + // } + // + // ImmOrOwnedObject.Builder immOrOwnedObjectBuilder = new ImmOrOwnedObject.Builder(); + // immOrOwnedObjectBuilder.value = getObjectRef(objectResponse.getObjectRef()); + // return immOrOwnedObjectBuilder.build(); + // }); + // } + + private void checkArgType( + MoveNormalizedType moveNormalizedType, java.lang.Object argVal, Class expectedArgClass) { + if (!expectedArgClass.isInstance(argVal)) { + throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + } + } + + @NotNull private Pure.Builder getPureBuilder(MoveValue moveValue) { + final Pure.Builder pureBuilder = new Pure.Builder(); + try { + pureBuilder.value = Arrays.asList(ArrayUtils.toObject(moveValue.bcsSerialize())); + } catch (SerializationError e) { + throw new BcsSerializationException(e); + } + return pureBuilder; + } + + private boolean isTxContext(MoveNormalizedType moveNormalizedType) { + if (moveNormalizedType instanceof MoveNormalizedType.MutableReferenceMoveNormalizedType) { + final MoveNormalizedType mutableRefMoveNormalizedType = + ((MoveNormalizedType.MutableReferenceMoveNormalizedType) moveNormalizedType) + .getMutableReference(); + if (mutableRefMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + final Struct struct = ((MoveNormalizedStructType) mutableRefMoveNormalizedType).getStruct(); + return struct.getAddress().equals("0x2") + && struct.getModule().equals("tx_context") + && struct.getName().equals("TxContext"); + } else { + return false; + } + } else { + return false; + } + } + + private Optional extractStruct(MoveNormalizedType moveNormalizedType) { + if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) moveNormalizedType); + } else if (moveNormalizedType instanceof MoveNormalizedType.ReferenceMoveNormalizedType) { + final MoveNormalizedType refMoveNormalizedType = + ((MoveNormalizedType.ReferenceMoveNormalizedType) moveNormalizedType).getReference(); + if (refMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) refMoveNormalizedType); + } + } else if (moveNormalizedType + instanceof MoveNormalizedType.MutableReferenceMoveNormalizedType) { + final MoveNormalizedType mutableRefMoveNormalizedType = + ((MoveNormalizedType.MutableReferenceMoveNormalizedType) moveNormalizedType) + .getMutableReference(); + if (mutableRefMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) mutableRefMoveNormalizedType); + } + } + + return Optional.empty(); + } + + @NotNull private List geAddressBytes(String address) { + return Arrays.asList(ArrayUtils.toObject(Hex.decode(StringUtils.removeStart(address, "0x")))); + } + + private String toAddress(List addressBytes) { + return StringUtils.prependIfMissing( + Hex.toHexString(ArrayUtils.toPrimitive(addressBytes.toArray(new Byte[0]))), "0x"); + } + + private Tuple3 getObjectRef(SuiObjectRef objRef) { + AccountAddress.Builder coinAddressBuilder = new AccountAddress.Builder(); + coinAddressBuilder.value = geAddressBytes(objRef.getObjectId()); + + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = coinAddressBuilder.build(); + + SequenceNumber.Builder sequenceNumberBuilder = new SequenceNumber.Builder(); + sequenceNumberBuilder.value = objRef.getVersion(); + Digest.Builder digestBuilder = new Digest.Builder(); + digestBuilder.value = Bytes.valueOf(Base58.decode(objRef.getDigest())); + ObjectDigest.Builder objectDigestBuilder = new ObjectDigest.Builder(); + objectDigestBuilder.value = digestBuilder.build(); + + return new Tuple3<>( + objectIdBuilder.build(), sequenceNumberBuilder.build(), objectDigestBuilder.build()); + } + + private io.sui.bcsgen.TypeTag toBcsTypeTag(TypeTag typeTag) { + if (typeTag instanceof TypeTag.SimpleType) { + switch ((TypeTag.SimpleType) typeTag) { + case u8: + io.sui.bcsgen.TypeTag.u8.Builder u8builder = new u8.Builder(); + return u8builder.build(); + case u16: + io.sui.bcsgen.TypeTag.u16.Builder u16builder = new u16.Builder(); + return u16builder.build(); + case u32: + io.sui.bcsgen.TypeTag.u32.Builder u32builder = new u32.Builder(); + return u32builder.build(); + case u64: + io.sui.bcsgen.TypeTag.u64.Builder u64builder = new u64.Builder(); + return u64builder.build(); + case bool: + io.sui.bcsgen.TypeTag.bool.Builder boolBuilder = new bool.Builder(); + return boolBuilder.build(); + case u128: + io.sui.bcsgen.TypeTag.u128.Builder u128builder = new u128.Builder(); + return u128builder.build(); + case u256: + io.sui.bcsgen.TypeTag.u256.Builder u256builder = new u256.Builder(); + return u256builder.build(); + case signer: + io.sui.bcsgen.TypeTag.signer.Builder signerBuilder = + new io.sui.bcsgen.TypeTag.signer.Builder(); + return signerBuilder.build(); + case address: + io.sui.bcsgen.TypeTag.address.Builder addressBuilder = + new io.sui.bcsgen.TypeTag.address.Builder(); + return addressBuilder.build(); + default: + throw new NotSupportedTypeTagException(); + } + } else if (typeTag instanceof TypeTag.VectorType) { + io.sui.bcsgen.TypeTag.vector.Builder vectorBuilder = + new io.sui.bcsgen.TypeTag.vector.Builder(); + vectorBuilder.value = toBcsTypeTag(((TypeTag.VectorType) typeTag).getTypeTag()); + return vectorBuilder.build(); + } else { + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = + geAddressBytes(((TypeTag.StructType) typeTag).getStructTag().getAddress()); + Identifier.Builder moduleBuilder = new Identifier.Builder(); + moduleBuilder.value = ((TypeTag.StructType) typeTag).getStructTag().getModule(); + Identifier.Builder nameBuilder = new Identifier.Builder(); + nameBuilder.value = ((TypeTag.StructType) typeTag).getStructTag().getName(); + + StructTag.Builder structTagBuilder = new StructTag.Builder(); + structTagBuilder.address = addressBuilder.build(); + structTagBuilder.module = moduleBuilder.build(); + structTagBuilder.name = nameBuilder.build(); + structTagBuilder.type_args = + ((TypeTag.StructType) typeTag) + .getStructTag().getTypeParams().stream() + .map(this::toBcsTypeTag) + .collect(Collectors.toList()); + io.sui.bcsgen.TypeTag.struct.Builder structBuilder = + new io.sui.bcsgen.TypeTag.struct.Builder(); + structBuilder.value = structTagBuilder.build(); + return structBuilder.build(); + } + } +} diff --git a/src/main/java/io/sui/clients/MismatchedObjectArgumentException.java b/src/main/java/io/sui/clients/MismatchedObjectArgumentException.java index 4ceb7cd..dc1ad51 100644 --- a/src/main/java/io/sui/clients/MismatchedObjectArgumentException.java +++ b/src/main/java/io/sui/clients/MismatchedObjectArgumentException.java @@ -1,7 +1,44 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/1 - * Time: 11:01 - */public class MismatchedObjectArgumentException { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + + +import io.sui.bcsgen.ObjectArg; +import io.sui.bcsgen.ObjectID; + +/** + * The type Mismatched object argument exception. + * + * @author grapebaba + * @since 2023.04 + */ +public class MismatchedObjectArgumentException extends RuntimeException { + + /** + * Instantiates a new Mismatched object argument exception. + * + * @param id the id + * @param old the old + * @param objectArg the object arg + */ + public MismatchedObjectArgumentException(ObjectID id, ObjectArg old, ObjectArg objectArg) { + super( + String.format( + "Mismatched Object argument kind for object %s. %s is not compatible with %s", + id, old, objectArg)); + } } diff --git a/src/main/java/io/sui/clients/NotSupportedArgumentException.java b/src/main/java/io/sui/clients/NotSupportedArgumentException.java index 369eb4b..e29067e 100644 --- a/src/main/java/io/sui/clients/NotSupportedArgumentException.java +++ b/src/main/java/io/sui/clients/NotSupportedArgumentException.java @@ -16,11 +16,15 @@ package io.sui.clients; -/** The type No supported move normalized type exception. */ -public class NotSupportedMoveNormalizedTypeException extends RuntimeException { +/** The type Not supported argument exception. */ +public class NotSupportedArgumentException extends RuntimeException { - /** Instantiates a new No supported move normalized type exception. */ - public NotSupportedMoveNormalizedTypeException() { - super("not supported MOVE normalized type tag."); + /** + * Instantiates a new Not supported argument exception. + * + * @param clazz the clazz + */ + public NotSupportedArgumentException(Class clazz) { + super(String.format("not supported Class %s", clazz.getCanonicalName())); } } diff --git a/src/main/java/io/sui/clients/OkhttpFaucetClient.java b/src/main/java/io/sui/clients/OkhttpFaucetClient.java index 748b88f..8c47688 100644 --- a/src/main/java/io/sui/clients/OkhttpFaucetClient.java +++ b/src/main/java/io/sui/clients/OkhttpFaucetClient.java @@ -1,11 +1,28 @@ +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + package io.sui.clients; import io.sui.jsonrpc.JsonHandler; -import io.sui.jsonrpc.JsonRpc20Response; import io.sui.models.FaucetResponse; +import io.sui.models.SuiApiException; import java.io.IOException; import java.time.Duration; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import okhttp3.Call; import okhttp3.Callback; @@ -15,8 +32,15 @@ import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; +import org.jetbrains.annotations.NotNull; -public class FaucetClient { +/** + * The type Okhttp faucet client. + * + * @author grapebaba + * @since 2023.04 + */ +public class OkhttpFaucetClient implements FaucetClient { private final OkHttpClient httpClient; @@ -24,8 +48,13 @@ public class FaucetClient { private final JsonHandler jsonHandler; - public FaucetClient(OkHttpClient httpClient, String baseUrl, - JsonHandler jsonHandler) { + /** + * Instantiates a new Okhttp faucet client. + * + * @param baseUrl the base url + * @param jsonHandler the json handler + */ + public OkhttpFaucetClient(String baseUrl, JsonHandler jsonHandler) { this.jsonHandler = jsonHandler; this.httpClient = new OkHttpClient() @@ -37,15 +66,18 @@ public FaucetClient(OkHttpClient httpClient, String baseUrl, this.baseUrl = baseUrl; } + /** + * request faucet. + * + * @param address the address. + * @return FaucetResponse. + */ public CompletableFuture requestSuiFromFaucet(String address) { final CompletableFuture future = new CompletableFuture<>(); final Request okhttpRequest; try { - final String requestBodyJsonStr = String.format("{\n" - + " FixedAmountRequest: {\n" - + " %s,\n" - + " },\n" - + " }", address); + final String requestBodyJsonStr = + String.format("{\"FixedAmountRequest\": {\"recipient\": \"%s\"}}", address); final RequestBody requestBody = RequestBody.create(requestBodyJsonStr, MediaType.get("application/json; charset=utf-8")); okhttpRequest = @@ -68,23 +100,17 @@ public void onFailure(Call call, IOException e) { } @Override - public void onResponse(Call call, Response response) { + public void onResponse(Call call, @NotNull Response response) { try { + final ResponseBody responseBody = response.body(); final FaucetResponse faucetResponse; if (response.isSuccessful()) { - final ResponseBody responseBody = response.body(); - if (responseBody != null) { - jsonRpc20Response = jsonHandler.fromJson(responseBody.string(), typeOfT); - } else { - jsonRpc20Response = new JsonRpc20Response<>(); - } - } else { - jsonRpc20Response = new JsonRpc20Response<>(); - JsonRpc20Response.Error error = new JsonRpc20Response.Error(); - error.setCode(JsonRpc20Response.Error.ErrorCode.FAILURE_RESPONSE); - jsonRpc20Response.setError(error); + faucetResponse = + jsonHandler.fromJsonFaucet(Objects.requireNonNull(responseBody).string()); + future.complete(faucetResponse); + } else if (response.code() == 403) { + future.completeExceptionally(new SuiApiException(new HttpForbiddenException())); } - future.complete(jsonRpc20Response); } catch (Throwable throwable) { future.completeExceptionally(throwable); } diff --git a/src/main/java/io/sui/clients/PayRecipientsAndAmountsMismatchException.java b/src/main/java/io/sui/clients/PayRecipientsAndAmountsMismatchException.java index c45720c..0569b9a 100644 --- a/src/main/java/io/sui/clients/PayRecipientsAndAmountsMismatchException.java +++ b/src/main/java/io/sui/clients/PayRecipientsAndAmountsMismatchException.java @@ -1,7 +1,39 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/21 - * Time: 16:07 - */public class PayRecipientsAndAmountsMismatchException { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + +/** + * The type Pay recipients and amounts mismatch exception. + * + * @author grapebaba + * @since 2023.03 + */ +public class PayRecipientsAndAmountsMismatchException extends RuntimeException { + + /** + * Instantiates a new Pay recipients and amounts mismatch exception. + * + * @param recipientsSize the recipients size + * @param amountsSize the amounts size + */ + public PayRecipientsAndAmountsMismatchException(int recipientsSize, int amountsSize) { + super( + String.format( + "recipients and amounts mismatch. Got %d recipients but %d amounts", + recipientsSize, amountsSize)); + } } diff --git a/src/main/java/io/sui/clients/ProgrammableTransactionBuilder.java b/src/main/java/io/sui/clients/ProgrammableTransactionBuilder.java index 649d053..bbfdc0b 100644 --- a/src/main/java/io/sui/clients/ProgrammableTransactionBuilder.java +++ b/src/main/java/io/sui/clients/ProgrammableTransactionBuilder.java @@ -1,7 +1,792 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/17 - * Time: 18:06 - */public class ProgrammableTransactionBuilder { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + + +import com.google.common.collect.Lists; +import com.novi.bcs.BcsSerializer; +import com.novi.serde.SerializationError; +import com.novi.serde.Serializer; +import com.novi.serde.Tuple3; +import io.sui.bcsgen.Argument; +import io.sui.bcsgen.Argument.GasCoin; +import io.sui.bcsgen.Argument.Input; +import io.sui.bcsgen.Argument.NestedResult; +import io.sui.bcsgen.Argument.Result; +import io.sui.bcsgen.CallArg; +import io.sui.bcsgen.CallArg.Object; +import io.sui.bcsgen.CallArg.Pure; +import io.sui.bcsgen.Command; +import io.sui.bcsgen.Command.MakeMoveVec; +import io.sui.bcsgen.Command.MergeCoins; +import io.sui.bcsgen.Command.MoveCall; +import io.sui.bcsgen.Command.Publish; +import io.sui.bcsgen.Command.SplitCoins; +import io.sui.bcsgen.Command.TransferObjects; +import io.sui.bcsgen.GasData; +import io.sui.bcsgen.Identifier; +import io.sui.bcsgen.MoveValue; +import io.sui.bcsgen.ObjectArg; +import io.sui.bcsgen.ObjectArg.ImmOrOwnedObject; +import io.sui.bcsgen.ObjectArg.SharedObject; +import io.sui.bcsgen.ObjectDigest; +import io.sui.bcsgen.ObjectID; +import io.sui.bcsgen.ProgrammableMoveCall; +import io.sui.bcsgen.ProgrammableTransaction; +import io.sui.bcsgen.ProgrammableTransaction.Builder; +import io.sui.bcsgen.SequenceNumber; +import io.sui.bcsgen.SuiAddress; +import io.sui.bcsgen.TransactionData; +import io.sui.bcsgen.TransactionData.V1; +import io.sui.bcsgen.TransactionDataV1; +import io.sui.bcsgen.TransactionExpiration; +import io.sui.bcsgen.TransactionKind; +import io.sui.bcsgen.TypeTag; +import io.sui.clients.BuilderArg.ForcedNonUniquePureBuilderArg; +import io.sui.clients.BuilderArg.ObjectBuilderArg; +import io.sui.clients.BuilderArg.PureBuilderArg; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; + +/** + * The type Programmable transaction builder. + * + * @author grapebaba + * @since 2023.03 + */ +public class ProgrammableTransactionBuilder { + + private LinkedHashMap inputs = new LinkedHashMap<>(); + + private List commands = new ArrayList<>(); + + /** + * Gets inputs. + * + * @return the inputs + */ + public LinkedHashMap getInputs() { + return inputs; + } + + /** + * Build programmable transaction. + * + * @return the programmable transaction + */ + public ProgrammableTransaction build() { + ProgrammableTransaction.Builder builder = new Builder(); + builder.inputs = Lists.newArrayList(inputs.values()); + builder.commands = commands; + return builder.build(); + } + + /** + * Pure bytes argument. + * + * @param bytes the bytes + * @param forceSeparate the force separate + * @return the argument + */ + public Argument pureBytes(byte[] bytes, boolean forceSeparate) { + final BuilderArg arg = + forceSeparate + ? new ForcedNonUniquePureBuilderArg(this.inputs.size()) + : new PureBuilderArg(bytes); + CallArg.Pure.Builder builder = new Pure.Builder(); + builder.value = Arrays.asList(ArrayUtils.toObject(bytes)); + this.inputs.put(arg, builder.build()); + Argument.Input.Builder argBuilder = new Input.Builder(); + argBuilder.value = (short) (this.inputs.size() - 1); + return argBuilder.build(); + } + + /** + * Obj argument. + * + * @param objectArg the object arg + * @return the argument + */ + public Argument obj(ObjectArg objectArg) { + ObjectID objectId; + if (objectArg instanceof ImmOrOwnedObject) { + objectId = ((ImmOrOwnedObject) objectArg).value.field0; + } else { + objectId = ((SharedObject) objectArg).id; + } + + ObjectBuilderArg search = new ObjectBuilderArg(objectId); + ObjectArg input = getOrCreate(objectArg, search); + + CallArg.Object.Builder objectBuilder = new Object.Builder(); + objectBuilder.value = input; + this.inputs.put(search, objectBuilder.build()); + Argument.Input.Builder argBuilder = new Input.Builder(); + argBuilder.value = (short) (this.inputs.size() - 1); + return argBuilder.build(); + } + + /** + * Input argument. + * + * @param callArg the call arg + * @return the argument + */ + public Argument input(CallArg callArg) { + if (callArg instanceof CallArg.Pure) { + return pureBytes(ArrayUtils.toPrimitive(((Pure) callArg).value.toArray(new Byte[0])), false); + } else { + return obj(((Object) callArg).value); + } + } + + private ObjectArg getOrCreate(ObjectArg objectArg, ObjectBuilderArg search) { + if (!this.inputs.containsKey(search)) { + return objectArg; + } + + ObjectArg old = ((Object) this.inputs.get(search)).value; + if ((objectArg instanceof SharedObject) && (old instanceof SharedObject)) { + if (((SharedObject) objectArg) + .initial_shared_version.equals(((SharedObject) old).initial_shared_version)) { + ObjectArg.SharedObject.Builder shardObjectArgBuilder = new SharedObject.Builder(); + shardObjectArgBuilder.id = search.getId(); + shardObjectArgBuilder.initial_shared_version = + ((SharedObject) objectArg).initial_shared_version; + shardObjectArgBuilder.mutable = + ((SharedObject) objectArg).mutable || ((SharedObject) old).mutable; + return shardObjectArgBuilder.build(); + } + } + + if (!objectArg.equals(old)) { + throw new MismatchedObjectArgumentException(search.getId(), old, objectArg); + } + + return objectArg; + } + + /** + * Make obj vec argument. + * + * @param objs the objs + * @return the argument + */ + public Argument makeObjVec(List objs) { + List arguments = objs.stream().map(this::obj).collect(Collectors.toList()); + Command.MakeMoveVec.Builder makeMoveVecBuilder = new MakeMoveVec.Builder(); + makeMoveVecBuilder.field0 = Optional.empty(); + makeMoveVecBuilder.field1 = arguments; + return command(makeMoveVecBuilder.build()); + } + + /** + * Pure argument. + * + * @param value the value + * @return the argument + */ + public Argument pure(java.lang.Object value) { + byte[] bytes; + try { + if (value instanceof MoveValue) { + bytes = ((MoveValue) value).bcsSerialize(); + } else if (value instanceof SuiAddress) { + bytes = ((SuiAddress) value).bcsSerialize(); + } else if (value instanceof Long) { + Serializer serializer = new BcsSerializer(); + serializer.increase_container_depth(); + serializer.serialize_u64((Long) value); + serializer.decrease_container_depth(); + bytes = serializer.get_bytes(); + } else { + throw new NotSupportedArgumentException(value.getClass()); + } + return this.pureBytes(bytes, false); + } catch (SerializationError e) { + throw new BcsSerializationException(e); + } + } + + /** + * Command argument. + * + * @param command the command + * @return the argument + */ + public Argument command(Command command) { + Argument argument = new Result((short) this.commands.size()); + this.commands.add(command); + return argument; + } + + /** + * Move call argument. + * + * @param suiPackage the sui package + * @param module the module + * @param function the function + * @param typeArguments the type arguments + * @param arguments the arguments + * @return the argument + */ + public Argument moveCall( + ObjectID suiPackage, + Identifier module, + Identifier function, + List typeArguments, + List arguments) { + List bcsArguments = + arguments.stream() + .map( + callArg -> { + if (callArg instanceof CallArgObjVec) { + return this.makeObjVec(((CallArgObjVec) callArg).getObjectArgs()); + } + return this.input(callArg); + }) + .collect(Collectors.toList()); + + return this.programmableMoveCall(suiPackage, module, function, typeArguments, bcsArguments); + } + + /** + * Programmable move call argument. + * + * @param suiPackage the sui package + * @param module the module + * @param function the function + * @param typeArguments the type arguments + * @param arguments the arguments + * @return the argument + */ + public Argument programmableMoveCall( + ObjectID suiPackage, + Identifier module, + Identifier function, + List typeArguments, + List arguments) { + ProgrammableMoveCall.Builder progCallBuilder = new ProgrammableMoveCall.Builder(); + progCallBuilder.Package = suiPackage; + progCallBuilder.module = module; + progCallBuilder.function = function; + progCallBuilder.type_arguments = typeArguments; + progCallBuilder.arguments = arguments; + Command.MoveCall.Builder callBuilder = new MoveCall.Builder(); + callBuilder.value = progCallBuilder.build(); + return this.command(callBuilder.build()); + } + + /** + * Transfer arg argument. + * + * @param recipient the recipient + * @param arg the arg + * @return the argument + */ + public Argument transferArg(SuiAddress recipient, Argument arg) { + return this.transferArgs(recipient, Lists.newArrayList(arg)); + } + + /** + * Transfer args argument. + * + * @param recipient the recipient + * @param args the args + * @return the argument + */ + public Argument transferArgs(SuiAddress recipient, List args) { + Argument recArg = this.pure(recipient); + Command.TransferObjects.Builder builder = new TransferObjects.Builder(); + builder.field0 = args; + builder.field1 = recArg; + return this.command(builder.build()); + } + + /** + * Publish upgradeable argument. + * + * @param modules the modules + * @param depIds the dep ids + * @return the argument + */ + public Argument publishUpgradeable(List> modules, List depIds) { + Command.Publish.Builder builder = new Publish.Builder(); + builder.field0 = modules; + builder.field1 = depIds; + return this.command(builder.build()); + } + + /** + * Transfer sui argument. + * + * @param recipient the recipient + * @param amount the amount + * @return the argument + */ + public Argument transferSui(SuiAddress recipient, Long amount) { + Argument recipientArg = this.pure(recipient); + Argument coinArg; + if (amount != null) { + Argument amountArg = this.pure(amount); + Command.SplitCoins.Builder splitCoinCommandBuilder = new SplitCoins.Builder(); + splitCoinCommandBuilder.field0 = new Argument.GasCoin.Builder().build(); + splitCoinCommandBuilder.field1 = Lists.newArrayList(amountArg); + coinArg = this.command(splitCoinCommandBuilder.build()); + } else { + coinArg = new Argument.GasCoin.Builder().build(); + } + + Command.TransferObjects.Builder transferObjectsCommandBuilder = new TransferObjects.Builder(); + transferObjectsCommandBuilder.field0 = Lists.newArrayList(coinArg); + transferObjectsCommandBuilder.field1 = recipientArg; + return this.command(transferObjectsCommandBuilder.build()); + } + + /** + * Transfer object argument. + * + * @param recipient the recipient + * @param objectRef the object ref + * @return the argument + */ + public Argument transferObject( + SuiAddress recipient, Tuple3 objectRef) { + return transferObjects(recipient, Lists.newArrayList(objectRef)); + } + + /** + * Split coins argument. + * + * @param amounts the amounts + * @return the argument + */ + public Argument splitCoins(List amounts) { + Argument coin = new GasCoin.Builder().build(); + List amountArgs = amounts.stream().map(this::pure).collect(Collectors.toList()); + + return splitCoins(coin, amountArgs); + } + + /** + * Split coins argument. + * + * @param coin the coin + * @param amounts the amounts + * @return the argument + */ + public Argument splitCoins( + Tuple3 coin, List amounts) { + ImmOrOwnedObject.Builder objectBuilder = new ImmOrOwnedObject.Builder(); + objectBuilder.value = coin; + Argument coinArg = obj(objectBuilder.build()); + + List amountArgs = amounts.stream().map(this::pure).collect(Collectors.toList()); + + return splitCoins(coinArg, amountArgs); + } + + /** + * Split coins argument. + * + * @param coin the coin + * @param amounts the amounts + * @return the argument + */ + public Argument splitCoins(Argument coin, List amounts) { + Command.SplitCoins.Builder builder = new SplitCoins.Builder(); + builder.field0 = coin; + builder.field1 = amounts; + return this.command(builder.build()); + } + + /** + * Merge coins argument. + * + * @param destCoin the dest coin + * @param sourceCoins the source coins + * @return the argument + */ + public Argument mergeCoins( + Tuple3 destCoin, + List> sourceCoins) { + ImmOrOwnedObject.Builder objectBuilder = new ImmOrOwnedObject.Builder(); + objectBuilder.value = destCoin; + Argument dcoin = obj(objectBuilder.build()); + + List scoins = + sourceCoins.stream() + .map( + objectRef -> { + ImmOrOwnedObject.Builder builder = new ImmOrOwnedObject.Builder(); + builder.value = objectRef; + return obj(builder.build()); + }) + .collect(Collectors.toList()); + + return mergeCoins(dcoin, scoins); + } + + /** + * Merge coins argument. + * + * @param destinationCoin the destination coin + * @param sourceCoins the source coins + * @return the argument + */ + public Argument mergeCoins(Argument destinationCoin, List sourceCoins) { + Command.MergeCoins.Builder builder = new MergeCoins.Builder(); + builder.field0 = destinationCoin; + builder.field1 = sourceCoins; + return this.command(builder.build()); + } + + /** + * Transfer objects argument. + * + * @param objects the objects + * @param recipient the recipient + * @return the argument + */ + public Argument transferObjects(List objects, Argument recipient) { + Command.TransferObjects.Builder transferObjectsCommandBuilder = new TransferObjects.Builder(); + transferObjectsCommandBuilder.field0 = objects; + transferObjectsCommandBuilder.field1 = recipient; + return this.command(transferObjectsCommandBuilder.build()); + } + + /** + * Transfer objects argument. + * + * @param recipient the recipient + * @param objectRefs the object refs + * @return the argument + */ + public Argument transferObjects( + SuiAddress recipient, List> objectRefs) { + Argument recipientArg = this.pure(recipient); + List arguments = + objectRefs.stream() + .map( + objectRef -> { + ImmOrOwnedObject.Builder objectBuilder = new ImmOrOwnedObject.Builder(); + objectBuilder.value = objectRef; + return obj(objectBuilder.build()); + }) + .collect(Collectors.toList()); + + return transferObjects(arguments, recipientArg); + } + + /** + * Pay all sui argument. + * + * @param recipient the recipient + * @return the argument + */ + public Argument payAllSui(SuiAddress recipient) { + Argument recArg = this.pure(recipient); + Command.TransferObjects.Builder builder = new TransferObjects.Builder(); + builder.field0 = Lists.newArrayList(new Argument.GasCoin.Builder().build()); + builder.field1 = recArg; + return this.command(builder.build()); + } + + /** + * Pay sui. + * + * @param recipients the recipients + * @param amounts the amounts + */ + public void paySui(List recipients, List amounts) { + Argument coinArg = new Argument.GasCoin.Builder().build(); + this.payImpl(recipients, amounts, coinArg); + } + + /** + * Pay. + * + * @param coins the coins + * @param recipients the recipients + * @param amounts the amounts + */ + public void pay( + List> coins, + List recipients, + List amounts) { + if (coins.isEmpty()) { + throw new EmptyInputCoinsException(); + } + ObjectArg.ImmOrOwnedObject.Builder coinBuilder = new ImmOrOwnedObject.Builder(); + coinBuilder.value = coins.get(0); + Argument coinArg = this.obj(coinBuilder.build()); + if (coins.size() > 1) { + List mergeArgs = + coins.subList(1, coins.size()).stream() + .map( + coin -> { + ImmOrOwnedObject.Builder builder = new ImmOrOwnedObject.Builder(); + builder.value = coin; + return obj(builder.build()); + }) + .collect(Collectors.toList()); + Command.MergeCoins.Builder mergeBuilder = new MergeCoins.Builder(); + mergeBuilder.field0 = coinArg; + mergeBuilder.field1 = mergeArgs; + this.command(mergeBuilder.build()); + } + this.payImpl(recipients, amounts, coinArg); + } + + private void payImpl(List recipients, List amounts, Argument coin) { + if (recipients.size() != amounts.size()) { + throw new PayRecipientsAndAmountsMismatchException(recipients.size(), amounts.size()); + } + + if (amounts.isEmpty()) { + return; + } + + LinkedHashMap> recipientMap = new LinkedHashMap<>(); + List amtArgs = Lists.newArrayList(); + for (int i = 0; i < recipients.size(); i++) { + if (recipientMap.containsKey(recipients.get(i))) { + recipientMap.get(recipients.get(i)).add(i); + } else { + recipientMap.put(recipients.get(i), Lists.newArrayList(i)); + } + amtArgs.add(this.pure(amounts.get(i))); + } + + Command.SplitCoins.Builder splitBuilder = new SplitCoins.Builder(); + splitBuilder.field0 = coin; + splitBuilder.field1 = amtArgs; + + Argument.Result splitPrimary = (Result) this.command(splitBuilder.build()); + for (Entry> entry : recipientMap.entrySet()) { + SuiAddress suiAddress = entry.getKey(); + List splitSecondaries = entry.getValue(); + Argument recArg = pure(suiAddress); + List coins = Lists.newArrayList(); + for (Integer index : splitSecondaries) { + Argument.NestedResult.Builder nestedBuilder = new NestedResult.Builder(); + nestedBuilder.field0 = splitPrimary.value; + nestedBuilder.field1 = index.shortValue(); + coins.add(nestedBuilder.build()); + } + TransferObjects.Builder transferBuilder = new TransferObjects.Builder(); + transferBuilder.field0 = coins; + transferBuilder.field1 = recArg; + command(transferBuilder.build()); + } + } + + /** + * New transfer sui transaction data. + * + * @param recipient the recipient + * @param sender the sender + * @param amount the amount + * @param gasPayment the gas payment + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newTransferSui( + SuiAddress recipient, + SuiAddress sender, + Long amount, + Tuple3 gasPayment, + Long gasBudget, + Long gasPrice) { + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + programmableTransactionBuilder.transferSui(recipient, amount); + ProgrammableTransaction programmableTransaction = programmableTransactionBuilder.build(); + return newProgrammable( + sender, Lists.newArrayList(gasPayment), programmableTransaction, gasBudget, gasPrice); + } + + /** + * New pay sui transaction data. + * + * @param sender the sender + * @param coins the coins + * @param recipients the recipients + * @param amounts the amounts + * @param gasPayment the gas payment + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newPaySui( + SuiAddress sender, + List> coins, + List recipients, + List amounts, + Tuple3 gasPayment, + Long gasBudget, + Long gasPrice) { + coins.add(0, gasPayment); + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + programmableTransactionBuilder.paySui(recipients, amounts); + ProgrammableTransaction programmableTransaction = programmableTransactionBuilder.build(); + return newProgrammable(sender, coins, programmableTransaction, gasBudget, gasPrice); + } + + /** + * New pay all sui transaction data. + * + * @param sender the sender + * @param coins the coins + * @param recipient the recipient + * @param gasPayment the gas payment + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newPayAllSui( + SuiAddress sender, + List> coins, + SuiAddress recipient, + Tuple3 gasPayment, + Long gasBudget, + Long gasPrice) { + coins.add(0, gasPayment); + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + programmableTransactionBuilder.payAllSui(recipient); + ProgrammableTransaction programmableTransaction = programmableTransactionBuilder.build(); + return newProgrammable(sender, coins, programmableTransaction, gasBudget, gasPrice); + } + + /** + * New pay transaction data. + * + * @param sender the sender + * @param coins the coins + * @param recipients the recipients + * @param amounts the amounts + * @param gasPayment the gas payment + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newPay( + SuiAddress sender, + List> coins, + List recipients, + List amounts, + Tuple3 gasPayment, + Long gasBudget, + Long gasPrice) { + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + programmableTransactionBuilder.pay(coins, recipients, amounts); + ProgrammableTransaction programmableTransaction = programmableTransactionBuilder.build(); + return newProgrammable( + sender, Lists.newArrayList(gasPayment), programmableTransaction, gasBudget, gasPrice); + } + + /** + * New module transaction data. + * + * @param sender the sender + * @param gasPayment the gas payment + * @param modules the modules + * @param depIds the dep ids + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newModule( + SuiAddress sender, + List> gasPayment, + List> modules, + List depIds, + Long gasBudget, + Long gasPrice) { + ProgrammableTransactionBuilder programmableTransactionBuilder = + new ProgrammableTransactionBuilder(); + Argument upgradeArg = programmableTransactionBuilder.publishUpgradeable(modules, depIds); + programmableTransactionBuilder.transferArg(sender, upgradeArg); + ProgrammableTransaction programmableTransaction = programmableTransactionBuilder.build(); + return newProgrammable( + sender, Lists.newArrayList(gasPayment), programmableTransaction, gasBudget, gasPrice); + } + + /** + * New programmable transaction data. + * + * @param sender the sender + * @param gasPayment the gas payment + * @param programmableTransaction the programmable transaction + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newProgrammable( + SuiAddress sender, + List> gasPayment, + ProgrammableTransaction programmableTransaction, + Long gasBudget, + Long gasPrice) { + TransactionKind.ProgrammableTransaction.Builder builder = + new TransactionKind.ProgrammableTransaction.Builder(); + builder.value = programmableTransaction; + return newWithGasCoins(builder.build(), sender, gasPayment, gasBudget, gasPrice); + } + + /** + * New with gas coins transaction data. + * + * @param kind the kind + * @param sender the sender + * @param gasPayment the gas payment + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the transaction data + */ + public static TransactionData newWithGasCoins( + TransactionKind kind, + SuiAddress sender, + List> gasPayment, + Long gasBudget, + Long gasPrice) { + + TransactionDataV1.Builder v1builder = new TransactionDataV1.Builder(); + v1builder.kind = kind; + v1builder.sender = sender; + GasData.Builder gasBuilder = new GasData.Builder(); + gasBuilder.payment = gasPayment; + gasBuilder.price = gasPrice; + gasBuilder.budget = gasBudget; + gasBuilder.owner = sender; + v1builder.gas_data = gasBuilder.build(); + v1builder.expiration = new TransactionExpiration.None.Builder().build(); + TransactionData.V1.Builder builder = new V1.Builder(); + builder.value = v1builder.build(); + return builder.build(); + } } diff --git a/src/main/java/io/sui/clients/QueryClient.java b/src/main/java/io/sui/clients/QueryClient.java index 92d9102..3169fd7 100644 --- a/src/main/java/io/sui/clients/QueryClient.java +++ b/src/main/java/io/sui/clients/QueryClient.java @@ -29,16 +29,19 @@ import io.sui.models.objects.MoveNormalizedFunction; import io.sui.models.objects.MoveNormalizedModule; import io.sui.models.objects.MoveNormalizedStruct; +import io.sui.models.objects.ObjectDataOptions; import io.sui.models.objects.ObjectResponse; +import io.sui.models.objects.ObjectResponseQuery; import io.sui.models.objects.PaginatedCoins; -import io.sui.models.objects.SuiObjectInfo; +import io.sui.models.objects.PaginatedObjectsResponse; import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiObjectResponse; import io.sui.models.objects.SuiSystemState; import io.sui.models.objects.ValidatorMetadata; -import io.sui.models.transactions.PaginatedTransactionDigests; -import io.sui.models.transactions.TransactionQuery; -import io.sui.models.transactions.TransactionResponse; -import io.sui.models.transactions.TransactionResponseOptions; +import io.sui.models.transactions.PaginatedTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; +import io.sui.models.transactions.TransactionBlockResponseQuery; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -58,40 +61,30 @@ public interface QueryClient { * Gets object. * * @param id the id + * @param objectDataOptions the object data options * @return the object */ - CompletableFuture getObject(String id); + CompletableFuture getObject(String id, ObjectDataOptions objectDataOptions); /** * Gets objects owned by address. * * @param address the address + * @param query the query + * @param cursor the cursor + * @param limit the limit + * @param checkpointId the checkpoint id * @return the objects owned by address */ - CompletableFuture> getObjectsOwnedByAddress(String address); - - /** - * Gets objects owned by object. - * - * @param objectId the object id - * @return the objects owned by object - */ - CompletableFuture> getObjectsOwnedByObject(String objectId); - - /** - * Gets raw object. - * - * @param id the id - * @return the raw object - */ - CompletableFuture getRawObject(String id); + CompletableFuture getObjectsOwnedByAddress( + String address, ObjectResponseQuery query, String cursor, Integer limit, String checkpointId); /** * Gets total transaction number. * * @return the total transaction number */ - CompletableFuture getTotalTransactionNumber(); + CompletableFuture getTotalTransactionBlocks(); /** * Gets transaction. @@ -100,25 +93,21 @@ public interface QueryClient { * @param options the options * @return the transaction */ - CompletableFuture getTransaction( - String digest, TransactionResponseOptions options); + CompletableFuture getTransactionBlock( + String digest, TransactionBlockResponseOptions options); /** - * Return the authority public keys that commits to the authority signature of the transaction. + * Multi get transaction blocks completable future. * - * @param transactionDigest the digest - * @return the Transaction auth signers + * @param digests the digests + * @param options the options + * @return the completable future */ - CompletableFuture getTransactionAuthSigners(String transactionDigest); + CompletableFuture> multiGetTransactionBlocks( + List digests, TransactionBlockResponseOptions options); - /** - * Gets transactions in range. - * - * @param start the start - * @param end the end - * @return the transactions in range - */ - CompletableFuture> getTransactionsInRange(Long start, Long end); + CompletableFuture> multiGetObjects( + List objectIds, ObjectDataOptions options); /** * Gets sui system state. @@ -223,8 +212,8 @@ CompletableFuture getNormalizedMoveStruct( * @param isDescOrder the is desc order * @return the transactions */ - CompletableFuture getTransactions( - TransactionQuery query, String cursor, int limit, boolean isDescOrder); + CompletableFuture queryTransactionBlocks( + TransactionBlockResponseQuery query, String cursor, Integer limit, boolean isDescOrder); /** * Gets coin metadata. @@ -245,9 +234,10 @@ CompletableFuture getTransactions( * Gets object ref. * * @param id the id + * @param objectDataOptions the object data options * @return the object ref */ - CompletableFuture getObjectRef(String id); + CompletableFuture getObjectRef(String id, ObjectDataOptions objectDataOptions); /** * Return the total coin balance for all coin type, owned by the address owner. diff --git a/src/main/java/io/sui/clients/QueryClientImpl.java b/src/main/java/io/sui/clients/QueryClientImpl.java index 423e7cb..f800dd4 100644 --- a/src/main/java/io/sui/clients/QueryClientImpl.java +++ b/src/main/java/io/sui/clients/QueryClientImpl.java @@ -33,16 +33,19 @@ import io.sui.models.objects.MoveNormalizedFunction; import io.sui.models.objects.MoveNormalizedModule; import io.sui.models.objects.MoveNormalizedStruct; +import io.sui.models.objects.ObjectDataOptions; import io.sui.models.objects.ObjectResponse; +import io.sui.models.objects.ObjectResponseQuery; import io.sui.models.objects.PaginatedCoins; -import io.sui.models.objects.SuiObjectInfo; +import io.sui.models.objects.PaginatedObjectsResponse; import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiObjectResponse; import io.sui.models.objects.SuiSystemState; import io.sui.models.objects.ValidatorMetadata; -import io.sui.models.transactions.PaginatedTransactionDigests; -import io.sui.models.transactions.TransactionQuery; -import io.sui.models.transactions.TransactionResponse; -import io.sui.models.transactions.TransactionResponseOptions; +import io.sui.models.transactions.PaginatedTransactionResponse; +import io.sui.models.transactions.TransactionBlockResponse; +import io.sui.models.transactions.TransactionBlockResponseOptions; +import io.sui.models.transactions.TransactionBlockResponseQuery; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -68,84 +71,76 @@ public QueryClientImpl(JsonRpcClientProvider jsonRpcClientProvider) { } @Override - public CompletableFuture getObject(String id) { - final JsonRpc20Request request = - this.jsonRpcClientProvider.createJsonRpc20Request("sui_getObject", Lists.newArrayList(id)); - return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getObject", request, new TypeToken() {}.getType()); - } - - public CompletableFuture getObjectRef(String id) { - return this.getObject(id).thenApply(ObjectResponse::getObjectRef); - } - - @Override - public CompletableFuture> getObjectsOwnedByAddress(String address) { + public CompletableFuture getObject( + String id, ObjectDataOptions objectDataOptions) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getObjectsOwnedByAddress", Lists.newArrayList(address)); + "sui_getObject", Lists.newArrayList(id, objectDataOptions)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getObjectsOwnedByAddress", - request, - new TypeToken>() {}.getType()); + "/sui_getObject", request, new TypeToken() {}.getType()); } - @Override - public CompletableFuture> getObjectsOwnedByObject(String objectId) { - final JsonRpc20Request request = - this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getObjectsOwnedByObject", Lists.newArrayList(objectId)); - return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getObjectsOwnedByObject", request, new TypeToken>() {}.getType()); + public CompletableFuture getObjectRef( + String id, ObjectDataOptions objectDataOptions) { + return this.getObject(id, objectDataOptions).thenApply(SuiObjectResponse::getObjectRef); } @Override - public CompletableFuture getRawObject(String id) { + public CompletableFuture getObjectsOwnedByAddress( + String address, + ObjectResponseQuery query, + String cursor, + Integer limit, + String checkpointId) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getRawObject", Lists.newArrayList(id)); + "suix_getOwnedObjects", + Lists.newArrayList(address, query, cursor, limit, checkpointId)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getRawObject", request, new TypeToken() {}.getType()); + "/suix_getOwnedObjects", request, new TypeToken() {}.getType()); } @Override - public CompletableFuture getTotalTransactionNumber() { + public CompletableFuture getTotalTransactionBlocks() { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getTotalTransactionNumber", Lists.newArrayList()); + "sui_getTotalTransactionBlocks", Lists.newArrayList()); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getTotalTransactionNumber", request, new TypeToken() {}.getType()); + "/sui_getTotalTransactionBlocks", request, new TypeToken() {}.getType()); } @Override - public CompletableFuture getTransaction( - String digest, TransactionResponseOptions options) { + public CompletableFuture getTransactionBlock( + String digest, TransactionBlockResponseOptions options) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getTransaction", Lists.newArrayList(digest, options)); + "sui_getTransactionBlock", Lists.newArrayList(digest, options)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getTransaction", request, new TypeToken() {}.getType()); + "/sui_getTransactionBlock", + request, + new TypeToken() {}.getType()); } @Override - public CompletableFuture getTransactionAuthSigners( - String transactionDigest) { + public CompletableFuture> multiGetTransactionBlocks( + List digests, TransactionBlockResponseOptions options) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getTransactionAuthSigners", Lists.newArrayList(transactionDigest)); + "sui_multiGetTransactionBlocks", Lists.newArrayList(digests, options)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getTransactionAuthSigners", + "/sui_multiGetTransactionBlocks", request, - new TypeToken() {}.getType()); + new TypeToken>() {}.getType()); } @Override - public CompletableFuture> getTransactionsInRange(Long start, Long end) { + public CompletableFuture> multiGetObjects( + List objectIds, ObjectDataOptions options) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getTransactionsInRange", Lists.newArrayList(start, end)); + "sui_multiGetObjects", Lists.newArrayList(objectIds, options)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getTransactionsInRange", request, new TypeToken>() {}.getType()); + "/sui_multiGetObjects", request, new TypeToken>() {}.getType()); } @Override @@ -255,13 +250,15 @@ public CompletableFuture tryGetPastObject(String objectId, long } @Override - public CompletableFuture getTransactions( - TransactionQuery query, String cursor, int limit, boolean isDescOrder) { + public CompletableFuture queryTransactionBlocks( + TransactionBlockResponseQuery query, String cursor, Integer limit, boolean isDescOrder) { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getTransactions", Lists.newArrayList(query, cursor, limit, isDescOrder)); + "suix_queryTransactionBlocks", Lists.newArrayList(query, cursor, limit, isDescOrder)); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getTransactions", request, new TypeToken() {}.getType()); + "/suix_queryTransactionBlocks", + request, + new TypeToken() {}.getType()); } @Override @@ -277,9 +274,9 @@ public CompletableFuture getCoinMetadata(String coinType) { public CompletableFuture getReferenceGasPrice() { final JsonRpc20Request request = this.jsonRpcClientProvider.createJsonRpc20Request( - "sui_getReferenceGasPrice", Lists.newArrayList()); + "suix_getReferenceGasPrice", Lists.newArrayList()); return this.jsonRpcClientProvider.callAndUnwrapResponse( - "/sui_getReferenceGasPrice", request, new TypeToken() {}.getType()); + "/suix_getReferenceGasPrice", request, new TypeToken() {}.getType()); } @Override diff --git a/src/main/java/io/sui/clients/TransactionBlock.java b/src/main/java/io/sui/clients/TransactionBlock.java index 47bd9dd..807232a 100644 --- a/src/main/java/io/sui/clients/TransactionBlock.java +++ b/src/main/java/io/sui/clients/TransactionBlock.java @@ -1,7 +1,1143 @@ -package io.sui.clients;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/3 - * Time: 15:53 - */public class TransactionBlock { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.clients; + +import static io.sui.bcsgen.CallArg.Pure.Builder; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Streams; +import com.novi.serde.Bytes; +import com.novi.serde.DeserializationError; +import com.novi.serde.SerializationError; +import com.novi.serde.Tuple3; +import io.sui.bcsgen.AccountAddress; +import io.sui.bcsgen.Argument; +import io.sui.bcsgen.CallArg; +import io.sui.bcsgen.Digest; +import io.sui.bcsgen.GasCoin; +import io.sui.bcsgen.GasData; +import io.sui.bcsgen.Identifier; +import io.sui.bcsgen.MoveValue; +import io.sui.bcsgen.MoveValue.Bool; +import io.sui.bcsgen.MoveValue.U8; +import io.sui.bcsgen.MoveValue.Vector; +import io.sui.bcsgen.ObjectArg; +import io.sui.bcsgen.ObjectArg.ImmOrOwnedObject; +import io.sui.bcsgen.ObjectArg.SharedObject; +import io.sui.bcsgen.ObjectDigest; +import io.sui.bcsgen.ObjectID; +import io.sui.bcsgen.SequenceNumber; +import io.sui.bcsgen.StructTag; +import io.sui.bcsgen.SuiAddress; +import io.sui.bcsgen.TransactionData; +import io.sui.bcsgen.TransactionData.V1; +import io.sui.bcsgen.TransactionDataV1; +import io.sui.bcsgen.TransactionExpiration; +import io.sui.bcsgen.TransactionExpiration.Epoch; +import io.sui.bcsgen.TransactionKind; +import io.sui.bcsgen.TypeTag.bool; +import io.sui.bcsgen.TypeTag.u128; +import io.sui.bcsgen.TypeTag.u16; +import io.sui.bcsgen.TypeTag.u256; +import io.sui.bcsgen.TypeTag.u32; +import io.sui.bcsgen.TypeTag.u64; +import io.sui.bcsgen.TypeTag.u8; +import io.sui.models.objects.MoveNormalizedFunction; +import io.sui.models.objects.MoveNormalizedType; +import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType; +import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType.Struct; +import io.sui.models.objects.MoveNormalizedType.MutableReferenceMoveNormalizedType; +import io.sui.models.objects.MoveNormalizedType.TypeMoveNormalizedType; +import io.sui.models.objects.MoveNormalizedType.VectorReferenceMoveNormalizedType; +import io.sui.models.objects.ObjectDataOptions; +import io.sui.models.objects.ObjectResponseQuery; +import io.sui.models.objects.PaginatedObjectsResponse; +import io.sui.models.objects.SuiObjectData; +import io.sui.models.objects.SuiObjectOwner; +import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiRawData; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bitcoinj.core.Base58; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.jetbrains.annotations.NotNull; + +/** + * The type Transaction block. + * + * @author grapebaba + * @since 2023.04 + */ +public class TransactionBlock { + + private static final Struct RESOLVED_ASCII_STR = new Struct(); + private static final Struct RESOLVED_UTF8_STR = new Struct(); + private static final Struct RESOLVED_SUI_ID = new Struct(); + private static final Struct RESOLVED_STD_OPTION = new Struct(); + private static final String GAS_COIN_TYPE = "0x2::coin::Coin<0x2::sui::SUI>"; + private static final String SUI_FRAMEWORK_ADDRESS = "0x0000000000000000000000000000000000000002"; + + static { + RESOLVED_ASCII_STR.setAddress("0x1"); + RESOLVED_ASCII_STR.setModule("ascii"); + RESOLVED_ASCII_STR.setName("String"); + + RESOLVED_UTF8_STR.setAddress("0x1"); + RESOLVED_UTF8_STR.setModule("string"); + RESOLVED_UTF8_STR.setName("String"); + + RESOLVED_SUI_ID.setAddress("0x2"); + RESOLVED_SUI_ID.setModule("object"); + RESOLVED_SUI_ID.setName("ID"); + + RESOLVED_STD_OPTION.setAddress("0x2"); + RESOLVED_STD_OPTION.setModule("option"); + RESOLVED_STD_OPTION.setName("Option"); + } + + private final ProgrammableTransactionBuilder programmableTransactionBuilder; + + private final QueryClient queryClient; + + private final GasData.Builder gasBuilder; + + private SuiAddress sender; + + private TransactionExpiration transactionExpiration = + new TransactionExpiration.None.Builder().build(); + + /** + * Instantiates a new Transaction block. + * + * @param queryClient the query client + */ + public TransactionBlock(QueryClient queryClient) { + this.queryClient = queryClient; + this.programmableTransactionBuilder = new ProgrammableTransactionBuilder(); + this.gasBuilder = new GasData.Builder(); + } + + /** + * Sets expiration. + * + * @param epoch the epoch + */ + public void setExpiration(Long epoch) { + if (epoch != null) { + TransactionExpiration.Epoch.Builder builder = new Epoch.Builder(); + builder.value = epoch; + this.transactionExpiration = builder.build(); + } + } + + /** + * Sets sender. + * + * @param sender the sender + */ + public void setSender(String sender) { + List senderBytes = geAddressBytes(sender); + final SuiAddress.Builder senderAddressBuilder = new SuiAddress.Builder(); + senderAddressBuilder.value = senderBytes; + this.sender = senderAddressBuilder.build(); + } + + /** + * Sets gas data. + * + * @param gasPayments the gas payments + * @param owner the owner + * @param gasBudget the gas budget + * @param gasPrice the gas price + * @return the gas data + */ + @SuppressWarnings("unchecked") + public CompletableFuture setGasData( + List gasPayments, String owner, Long gasBudget, Long gasPrice) { + ObjectDataOptions objectDataOptions = new ObjectDataOptions(); + CompletableFuture>[] gasPaymentsFuture = + (CompletableFuture>[]) + gasPayments.stream() + .map( + s -> + queryClient + .getObjectRef(s, objectDataOptions) + .thenApply(TransactionBlock.this::getObjectRef)) + .toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(gasPaymentsFuture) + .thenAccept( + unused -> { + TransactionBlock.this.gasBuilder.payment = + Arrays.stream(gasPaymentsFuture) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + if (StringUtils.isNotEmpty(owner)) { + List ownerBytes = geAddressBytes(owner); + final SuiAddress.Builder ownerAddressBuilder = new SuiAddress.Builder(); + ownerAddressBuilder.value = ownerBytes; + TransactionBlock.this.gasBuilder.owner = ownerAddressBuilder.build(); + } + TransactionBlock.this.gasBuilder.budget = gasBudget; + TransactionBlock.this.gasBuilder.price = gasPrice; + }); + } + + /** + * Build completable future. + * + * @return the completable future + */ + public CompletableFuture build() { + TransactionKind.ProgrammableTransaction.Builder transactionKindBuilder = + new TransactionKind.ProgrammableTransaction.Builder(); + transactionKindBuilder.value = this.programmableTransactionBuilder.build(); + + TransactionDataV1.Builder v1builder = new TransactionDataV1.Builder(); + v1builder.kind = transactionKindBuilder.build(); + v1builder.sender = sender; + v1builder.expiration = transactionExpiration; + + if (this.gasBuilder.owner == null) { + this.gasBuilder.owner = sender; + } + + CompletableFuture gasPriceFuture; + if (this.gasBuilder.price == null) { + gasPriceFuture = queryClient.getReferenceGasPrice(); + } else { + gasPriceFuture = CompletableFuture.completedFuture(this.gasBuilder.price); + } + + CompletableFuture gasBudgetFuture; + if (this.gasBuilder.budget == null) { + // TODO: USE DRYRUN + gasBudgetFuture = CompletableFuture.completedFuture(Long.MAX_VALUE); + } else { + gasBudgetFuture = CompletableFuture.completedFuture(this.gasBuilder.budget); + } + + return CompletableFuture.allOf(gasPriceFuture, gasPriceFuture) + .thenCompose( + (Function>) + unused -> { + List excludeObjects = + programmableTransactionBuilder.getInputs().values().stream() + .flatMap( + (Function>) + callArg -> { + if (callArg instanceof CallArgObjVec) { + return ((CallArgObjVec) callArg).getObjectArgs().stream(); + } else if (callArg instanceof CallArg.Object) { + return Stream.of(((CallArg.Object) callArg).value); + } + + return Stream.empty(); + }) + .map( + (Function>) + objectArg -> { + if (objectArg instanceof SharedObject) { + return Optional.of( + toAddress(((SharedObject) objectArg).id.value.value)); + } + + if (objectArg instanceof ImmOrOwnedObject) { + return Optional.of( + toAddress( + ((ImmOrOwnedObject) objectArg) + .value + .field0 + .value + .value)); + } + + return Optional.empty(); + }) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + Long gasBudget = gasBudgetFuture.join(); + Long gasPrice = gasPriceFuture.join(); + GasData.Builder gasDataBuilder = new GasData.Builder(); + gasDataBuilder.budget = gasBudget; + gasDataBuilder.price = gasPrice; + gasDataBuilder.owner = gasBuilder.owner; + + V1.Builder builder = new V1.Builder(); + if (this.gasBuilder.payment == null || this.gasBuilder.payment.isEmpty()) { + return selectGas( + toAddress(gasBuilder.owner.value), gasBudget, gasPrice, excludeObjects) + .thenApply( + suiObjectRef -> { + Tuple3 gas = + getObjectRef(suiObjectRef); + gasDataBuilder.payment = Lists.newArrayList(gas); + v1builder.gas_data = gasDataBuilder.build(); + builder.value = v1builder.build(); + return builder.build(); + }); + } else { + gasDataBuilder.payment = this.gasBuilder.payment; + v1builder.gas_data = gasDataBuilder.build(); + builder.value = v1builder.build(); + return CompletableFuture.completedFuture(builder.build()); + } + }); + } + + /** + * Make move vec completable future. + * + * @param mutables the mutables + * @param args the args + * @return the completable future + */ + @SuppressWarnings("unchecked") + public CompletableFuture makeMoveVec(List mutables, List args) { + CompletableFuture[] callArgFutures = + (CompletableFuture[]) + Streams.zip(args.stream(), mutables.stream(), this::newObjectArg) + .toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(callArgFutures) + .thenApply( + unused -> { + List objectArgs = + Arrays.stream(callArgFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + return programmableTransactionBuilder.makeObjVec(objectArgs); + }); + } + + /** + * Make move vec argument. + * + * @param objects the objects + * @return the argument + */ + public Argument makeMoveVec(List objects) { + return programmableTransactionBuilder.makeObjVec(objects); + } + + /** + * Split coins completable future. + * + * @param coin the coin + * @param amounts the amounts + * @return the completable future + */ + public CompletableFuture splitCoins(String coin, List amounts) { + if (coin == null) { + return CompletableFuture.completedFuture(splitCoins(amounts)); + } + CompletableFuture> coinFuture = + queryClient.getObjectRef(coin, new ObjectDataOptions()).thenApply(this::getObjectRef); + return coinFuture.thenApply( + objectIDSequenceNumberObjectDigestTuple3 -> + programmableTransactionBuilder.splitCoins(coinFuture.join(), amounts)); + } + + /** + * Split coins argument. + * + * @param amounts the amounts + * @return the argument + */ + public Argument splitCoins(List amounts) { + return programmableTransactionBuilder.splitCoins(amounts); + } + + /** + * Split coins argument. + * + * @param coin the coin + * @param amounts the amounts + * @return the argument + */ + public Argument splitCoins(Argument coin, List amounts) { + return programmableTransactionBuilder.splitCoins(coin, amounts); + } + + /** + * Merge coins argument. + * + * @param destinationCoin the destination coin + * @param sourceCoins the source coins + * @return the argument + */ + public Argument mergeCoins(Argument destinationCoin, List sourceCoins) { + return programmableTransactionBuilder.mergeCoins(destinationCoin, sourceCoins); + } + + /** + * Merge coins completable future. + * + * @param destinationCoin the destination coin + * @param sourceCoins the source coins + * @return the completable future + */ + @SuppressWarnings("unchecked") + public CompletableFuture mergeCoins(String destinationCoin, List sourceCoins) { + ObjectDataOptions objectDataOptions = new ObjectDataOptions(); + CompletableFuture> destinationCoinFuture = + queryClient.getObjectRef(destinationCoin, objectDataOptions).thenApply(this::getObjectRef); + + CompletableFuture>[] sourceCoinsFuture = + (CompletableFuture>[]) + sourceCoins.stream() + .map( + s -> + queryClient + .getObjectRef(s, new ObjectDataOptions()) + .thenApply(TransactionBlock.this::getObjectRef)) + .toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(ArrayUtils.addAll(sourceCoinsFuture, destinationCoinFuture)) + .thenApply( + unused -> { + List> scoins = + Arrays.stream(sourceCoinsFuture) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + Tuple3 dcoin = destinationCoinFuture.join(); + return programmableTransactionBuilder.mergeCoins(dcoin, scoins); + }); + } + + /** + * Transfer objects argument. + * + * @param objects the objects + * @param recipient the recipient + * @return the argument + */ + public Argument transferObjects(List objects, Argument recipient) { + return programmableTransactionBuilder.transferObjects(objects, recipient); + } + + /** + * Transfer objects completable future. + * + * @param suiObjects the sui objects + * @param recipient the recipient + * @return the completable future + */ + @SuppressWarnings("unchecked") + public CompletableFuture transferObjects(List suiObjects, String recipient) { + List recipientBytes = geAddressBytes(recipient); + final SuiAddress.Builder recipientAddressBuilder = new SuiAddress.Builder(); + recipientAddressBuilder.value = recipientBytes; + + CompletableFuture>[] suiObjectsFuture = + (CompletableFuture>[]) + suiObjects.stream() + .map( + s -> + queryClient + .getObjectRef(s, new ObjectDataOptions()) + .thenApply(TransactionBlock.this::getObjectRef)) + .toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(suiObjectsFuture) + .thenApply( + unused -> { + List> objects = + Arrays.stream(suiObjectsFuture) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + return programmableTransactionBuilder.transferObjects( + recipientAddressBuilder.build(), objects); + }); + } + + /** + * MoveCall1 argument. + * + * @param packageObjectId the package object id + * @param module the module + * @param function the function + * @param typeArguments the type arguments + * @param arguments the arguments + * @return the argument + */ + public Argument moveCall1( + String packageObjectId, + String module, + String function, + List typeArguments, + List arguments) { + final List bcsTypeArguments = + typeArguments.stream().map(this::toBcsTypeTag).collect(Collectors.toList()); + Identifier.Builder moduleBuilder = new Identifier.Builder(); + moduleBuilder.value = module; + Identifier.Builder functionBuilder = new Identifier.Builder(); + functionBuilder.value = function; + + AccountAddress.Builder objectAddressBuilder = new AccountAddress.Builder(); + objectAddressBuilder.value = geAddressBytes(packageObjectId); + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = objectAddressBuilder.build(); + + return programmableTransactionBuilder.programmableMoveCall( + objectIdBuilder.build(), + moduleBuilder.build(), + functionBuilder.build(), + bcsTypeArguments, + arguments); + } + + /** + * Move call completable future. + * + * @param packageObjectId the package object id + * @param module the module + * @param function the function + * @param typeArguments the type arguments + * @param arguments the arguments + * @return the completable future + */ + @SuppressWarnings("unchecked") + public CompletableFuture moveCall( + String packageObjectId, + String module, + String function, + List typeArguments, + List arguments) { + List bcsTypeArguments = + typeArguments.stream().map(this::toBcsTypeTag).collect(Collectors.toList()); + return extractNormalizedFunctionParams(packageObjectId, module, function) + .thenCompose( + moveNormalizedTypes -> { + if (moveNormalizedTypes.size() != arguments.size()) { + throw new MoveCallArgSizeNotMatchException( + moveNormalizedTypes.size(), arguments.size()); + } + CompletableFuture[] callArgFutures = + (CompletableFuture[]) + Streams.zip( + moveNormalizedTypes.stream(), + arguments.stream(), + (BiFunction>) + this::toBcsCallArg) + .toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(callArgFutures) + .thenApply( + unused -> { + final List callArgs = + Arrays.stream(callArgFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList()); + + Identifier.Builder moduleBuilder = new Identifier.Builder(); + moduleBuilder.value = module; + Identifier.Builder functionBuilder = new Identifier.Builder(); + functionBuilder.value = function; + + AccountAddress.Builder objectAddressBuilder = new AccountAddress.Builder(); + objectAddressBuilder.value = geAddressBytes(packageObjectId); + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = objectAddressBuilder.build(); + + return programmableTransactionBuilder.moveCall( + objectIdBuilder.build(), + moduleBuilder.build(), + functionBuilder.build(), + bcsTypeArguments, + callArgs); + }); + }); + } + + /** + * Publish argument. + * + * @param compiledModules the compiled modules + * @param depIds the dep ids + * @return the argument + */ + public Argument publish(List compiledModules, List depIds) { + List> modules = + compiledModules.stream() + .map(s -> Arrays.asList(ArrayUtils.toObject(Base64.decode(s)))) + .collect(Collectors.toList()); + List depIdObjects = + depIds != null + ? depIds.stream() + .map( + objectId -> { + AccountAddress.Builder accountAddressBuilder = new AccountAddress.Builder(); + accountAddressBuilder.value = geAddressBytes(objectId); + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = accountAddressBuilder.build(); + return objectIdBuilder.build(); + }) + .collect(Collectors.toList()) + : Lists.newArrayList(); + return programmableTransactionBuilder.publishUpgradeable(modules, depIdObjects); + } + + /** + * Pure argument. + * + * @param value the value + * @return the argument + */ + public Argument pure(Object value) { + return this.programmableTransactionBuilder.pure(value); + } + + @SuppressWarnings("unchecked") + private CompletableFuture selectGas( + String signer, Long budget, Long gasPrice, List excludeObjects) { + final ObjectResponseQuery objectResponseQuery = new ObjectResponseQuery(); + ObjectDataOptions objectDataOptions = new ObjectDataOptions(); + objectDataOptions.setShowPreviousTransaction(true); + objectDataOptions.setShowOwner(true); + objectDataOptions.setShowContent(true); + objectDataOptions.setShowStorageRebate(true); + objectDataOptions.setShowBcs(true); + objectResponseQuery.setOptions(objectDataOptions); + return queryClient + .getObjectsOwnedByAddress(signer, objectResponseQuery, null, null, null) + .thenCompose( + (Function>) + paginatedObjectsResponse -> { + CompletableFuture>[] gases = + (CompletableFuture>[]) + paginatedObjectsResponse.getData().stream() + .map( + objectResponse -> { + if (objectResponse.getError() == null + && objectResponse + .getData() + .getType() + .equals(GAS_COIN_TYPE)) { + GasCoin gasCoin; + try { + gasCoin = + GasCoin.bcsDeserialize( + Base64.decode( + ((SuiRawData.MoveObject) + objectResponse.getData().getBcs()) + .getBcsBytes())); + } catch (DeserializationError e) { + throw new BcsSerializationException(e); + } + final long requiredGasAmount = + BigInteger.valueOf(budget) + .multiply(BigInteger.valueOf(gasPrice)) + .longValue(); + + if (!excludeObjects.contains( + objectResponse.getData().getObjectId()) + && gasCoin.value.balance.value >= requiredGasAmount) { + return CompletableFuture.completedFuture( + Optional.of(objectResponse.getData().getRef())); + } + + return CompletableFuture.completedFuture(Optional.empty()); + } + return CompletableFuture + .>completedFuture(Optional.empty()); + }) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(gases) + .thenApply( + unused -> { + Optional> selected = + Arrays.stream(gases) + .map(CompletableFuture::join) + .filter(Optional::isPresent) + .findFirst(); + + if (!selected.isPresent()) { + throw new GasNotFoundException(); + } + + return selected.get().get(); + }); + }); + } + + private CompletableFuture> extractNormalizedFunctionParams( + String packageObjectId, String module, String function) { + CompletableFuture normalizedFunction = + this.queryClient.getNormalizedMoveFunction(packageObjectId, module, function); + return normalizedFunction.thenCompose( + (Function>>) + moveNormalizedFunction -> { + final boolean hasTxContext = + moveNormalizedFunction.getParameters().size() > 0 + && isTxContext(Iterables.getLast(moveNormalizedFunction.getParameters())); + return CompletableFuture.completedFuture( + hasTxContext + ? moveNormalizedFunction + .getParameters() + .subList(0, moveNormalizedFunction.getParameters().size() - 1) + : moveNormalizedFunction.getParameters()); + }); + } + + private Optional extractStruct(MoveNormalizedType moveNormalizedType) { + if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) moveNormalizedType); + } else if (moveNormalizedType instanceof MoveNormalizedType.ReferenceMoveNormalizedType) { + final MoveNormalizedType refMoveNormalizedType = + ((MoveNormalizedType.ReferenceMoveNormalizedType) moveNormalizedType).getReference(); + if (refMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) refMoveNormalizedType); + } + } else if (moveNormalizedType + instanceof MoveNormalizedType.MutableReferenceMoveNormalizedType) { + final MoveNormalizedType mutableRefMoveNormalizedType = + ((MoveNormalizedType.MutableReferenceMoveNormalizedType) moveNormalizedType) + .getMutableReference(); + if (mutableRefMoveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + return Optional.of((MoveNormalizedStructType) mutableRefMoveNormalizedType); + } + } + + return Optional.empty(); + } + + private boolean isTxContext(MoveNormalizedType moveNormalizedType) { + Optional structTypeOpt = extractStruct(moveNormalizedType); + return structTypeOpt + .filter( + moveNormalizedStructType -> + moveNormalizedStructType.getStruct().getAddress().equals("0x2") + && moveNormalizedStructType.getStruct().getModule().equals("tx_context") + && moveNormalizedStructType.getStruct().getName().equals("TxContext")) + .isPresent(); + } + + @NotNull private Builder getPureBuilder(MoveValue moveValue) { + final Builder pureBuilder = new Builder(); + try { + pureBuilder.value = Arrays.asList(ArrayUtils.toObject(moveValue.bcsSerialize())); + } catch (SerializationError e) { + throw new BcsSerializationException(e); + } + return pureBuilder; + } + + private Optional toPureMoveValue( + MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { + final MoveValue moveValue; + if (moveNormalizedType instanceof MoveNormalizedType.TypeMoveNormalizedType) { + MoveNormalizedType.TypeMoveNormalizedType argType = + (MoveNormalizedType.TypeMoveNormalizedType) moveNormalizedType; + switch (argType) { + case U8: + checkArgType(moveNormalizedType, argVal, Byte.class); + MoveValue.U8.Builder u8Builder = new MoveValue.U8.Builder(); + u8Builder.value = (Byte) argVal; + moveValue = u8Builder.build(); + break; + case U16: + checkArgType(moveNormalizedType, argVal, Short.class); + + MoveValue.U16.Builder u16Builder = new MoveValue.U16.Builder(); + u16Builder.value = (Short) argVal; + moveValue = u16Builder.build(); + break; + case U32: + checkArgType(moveNormalizedType, argVal, Integer.class); + + MoveValue.U32.Builder u32Builder = new MoveValue.U32.Builder(); + u32Builder.value = (Integer) argVal; + moveValue = u32Builder.build(); + break; + case U64: + checkArgType(moveNormalizedType, argVal, Long.class); + + MoveValue.U64.Builder u64Builder = new MoveValue.U64.Builder(); + u64Builder.value = (Long) argVal; + moveValue = u64Builder.build(); + break; + case U128: + checkArgType(moveNormalizedType, argVal, BigInteger.class); + + MoveValue.U128.Builder u128Builder = new MoveValue.U128.Builder(); + u128Builder.value = (BigInteger) argVal; + moveValue = u128Builder.build(); + break; + case U256: + checkArgType(moveNormalizedType, argVal, byte[].class); + + MoveValue.U256.Builder u256Builder = new MoveValue.U256.Builder(); + u256Builder.value = Arrays.asList(ArrayUtils.toObject((byte[]) argVal)); + moveValue = u256Builder.build(); + break; + case Bool: + checkArgType(moveNormalizedType, argVal, Boolean.class); + + MoveValue.Bool.Builder boolBuilder = new Bool.Builder(); + boolBuilder.value = (Boolean) argVal; + moveValue = boolBuilder.build(); + break; + case Address: + checkArgType(moveNormalizedType, argVal, String.class); + + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = geAddressBytes((String) argVal); + MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); + addressValueBuilder.value = addressBuilder.build(); + moveValue = addressValueBuilder.build(); + break; + default: + throw new NotSupportedMoveNormalizedTypeException(); + } + + return Optional.of(moveValue); + } + + if (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedStructType) { + final Struct argStruct = + ((MoveNormalizedType.MoveNormalizedStructType) moveNormalizedType).getStruct(); + if (argStruct.equals(RESOLVED_ASCII_STR)) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream( + ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.US_ASCII))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } else if (argStruct.equals(RESOLVED_UTF8_STR)) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } else if (argStruct.equals(RESOLVED_SUI_ID)) { + checkArgType(moveNormalizedType, argVal, String.class); + + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = geAddressBytes((String) argVal); + MoveValue.Address.Builder addressValueBuilder = new MoveValue.Address.Builder(); + addressValueBuilder.value = addressBuilder.build(); + moveValue = addressValueBuilder.build(); + + return Optional.of(moveValue); + } else if (argStruct.equals(RESOLVED_STD_OPTION)) { + MoveNormalizedType.VectorReferenceMoveNormalizedType optionToVec = + new VectorReferenceMoveNormalizedType(); + optionToVec.setVector(argStruct.getTypeArguments().get(0)); + toPureMoveValue(optionToVec, argVal); + } + } + + if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { + if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) moveNormalizedType).getVector() + == TypeMoveNormalizedType.U8) { + checkArgType(moveNormalizedType, argVal, String.class); + + MoveValue.Vector.Builder vectorBuilder = new MoveValue.Vector.Builder(); + vectorBuilder.value = + Arrays.stream(ArrayUtils.toObject(((String) argVal).getBytes(StandardCharsets.UTF_8))) + .map( + (Function) + b -> { + U8.Builder u8Builder = new U8.Builder(); + u8Builder.value = b; + return u8Builder.build(); + }) + .collect(Collectors.toList()); + moveValue = vectorBuilder.build(); + + return Optional.of(moveValue); + } + + if (!(argVal instanceof List)) { + throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + } + + List objects = (List) argVal; + List pureMoveValues = + objects.stream() + .map( + object -> + toPureMoveValue( + ((MoveNormalizedType.VectorReferenceMoveNormalizedType) + moveNormalizedType) + .getVector(), + object)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + if (pureMoveValues.isEmpty()) { + // ObjVec TYPE will be handled later + return Optional.empty(); + } + + MoveValue.Vector.Builder moveValueVectorBuilder = new Vector.Builder(); + moveValueVectorBuilder.value = pureMoveValues; + + return Optional.of(moveValueVectorBuilder.build()); + } + + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private CompletableFuture toBcsCallArg( + MoveNormalizedType moveNormalizedType, java.lang.Object argVal) { + final Optional pureMoveValue = toPureMoveValue(moveNormalizedType, argVal); + if (pureMoveValue.isPresent()) { + final CallArg.Pure.Builder pureBuilder = getPureBuilder(pureMoveValue.get()); + return CompletableFuture.completedFuture(pureBuilder.build()); + } + + if (moveNormalizedType instanceof MoveNormalizedType.VectorReferenceMoveNormalizedType) { + + if (((MoveNormalizedType.VectorReferenceMoveNormalizedType) moveNormalizedType).getVector() + instanceof MoveNormalizedType.MoveNormalizedStructType) { + checkArgType(moveNormalizedType, argVal, List.class); + + CompletableFuture[] objectArgFutures = + (CompletableFuture[]) + Arrays.stream((String[]) argVal) + .map((String objectId) -> newObjectArg(objectId, moveNormalizedType)) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(objectArgFutures) + .thenApply( + unused -> { + final CallArgObjVec callArgObjVec = new CallArgObjVec(); + callArgObjVec.setObjectArgs( + Arrays.stream(objectArgFutures) + .map(CompletableFuture::join) + .collect(Collectors.toList())); + return callArgObjVec; + }); + } + } + + final Optional structOptional = + extractStruct(moveNormalizedType).map(MoveNormalizedStructType::getStruct); + + if (structOptional.isPresent() + || (moveNormalizedType instanceof MoveNormalizedType.MoveNormalizedTypeParameterType)) { + checkArgType(moveNormalizedType, argVal, String.class); + + return newObjectArg((String) argVal, moveNormalizedType) + .thenApply( + objectArg -> { + final io.sui.bcsgen.CallArg.Object.Builder objectBuilder = + new CallArg.Object.Builder(); + objectBuilder.value = objectArg; + return objectBuilder.build(); + }); + } + + throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + } + + private CompletableFuture newObjectArg(String objectId, boolean mutable) { + ObjectDataOptions queryOptions = new ObjectDataOptions(); + queryOptions.setShowOwner(true); + return queryClient + .getObject(objectId, queryOptions) + .thenApply( + objectResponse -> { + if (objectResponse.getError() != null) { + throw new SuiObjectNotFoundException(); + } + final SuiObjectData objectData = objectResponse.getData(); + final SuiObjectOwner owner = objectData.getOwner(); + if (owner instanceof SuiObjectOwner.SharedOwner) { + AccountAddress.Builder accountAddressBuilder = new AccountAddress.Builder(); + accountAddressBuilder.value = geAddressBytes(objectId); + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = accountAddressBuilder.build(); + SequenceNumber.Builder seqBuilder = new SequenceNumber.Builder(); + seqBuilder.value = + ((SuiObjectOwner.SharedOwner) owner).getShared().getInitial_shared_version(); + SharedObject.Builder sharedObjectBuilder = new SharedObject.Builder(); + sharedObjectBuilder.id = objectIdBuilder.build(); + sharedObjectBuilder.initial_shared_version = seqBuilder.build(); + if (mutable) { + sharedObjectBuilder.mutable = true; + } + + return sharedObjectBuilder.build(); + } + + ImmOrOwnedObject.Builder immOrOwnedObjectBuilder = new ImmOrOwnedObject.Builder(); + immOrOwnedObjectBuilder.value = getObjectRef(objectResponse.getObjectRef()); + return immOrOwnedObjectBuilder.build(); + }); + } + + private CompletableFuture newObjectArg( + String objectId, MoveNormalizedType moveNormalizedType) { + return newObjectArg(objectId, moveNormalizedType instanceof MutableReferenceMoveNormalizedType); + } + + private void checkArgType( + MoveNormalizedType moveNormalizedType, java.lang.Object argVal, Class expectedArgClass) { + if (!expectedArgClass.isInstance(argVal)) { + throw new CallArgTypeMismatchException(moveNormalizedType, argVal.getClass()); + } + } + + /** + * Ge address bytes list. + * + * @param address the address + * @return the list + */ + @NotNull public List geAddressBytes(String address) { + return Arrays.asList( + ArrayUtils.toObject( + Hex.decode(StringUtils.leftPad(StringUtils.removeStart(address, "0x"), 64, "0")))); + } + + /** + * To address string. + * + * @param addressBytes the address bytes + * @return the string + */ + public String toAddress(List addressBytes) { + return StringUtils.prependIfMissing( + Hex.toHexString(ArrayUtils.toPrimitive(addressBytes.toArray(new Byte[0]))), "0x"); + } + + private Tuple3 getObjectRef(SuiObjectRef objRef) { + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = geAddressBytes(objRef.getObjectId()); + + ObjectID.Builder objectIdBuilder = new ObjectID.Builder(); + objectIdBuilder.value = addressBuilder.build(); + + SequenceNumber.Builder sequenceNumberBuilder = new SequenceNumber.Builder(); + sequenceNumberBuilder.value = objRef.getVersion(); + Digest.Builder digestBuilder = new Digest.Builder(); + digestBuilder.value = Bytes.valueOf(Base58.decode(objRef.getDigest())); + ObjectDigest.Builder objectDigestBuilder = new ObjectDigest.Builder(); + objectDigestBuilder.value = digestBuilder.build(); + + return new Tuple3<>( + objectIdBuilder.build(), sequenceNumberBuilder.build(), objectDigestBuilder.build()); + } + + private io.sui.bcsgen.TypeTag toBcsTypeTag(io.sui.models.transactions.TypeTag typeTag) { + if (typeTag instanceof io.sui.models.transactions.TypeTag.SimpleType) { + switch ((io.sui.models.transactions.TypeTag.SimpleType) typeTag) { + case u8: + io.sui.bcsgen.TypeTag.u8.Builder u8builder = new u8.Builder(); + return u8builder.build(); + case u16: + io.sui.bcsgen.TypeTag.u16.Builder u16builder = new u16.Builder(); + return u16builder.build(); + case u32: + io.sui.bcsgen.TypeTag.u32.Builder u32builder = new u32.Builder(); + return u32builder.build(); + case u64: + io.sui.bcsgen.TypeTag.u64.Builder u64builder = new u64.Builder(); + return u64builder.build(); + case bool: + io.sui.bcsgen.TypeTag.bool.Builder boolBuilder = new bool.Builder(); + return boolBuilder.build(); + case u128: + io.sui.bcsgen.TypeTag.u128.Builder u128builder = new u128.Builder(); + return u128builder.build(); + case u256: + io.sui.bcsgen.TypeTag.u256.Builder u256builder = new u256.Builder(); + return u256builder.build(); + case signer: + io.sui.bcsgen.TypeTag.signer.Builder signerBuilder = + new io.sui.bcsgen.TypeTag.signer.Builder(); + return signerBuilder.build(); + case address: + io.sui.bcsgen.TypeTag.address.Builder addressBuilder = + new io.sui.bcsgen.TypeTag.address.Builder(); + return addressBuilder.build(); + default: + throw new NotSupportedTypeTagException(); + } + } else if (typeTag instanceof io.sui.models.transactions.TypeTag.VectorType) { + io.sui.bcsgen.TypeTag.vector.Builder vectorBuilder = + new io.sui.bcsgen.TypeTag.vector.Builder(); + vectorBuilder.value = + toBcsTypeTag(((io.sui.models.transactions.TypeTag.VectorType) typeTag).getTypeTag()); + return vectorBuilder.build(); + } else { + AccountAddress.Builder addressBuilder = new AccountAddress.Builder(); + addressBuilder.value = + geAddressBytes( + ((io.sui.models.transactions.TypeTag.StructType) typeTag) + .getStructTag() + .getAddress()); + Identifier.Builder moduleBuilder = new Identifier.Builder(); + moduleBuilder.value = + ((io.sui.models.transactions.TypeTag.StructType) typeTag).getStructTag().getModule(); + Identifier.Builder nameBuilder = new Identifier.Builder(); + nameBuilder.value = + ((io.sui.models.transactions.TypeTag.StructType) typeTag).getStructTag().getName(); + + StructTag.Builder structTagBuilder = new StructTag.Builder(); + structTagBuilder.address = addressBuilder.build(); + structTagBuilder.module = moduleBuilder.build(); + structTagBuilder.name = nameBuilder.build(); + structTagBuilder.type_args = + ((io.sui.models.transactions.TypeTag.StructType) typeTag) + .getStructTag().getTypeParams().stream() + .map(this::toBcsTypeTag) + .collect(Collectors.toList()); + io.sui.bcsgen.TypeTag.struct.Builder structBuilder = + new io.sui.bcsgen.TypeTag.struct.Builder(); + structBuilder.value = structTagBuilder.build(); + return structBuilder.build(); + } + } } diff --git a/src/main/java/io/sui/clients/TransactionBuilder.java b/src/main/java/io/sui/clients/TransactionBuilder.java index a34949a..99a68fb 100644 --- a/src/main/java/io/sui/clients/TransactionBuilder.java +++ b/src/main/java/io/sui/clients/TransactionBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -87,7 +87,7 @@ CompletableFuture pay( List recipients, List amounts, String gas, - long gasBudget); + Long gasBudget); /** * Pay sui completable future. @@ -104,7 +104,7 @@ CompletableFuture paySui( List inputCoins, List recipients, List amounts, - long gasBudget); + Long gasBudget); /** * Pay all sui completable future. @@ -116,7 +116,7 @@ CompletableFuture paySui( * @return the completable future */ CompletableFuture payAllSui( - String signer, List inputCoins, String recipient, long gasBudget); + String signer, List inputCoins, String recipient, Long gasBudget); /** * Transfer sui completable future. @@ -129,20 +129,20 @@ CompletableFuture payAllSui( * @return the completable future */ CompletableFuture transferSui( - String signer, String coin, long gasBudget, String recipient, long amount); + String signer, String coin, Long gasBudget, String recipient, Long amount); /** * Transfer object completable future. * * @param signer the signer * @param suiObject the sui object + * @param recipient the recipient * @param gas the gas * @param gasBudget the gas budget - * @param recipient the recipient * @return the completable future */ CompletableFuture transferObject( - String signer, String suiObject, String recipient, String gas, long gasBudget); + String signer, String suiObject, String recipient, String gas, Long gasBudget); /** * Batch transaction completable future. @@ -187,10 +187,11 @@ CompletableFuture moveCall( * * @param signer the signer * @param compiledModules the compiled modules + * @param depIds the dep ids * @param gas the gas * @param gasBudget the gas budget * @return the completable future */ CompletableFuture publish( - String signer, List compiledModules, String gas, long gasBudget); + String signer, List compiledModules, List depIds, String gas, Long gasBudget); } diff --git a/src/main/java/io/sui/crypto/AbstractKeyStore.java b/src/main/java/io/sui/crypto/AbstractKeyStore.java index 576bfc2..f072d6e 100644 --- a/src/main/java/io/sui/crypto/AbstractKeyStore.java +++ b/src/main/java/io/sui/crypto/AbstractKeyStore.java @@ -59,6 +59,7 @@ public NavigableSet addresses() { * @return the key response * @throws SignatureSchemeNotSupportedException the signature scheme not supported exception */ + @Override public KeyResponse generateNewKey(SignatureScheme schema) throws SignatureSchemeNotSupportedException { @@ -88,6 +89,7 @@ public KeyResponse generateNewKey(SignatureScheme schema) * @return the string * @throws SignatureSchemeNotSupportedException the signature scheme not supported exception */ + @Override public String importFromMnemonic(String mnemonic, SignatureScheme schema) throws SignatureSchemeNotSupportedException { // todo check mnemonic diff --git a/src/main/java/io/sui/crypto/ED25519KeyPair.java b/src/main/java/io/sui/crypto/ED25519KeyPair.java index 9d50414..af24495 100644 --- a/src/main/java/io/sui/crypto/ED25519KeyPair.java +++ b/src/main/java/io/sui/crypto/ED25519KeyPair.java @@ -25,7 +25,7 @@ import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.signers.Ed25519Signer; -import org.bouncycastle.jcajce.provider.digest.SHA3.Digest256; +import org.bouncycastle.jcajce.provider.digest.Blake2b.Blake2b256; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; @@ -53,13 +53,13 @@ public ED25519KeyPair( @Override public String address() { - final Digest256 digest256 = new Digest256(); + final Blake2b256 blake2b256 = new Blake2b256(); final byte[] hash = - digest256.digest( + blake2b256.digest( Arrays.prepend( ((Ed25519PublicKeyParameters) keyPair.getPublic()).getEncoded(), SignatureScheme.ED25519.getScheme())); - return "0x" + StringUtils.substring(Hex.toHexString(hash), 0, 40); + return "0x" + StringUtils.substring(Hex.toHexString(hash), 0, 64); } @Override diff --git a/src/main/java/io/sui/crypto/KeyResponse.java b/src/main/java/io/sui/crypto/KeyResponse.java index 1b41fff..0537e51 100644 --- a/src/main/java/io/sui/crypto/KeyResponse.java +++ b/src/main/java/io/sui/crypto/KeyResponse.java @@ -16,6 +16,9 @@ package io.sui.crypto; + +import java.util.Objects; + /** * The type Key response. * @@ -55,4 +58,26 @@ public String getMnemonic() { public String getAddress() { return address; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof KeyResponse)) { + return false; + } + KeyResponse that = (KeyResponse) o; + return mnemonic.equals(that.mnemonic) && address.equals(that.address); + } + + @Override + public int hashCode() { + return Objects.hash(mnemonic, address); + } + + @Override + public String toString() { + return "KeyResponse{" + "mnemonic='" + mnemonic + '\'' + ", address='" + address + '\'' + '}'; + } } diff --git a/src/main/java/io/sui/crypto/KeyStore.java b/src/main/java/io/sui/crypto/KeyStore.java index bf6b2ad..ebdfeda 100644 --- a/src/main/java/io/sui/crypto/KeyStore.java +++ b/src/main/java/io/sui/crypto/KeyStore.java @@ -49,4 +49,24 @@ public interface KeyStore { * @param keyPair the keyPair */ void addKey(String address, SuiKeyPair keyPair); + + /** + * Generate new key key response. + * + * @param schema the schema + * @return the key response + * @throws SignatureSchemeNotSupportedException the signature scheme not supported exception + */ + KeyResponse generateNewKey(SignatureScheme schema) throws SignatureSchemeNotSupportedException; + + /** + * Import from mnemonic string. + * + * @param mnemonic the mnemonic + * @param schema the schema + * @return the string + * @throws SignatureSchemeNotSupportedException the signature scheme not supported exception + */ + String importFromMnemonic(String mnemonic, SignatureScheme schema) + throws SignatureSchemeNotSupportedException; } diff --git a/src/main/java/io/sui/crypto/SECP256K1KeyPair.java b/src/main/java/io/sui/crypto/SECP256K1KeyPair.java index f29e1b5..966209f 100644 --- a/src/main/java/io/sui/crypto/SECP256K1KeyPair.java +++ b/src/main/java/io/sui/crypto/SECP256K1KeyPair.java @@ -25,7 +25,7 @@ import org.bitcoinj.core.ECKey.ECDSASignature; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Utils; -import org.bouncycastle.jcajce.provider.digest.SHA3; +import org.bouncycastle.jcajce.provider.digest.Blake2b.Blake2b256; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; @@ -59,10 +59,10 @@ public static SECP256K1KeyPair decodeBase64(byte[] encoded) { @Override public String address() { - SHA3.Digest256 digest256 = new SHA3.Digest256(); + final Blake2b256 blake2b256 = new Blake2b256(); byte[] hash = - digest256.digest(prepend(keyPair.getPubKey(), SignatureScheme.Secp256k1.getScheme())); - return "0x" + StringUtils.substring(Hex.toHexString(hash), 0, 40); + blake2b256.digest(prepend(keyPair.getPubKey(), SignatureScheme.Secp256k1.getScheme())); + return "0x" + StringUtils.substring(Hex.toHexString(hash), 0, 64); } @Override @@ -79,31 +79,13 @@ public SignatureScheme signatureScheme() { public byte[] sign(byte[] msg) throws SigningException { Sha256Hash sha256Hash = Sha256Hash.of(msg); ECDSASignature signature = keyPair.sign(sha256Hash); - byte recId = findRecoveryId(sha256Hash, signature); - byte[] sigData = new byte[65]; // 32 bytes for R + 32 bytes for S + 1 recID + byte[] sigData = new byte[64]; // 32 bytes for R + 32 bytes for S System.arraycopy(Utils.bigIntegerToBytes(signature.r, 32), 0, sigData, 0, 32); System.arraycopy(Utils.bigIntegerToBytes(signature.s, 32), 0, sigData, 32, 32); - sigData[64] = recId; return sigData; } - private byte findRecoveryId(Sha256Hash hash, ECDSASignature sig) throws SigningException { - byte recId = -1; - for (byte i = 0; i < 2; i++) { - ECKey k = ECKey.recoverFromSignature(i, sig, hash, keyPair.isCompressed()); - if (k != null && Arrays.equals(k.getPubKey(), keyPair.getPubKey())) { - recId = i; - break; - } - } - if (recId == -1) { - throw new SigningException( - "Could not construct a recoverable key. This should never happen."); - } - return recId; - } - /** * Encode base 64 sui key. * diff --git a/src/main/java/io/sui/crypto/SignatureSchemeNotSupportedException.java b/src/main/java/io/sui/crypto/SignatureSchemeNotSupportedException.java index 4d57d72..822d291 100644 --- a/src/main/java/io/sui/crypto/SignatureSchemeNotSupportedException.java +++ b/src/main/java/io/sui/crypto/SignatureSchemeNotSupportedException.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -22,7 +22,7 @@ * @author grapebaba * @since 2022.11 */ -public class SignatureSchemeNotSupportedException extends Exception { +public class SignatureSchemeNotSupportedException extends RuntimeException { /** Instantiates a new Signature scheme not supported exception. */ public SignatureSchemeNotSupportedException() { diff --git a/src/main/java/io/sui/jsonrpc/GsonJsonHandler.java b/src/main/java/io/sui/jsonrpc/GsonJsonHandler.java index 8ae2170..d9f9f2e 100644 --- a/src/main/java/io/sui/jsonrpc/GsonJsonHandler.java +++ b/src/main/java/io/sui/jsonrpc/GsonJsonHandler.java @@ -30,12 +30,12 @@ import com.google.gson.JsonSerializer; import com.google.gson.ToNumberPolicy; import com.google.gson.reflect.TypeToken; +import io.sui.models.FaucetResponse; import io.sui.models.events.EventFilter; import io.sui.models.events.EventFilter.PackageEventFilter; import io.sui.models.events.EventKind; import io.sui.models.events.EventQuery; import io.sui.models.events.EventQuery.AllQuery; -import io.sui.models.events.MoveModule; import io.sui.models.objects.CommitteeInfo; import io.sui.models.objects.InputObjectKind; import io.sui.models.objects.InputObjectKind.ImmOrOwnedMoveObjectKind; @@ -44,6 +44,7 @@ import io.sui.models.objects.MoveFunctionArgType; import io.sui.models.objects.MoveFunctionArgType.ObjectValueKindMoveFunctionArgType; import io.sui.models.objects.MoveFunctionArgType.PureFunctionMoveFunctionArgType; +import io.sui.models.objects.MoveModule; import io.sui.models.objects.MoveNormalizedType; import io.sui.models.objects.MoveNormalizedType.MoveNormalizedStructType; import io.sui.models.objects.MoveNormalizedType.MoveNormalizedTypeParameterType; @@ -54,12 +55,12 @@ import io.sui.models.objects.ObjectChange; import io.sui.models.objects.ObjectChange.ObjectChangeType; import io.sui.models.objects.ObjectResponse; -import io.sui.models.objects.ObjectResponse.ObjectIdAndVersionResponseDetails; -import io.sui.models.objects.ObjectResponse.ObjectResponseDetails; -import io.sui.models.objects.SuiData; -import io.sui.models.objects.SuiObject; +import io.sui.models.objects.ObjectStatus; +import io.sui.models.objects.SuiObjectData; import io.sui.models.objects.SuiObjectOwner; import io.sui.models.objects.SuiObjectRef; +import io.sui.models.objects.SuiParsedData; +import io.sui.models.objects.SuiRawData; import io.sui.models.transactions.Argument; import io.sui.models.transactions.Argument.NestedResult; import io.sui.models.transactions.Argument.NestedResultArgument; @@ -87,7 +88,6 @@ import io.sui.models.transactions.ParsedTransactionResponseKind.ParsedPublishResponseKind; import io.sui.models.transactions.ParsedTransactionResponseKind.ParsedSplitCoinResponseKind; import io.sui.models.transactions.TransactionKind; -import io.sui.models.transactions.TransactionQuery; import io.sui.models.transactions.TypeTag; import io.sui.models.transactions.TypeTag.StructType; import io.sui.models.transactions.TypeTag.VectorType; @@ -118,16 +118,34 @@ public JsonRpc20Response.Error.ErrorCode deserialize( } /** The type Sui data deserializer. */ - public class SuiDataDeserializer implements JsonDeserializer { + public class SuiRawDataDeserializer implements JsonDeserializer { @Override - public SuiData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + public SuiRawData deserialize( + JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if ("package".equals(json.getAsJsonObject().get("dataType").getAsString())) { + return gson.fromJson(json, SuiRawData.PackageObject.class); + } + if ("moveObject".equals(json.getAsJsonObject().get("dataType").getAsString())) { + return gson.fromJson(json, SuiRawData.MoveObject.class); + } + return null; + } + } + + /** The type Sui parsed data deserializer. */ + public class SuiParsedDataDeserializer implements JsonDeserializer { + + @Override + public SuiParsedData deserialize( + JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if ("package".equals(json.getAsJsonObject().get("dataType").getAsString())) { - return gson.fromJson(json, SuiData.PackageObject.class); + return gson.fromJson(json, SuiParsedData.PackageObject.class); } if ("moveObject".equals(json.getAsJsonObject().get("dataType").getAsString())) { - return gson.fromJson(json, SuiData.MoveObject.class); + return gson.fromJson(json, SuiParsedData.MoveObject.class); } return null; } @@ -240,36 +258,42 @@ public SuiObjectOwner deserialize( } /** The type Get object response details deserializer. */ - public class GetObjectResponseDetailsDeserializer - implements JsonDeserializer { + public class GetObjectResponseDeserializer implements JsonDeserializer { @Override - public ObjectResponseDetails deserialize( + public ObjectResponse deserialize( JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonObject()) { - if (json.getAsJsonObject().get("data") != null - && !json.getAsJsonObject().get("data").isJsonNull()) { - return gson.fromJson(json, SuiObject.class); - } else if (json.getAsJsonObject().get("asked_version") != null - && !json.getAsJsonObject().get("asked_version").isJsonNull()) { - return gson.fromJson(json, ObjectResponse.ObjectIdHigherVersionResponseDetails.class); - } else { - return gson.fromJson(json, SuiObjectRef.class); + if (json.getAsJsonObject().get("status").getAsString().equals(ObjectStatus.Exists.name())) { + ObjectResponse objectResponse = new ObjectResponse(); + objectResponse.setStatus(ObjectStatus.Exists); + objectResponse.setDetails( + gson.fromJson(json.getAsJsonObject().get("details"), SuiObjectData.class)); + return objectResponse; + } else if (json.getAsJsonObject() + .get("status") + .getAsString() + .equals(ObjectStatus.NotExists.name())) { + ObjectResponse objectResponse = new ObjectResponse(); + objectResponse.setStatus(ObjectStatus.NotExists); + objectResponse.setDetails( + gson.fromJson( + json.getAsJsonObject().get("details"), + ObjectResponse.ObjectIdResponseDetails.class)); + return objectResponse; + } else if (json.getAsJsonObject() + .get("status") + .getAsString() + .equals(ObjectStatus.Deleted.name())) { + ObjectResponse objectResponse = new ObjectResponse(); + objectResponse.setStatus(ObjectStatus.Deleted); + objectResponse.setDetails( + gson.fromJson(json.getAsJsonObject().get("details"), SuiObjectRef.class)); + return objectResponse; } - } else if (json.isJsonArray()) { - final ObjectResponse.ObjectIdAndVersionResponseDetails objectIdAndVersionResponseDetails = - new ObjectIdAndVersionResponseDetails(); - objectIdAndVersionResponseDetails.setObjectId(json.getAsJsonArray().get(0).getAsString()); - objectIdAndVersionResponseDetails.setVersion( - json.getAsJsonArray().get(1) != null ? json.getAsJsonArray().get(1).getAsLong() : null); - return objectIdAndVersionResponseDetails; - } else { - final ObjectResponse.ObjectIdResponseDetails objectIdResponseDetails = - new ObjectResponse.ObjectIdResponseDetails(); - objectIdResponseDetails.setObjectId(json.getAsString()); - return objectIdResponseDetails; } + return null; } } @@ -459,13 +483,13 @@ public ParsedPublishResponse deserialize( JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { ParsedPublishResponse parsedPublishResponse = new ParsedPublishResponse(); - SuiObject updatedGas = - gson.fromJson(json.getAsJsonObject().get("updatedGas"), SuiObject.class); + SuiObjectData updatedGas = + gson.fromJson(json.getAsJsonObject().get("updatedGas"), SuiObjectData.class); parsedPublishResponse.setUpdatedGas(updatedGas); - List createdObjects = + List createdObjects = gson.fromJson( json.getAsJsonObject().get("createdObjects"), - new com.google.common.reflect.TypeToken>() {}.getType()); + new com.google.common.reflect.TypeToken>() {}.getType()); parsedPublishResponse.setCreatedObjects(createdObjects); SuiObjectRef suiPackage = gson.fromJson(json.getAsJsonObject().get("package"), SuiObjectRef.class); @@ -669,20 +693,6 @@ public InputObjectKind deserialize( } } - /** The type Transaction query serializer. */ - public class TransactionQuerySerializer implements JsonSerializer { - - @Override - public JsonElement serialize( - TransactionQuery src, Type typeOfSrc, JsonSerializationContext context) { - if (src instanceof TransactionQuery.AllQuery) { - return new JsonPrimitive(AllQuery.All.name()); - } - - return gson.toJsonTree(src, typeOfSrc); - } - } - /** The type Type tag serializer. */ public static class TypeTagSerializer implements JsonSerializer { @@ -727,9 +737,8 @@ public GsonJsonHandler() { .registerTypeAdapter( JsonRpc20Response.Error.ErrorCode.class, new ErrorCodeDeserializer()) .registerTypeAdapter(SuiObjectOwner.class, new SuiObjectOwnerDeserializer()) - .registerTypeAdapter(SuiData.class, new SuiDataDeserializer()) - .registerTypeAdapter( - ObjectResponseDetails.class, new GetObjectResponseDetailsDeserializer()) + .registerTypeAdapter(SuiRawData.class, new SuiRawDataDeserializer()) + .registerTypeAdapter(ObjectResponse.class, new GetObjectResponseDeserializer()) .registerTypeAdapter(EventKind.class, new EventKindDeserializer()) .registerTypeAdapter(MoveCall.class, new MoveCallDeserializer()) .registerTypeAdapter( @@ -746,7 +755,6 @@ AuthorityQuorumSignInfo.class, new AuthorityQuorumSignInfoDeserializer()) .registerTypeAdapter(CommitteeInfo.class, new CommitteeInfoDeserializer()) .registerTypeAdapter(MoveFunctionArgType.class, new MoveFunctionArgTypeDeserializer()) .registerTypeAdapter(InputObjectKind.class, new InputObjectKindDeserializer()) - .registerTypeAdapter(TransactionQuery.class, new TransactionQuerySerializer()) .registerTypeAdapter(MoveFunction.class, new MoveFunctionSerializer()) .registerTypeAdapter( ExecuteTransactionResponse.class, new ExecuteTransactionResponseDeserializer()) @@ -758,6 +766,7 @@ EventFilter.PackageEventFilter.class, new PackageEventFilterSerializer()) .registerTypeAdapter(Argument.class, new SuiArgumentDeserializer()) .registerTypeAdapter(Command.class, new SuiCommandDeserializer()) .registerTypeAdapter(ObjectChange.class, new ObjectChangeDeserializer()) + .registerTypeAdapter(SuiParsedData.class, new SuiParsedDataDeserializer()) .create(); } @@ -772,6 +781,11 @@ public JsonRpc20WSResponse fromJson(String response) { return this.gson.fromJson(response, JsonRpc20WSResponse.class); } + @Override + public FaucetResponse fromJsonFaucet(String response) { + return this.gson.fromJson(response, FaucetResponse.class); + } + @Override public JsonRpc20Request fromJsonReq(String request) { return this.gson.fromJson(request, JsonRpc20Request.class); @@ -787,13 +801,4 @@ public Map fromJsonMap(String json) { public String toJson(JsonRpc20Request request) { return this.gson.toJson(request); } - - /** - * Gets gson. - * - * @return the gson - */ - public Gson getGson() { - return gson; - } } diff --git a/src/main/java/io/sui/jsonrpc/JsonHandler.java b/src/main/java/io/sui/jsonrpc/JsonHandler.java index 2151877..3e7a0b8 100644 --- a/src/main/java/io/sui/jsonrpc/JsonHandler.java +++ b/src/main/java/io/sui/jsonrpc/JsonHandler.java @@ -17,6 +17,7 @@ package io.sui.jsonrpc; +import io.sui.models.FaucetResponse; import java.lang.reflect.Type; import java.util.Map; @@ -46,6 +47,14 @@ public interface JsonHandler { */ JsonRpc20WSResponse fromJson(String response); + /** + * From json faucet faucet response. + * + * @param response the response + * @return the faucet response + */ + FaucetResponse fromJsonFaucet(String response); + /** * From json general map. * diff --git a/src/main/java/io/sui/models/FaucetCoinInfo.java b/src/main/java/io/sui/models/FaucetCoinInfo.java index b26c752..c67c6dd 100644 --- a/src/main/java/io/sui/models/FaucetCoinInfo.java +++ b/src/main/java/io/sui/models/FaucetCoinInfo.java @@ -1,7 +1,122 @@ -package io.sui.models;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/11 - * Time: 15:51 - */public class FaucetCoinInfo { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models; + + +import java.util.Objects; + +/** + * The type Faucet coin info. + * + * @author grapebaba + * @since 2023.04 + */ +public class FaucetCoinInfo { + + private Long amount; + + private String id; + + private String transferTxDigest; + + /** + * Gets amount. + * + * @return the amount + */ + public Long getAmount() { + return amount; + } + + /** + * Sets amount. + * + * @param amount the amount + */ + public void setAmount(Long amount) { + this.amount = amount; + } + + /** + * Gets id. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets id. + * + * @param id the id + */ + public void setId(String id) { + this.id = id; + } + + /** + * Gets transfer tx digest. + * + * @return the transfer tx digest + */ + public String getTransferTxDigest() { + return transferTxDigest; + } + + /** + * Sets transfer tx digest. + * + * @param transferTxDigest the transfer tx digest + */ + public void setTransferTxDigest(String transferTxDigest) { + this.transferTxDigest = transferTxDigest; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FaucetCoinInfo)) { + return false; + } + FaucetCoinInfo that = (FaucetCoinInfo) o; + return amount.equals(that.amount) + && id.equals(that.id) + && transferTxDigest.equals(that.transferTxDigest); + } + + @Override + public int hashCode() { + return Objects.hash(amount, id, transferTxDigest); + } + + @Override + public String toString() { + return "FaucetCoinInfo{" + + "amount=" + + amount + + ", id='" + + id + + '\'' + + ", transferTxDigest='" + + transferTxDigest + + '\'' + + '}'; + } } diff --git a/src/main/java/io/sui/models/FaucetResponse.java b/src/main/java/io/sui/models/FaucetResponse.java index 6388b9b..76057a1 100644 --- a/src/main/java/io/sui/models/FaucetResponse.java +++ b/src/main/java/io/sui/models/FaucetResponse.java @@ -1,7 +1,98 @@ -package io.sui.models;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/11 - * Time: 15:56 - */public class FaucetResponse { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models; + + +import java.util.List; +import java.util.Objects; + +/** + * The type Faucet response. + * + * @author grapebaba + * @since 2023.04 + */ +public class FaucetResponse { + + private List transferredGasObjects; + + private String error; + + /** + * Gets transferred gas objects. + * + * @return the transferred gas objects + */ + public List getTransferredGasObjects() { + return transferredGasObjects; + } + + /** + * Sets transferred gas objects. + * + * @param transferredGasObjects the transferred gas objects + */ + public void setTransferredGasObjects(List transferredGasObjects) { + this.transferredGasObjects = transferredGasObjects; + } + + /** + * Gets error. + * + * @return the error + */ + public String getError() { + return error; + } + + /** + * Sets error. + * + * @param error the error + */ + public void setError(String error) { + this.error = error; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FaucetResponse)) { + return false; + } + FaucetResponse that = (FaucetResponse) o; + return transferredGasObjects.equals(that.transferredGasObjects) && error.equals(that.error); + } + + @Override + public int hashCode() { + return Objects.hash(transferredGasObjects, error); + } + + @Override + public String toString() { + return "FaucetResponse{" + + "transferredGasObjects=" + + transferredGasObjects + + ", error='" + + error + + '\'' + + '}'; + } } diff --git a/src/main/java/io/sui/models/events/EventQuery.java b/src/main/java/io/sui/models/events/EventQuery.java index 38929db..f129504 100644 --- a/src/main/java/io/sui/models/events/EventQuery.java +++ b/src/main/java/io/sui/models/events/EventQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -17,6 +17,7 @@ package io.sui.models.events; +import io.sui.models.objects.MoveModule; import io.sui.models.objects.SuiObjectOwner; import java.util.Objects; @@ -92,7 +93,7 @@ class MoveModuleEventQuery implements EventQuery { * * @return the move module */ - public io.sui.models.events.MoveModule getMoveModule() { + public io.sui.models.objects.MoveModule getMoveModule() { return MoveModule; } @@ -101,7 +102,7 @@ public io.sui.models.events.MoveModule getMoveModule() { * * @param moveModule the move module */ - public void setMoveModule(io.sui.models.events.MoveModule moveModule) { + public void setMoveModule(io.sui.models.objects.MoveModule moveModule) { MoveModule = moveModule; } diff --git a/src/main/java/io/sui/models/objects/CheckpointedObjectId.java b/src/main/java/io/sui/models/objects/CheckpointedObjectId.java index e4997c4..c6ad869 100644 --- a/src/main/java/io/sui/models/objects/CheckpointedObjectId.java +++ b/src/main/java/io/sui/models/objects/CheckpointedObjectId.java @@ -1,7 +1,97 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/8 - * Time: 11:23 - */public class CheckpointedObjectId { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Objects; + +/** + * The type Checkpointed object id. + * + * @author grapebaba + * @since 2023.04 + */ +public class CheckpointedObjectId { + + private String objectId; + + private Long atCheckpoint; + + /** + * Gets object id. + * + * @return the object id + */ + public String getObjectId() { + return objectId; + } + + /** + * Sets object id. + * + * @param objectId the object id + */ + public void setObjectId(String objectId) { + this.objectId = objectId; + } + + /** + * Gets at checkpoint. + * + * @return the at checkpoint + */ + public Long getAtCheckpoint() { + return atCheckpoint; + } + + /** + * Sets at checkpoint. + * + * @param atCheckpoint the at checkpoint + */ + public void setAtCheckpoint(Long atCheckpoint) { + this.atCheckpoint = atCheckpoint; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CheckpointedObjectId)) { + return false; + } + CheckpointedObjectId that = (CheckpointedObjectId) o; + return objectId.equals(that.objectId) && atCheckpoint.equals(that.atCheckpoint); + } + + @Override + public int hashCode() { + return Objects.hash(objectId, atCheckpoint); + } + + @Override + public String toString() { + return "CheckpointedObjectId{" + + "objectId='" + + objectId + + '\'' + + ", atCheckpoint=" + + atCheckpoint + + '}'; + } } diff --git a/src/main/java/io/sui/models/objects/MoveModule.java b/src/main/java/io/sui/models/objects/MoveModule.java index 197daab..fc25836 100644 --- a/src/main/java/io/sui/models/objects/MoveModule.java +++ b/src/main/java/io/sui/models/objects/MoveModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -14,7 +14,7 @@ * specific language governing permissions and limitations under the License. */ -package io.sui.models.events; +package io.sui.models.objects; import java.util.Objects; diff --git a/src/main/java/io/sui/models/objects/MoveNormalizedType.java b/src/main/java/io/sui/models/objects/MoveNormalizedType.java index c474f3b..2633218 100644 --- a/src/main/java/io/sui/models/objects/MoveNormalizedType.java +++ b/src/main/java/io/sui/models/objects/MoveNormalizedType.java @@ -250,8 +250,7 @@ public static class Struct { private String name; - @SuppressWarnings("checkstyle:MemberName") - private List type_arguments; + private List typeArguments; /** * Gets address. @@ -312,18 +311,18 @@ public void setName(String name) { * * @return the type arguments */ - public List getType_arguments() { - return type_arguments; + public List getTypeArguments() { + return typeArguments; } /** * Sets type arguments. * - * @param type_arguments the type arguments + * @param typeArguments the type arguments */ @SuppressWarnings("checkstyle:ParameterName") - public void setType_arguments(List type_arguments) { - this.type_arguments = type_arguments; + public void setTypeArguments(List typeArguments) { + this.typeArguments = typeArguments; } @Override @@ -358,7 +357,7 @@ public String toString() { + name + '\'' + ", type_arguments=" - + type_arguments + + typeArguments + '}'; } } diff --git a/src/main/java/io/sui/models/objects/ObjectDataFilter.java b/src/main/java/io/sui/models/objects/ObjectDataFilter.java index 1fe7308..f48f93f 100644 --- a/src/main/java/io/sui/models/objects/ObjectDataFilter.java +++ b/src/main/java/io/sui/models/objects/ObjectDataFilter.java @@ -1,7 +1,171 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/20 - * Time: 16:12 - */public class ObjectDataFilter { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Objects; + +/** + * The type Object data filter. + * + * @author grapebaba + * @since 2023.03 + */ +public abstract class ObjectDataFilter { + + /** The type Package filter. */ + public static class PackageFilter extends ObjectDataFilter { + + @SuppressWarnings("checkstyle:MemberName") + private String Package; + + /** + * Gets package. + * + * @return the package + */ + public String getPackage() { + return Package; + } + + /** + * Sets package. + * + * @param aPackage the a package + */ + @SuppressWarnings("checkstyle:ParameterName") + public void setPackage(String aPackage) { + Package = aPackage; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PackageFilter)) { + return false; + } + PackageFilter that = (PackageFilter) o; + return Package.equals(that.Package); + } + + @Override + public int hashCode() { + return Objects.hash(Package); + } + + @Override + public String toString() { + return "PackageFilter{" + "Package='" + Package + '\'' + '}'; + } + } + + /** The type Move module filter. */ + public static class MoveModuleFilter extends ObjectDataFilter { + + @SuppressWarnings("checkstyle:MemberName") + private MoveModule MoveModule; + + /** + * Gets move module. + * + * @return the move module + */ + public io.sui.models.objects.MoveModule getMoveModule() { + return MoveModule; + } + + /** + * Sets move module. + * + * @param moveModule the move module + */ + public void setMoveModule(io.sui.models.objects.MoveModule moveModule) { + MoveModule = moveModule; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MoveModuleFilter)) { + return false; + } + MoveModuleFilter that = (MoveModuleFilter) o; + return MoveModule.equals(that.MoveModule); + } + + @Override + public int hashCode() { + return Objects.hash(MoveModule); + } + + @Override + public String toString() { + return "MoveModuleFilter{" + "MoveModule=" + MoveModule + '}'; + } + } + + /** The type Struct type filter. */ + public static class StructTypeFilter extends ObjectDataFilter { + + @SuppressWarnings("checkstyle:MemberName") + private String StructType; + + /** + * Gets struct type. + * + * @return the struct type + */ + public String getStructType() { + return StructType; + } + + /** + * Sets struct type. + * + * @param structType the struct type + */ + public void setStructType(String structType) { + StructType = structType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof StructTypeFilter)) { + return false; + } + StructTypeFilter that = (StructTypeFilter) o; + return StructType.equals(that.StructType); + } + + @Override + public int hashCode() { + return Objects.hash(StructType); + } + + @Override + public String toString() { + return "StructTypeFilter{" + "StructType='" + StructType + '\'' + '}'; + } + } } diff --git a/src/main/java/io/sui/models/objects/ObjectDataOptions.java b/src/main/java/io/sui/models/objects/ObjectDataOptions.java index 563d363..38fada4 100644 --- a/src/main/java/io/sui/models/objects/ObjectDataOptions.java +++ b/src/main/java/io/sui/models/objects/ObjectDataOptions.java @@ -1,7 +1,219 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/19 - * Time: 17:32 - */public class ObjectDataOptions { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Objects; + +/** + * The type Object data options. + * + * @author grapebaba + * @since 2023.03 + */ +public class ObjectDataOptions { + + private boolean showType = true; + + private boolean showContent; + + private boolean showBcs; + + private boolean showOwner; + + private boolean showPreviousTransaction; + + private boolean showStorageRebate; + + private boolean showDisplay; + + /** + * Is show type boolean. + * + * @return the boolean + */ + public boolean isShowType() { + return showType; + } + + /** + * Sets show type. + * + * @param showType the show type + */ + public void setShowType(boolean showType) { + this.showType = showType; + } + + /** + * Is show content boolean. + * + * @return the boolean + */ + public boolean isShowContent() { + return showContent; + } + + /** + * Sets show content. + * + * @param showContent the show content + */ + public void setShowContent(boolean showContent) { + this.showContent = showContent; + } + + /** + * Is show bcs boolean. + * + * @return the boolean + */ + public boolean isShowBcs() { + return showBcs; + } + + /** + * Sets show bcs. + * + * @param showBcs the show bcs + */ + public void setShowBcs(boolean showBcs) { + this.showBcs = showBcs; + } + + /** + * Is show owner boolean. + * + * @return the boolean + */ + public boolean isShowOwner() { + return showOwner; + } + + /** + * Sets show owner. + * + * @param showOwner the show owner + */ + public void setShowOwner(boolean showOwner) { + this.showOwner = showOwner; + } + + /** + * Is show previous transaction boolean. + * + * @return the boolean + */ + public boolean isShowPreviousTransaction() { + return showPreviousTransaction; + } + + /** + * Sets show previous transaction. + * + * @param showPreviousTransaction the show previous transaction + */ + public void setShowPreviousTransaction(boolean showPreviousTransaction) { + this.showPreviousTransaction = showPreviousTransaction; + } + + /** + * Is show storage rebate boolean. + * + * @return the boolean + */ + public boolean isShowStorageRebate() { + return showStorageRebate; + } + + /** + * Sets show storage rebate. + * + * @param showStorageRebate the show storage rebate + */ + public void setShowStorageRebate(boolean showStorageRebate) { + this.showStorageRebate = showStorageRebate; + } + + /** + * Is show display boolean. + * + * @return the boolean + */ + public boolean isShowDisplay() { + return showDisplay; + } + + /** + * Sets show display. + * + * @param showDisplay the show display + */ + public void setShowDisplay(boolean showDisplay) { + this.showDisplay = showDisplay; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ObjectDataOptions)) { + return false; + } + ObjectDataOptions that = (ObjectDataOptions) o; + return showType == that.showType + && showContent == that.showContent + && showBcs == that.showBcs + && showOwner == that.showOwner + && showPreviousTransaction == that.showPreviousTransaction + && showStorageRebate == that.showStorageRebate + && showDisplay == that.showDisplay; + } + + @Override + public int hashCode() { + return Objects.hash( + showType, + showContent, + showBcs, + showOwner, + showPreviousTransaction, + showStorageRebate, + showDisplay); + } + + @Override + public String toString() { + return "ObjectDataOptions{" + + "showType=" + + showType + + ", showContent=" + + showContent + + ", showBcs=" + + showBcs + + ", showOwner=" + + showOwner + + ", showPreviousTransaction=" + + showPreviousTransaction + + ", showStorageRebate=" + + showStorageRebate + + ", showDisplay=" + + showDisplay + + '}'; + } } diff --git a/src/main/java/io/sui/models/objects/ObjectResponse.java b/src/main/java/io/sui/models/objects/ObjectResponse.java index e03cf8d..a58ea4f 100644 --- a/src/main/java/io/sui/models/objects/ObjectResponse.java +++ b/src/main/java/io/sui/models/objects/ObjectResponse.java @@ -79,180 +79,6 @@ public String toString() { } } - /** The type Object id and version response details. */ - public static class ObjectIdAndVersionResponseDetails implements ObjectResponseDetails { - - private String objectId; - - private Long version; - - /** - * Gets object id. - * - * @return the object id - */ - public String getObjectId() { - return objectId; - } - - /** - * Sets object id. - * - * @param objectId the object id - */ - public void setObjectId(String objectId) { - this.objectId = objectId; - } - - /** - * Gets version. - * - * @return the version - */ - public Long getVersion() { - return version; - } - - /** - * Sets version. - * - * @param version the version - */ - public void setVersion(Long version) { - this.version = version; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ObjectIdAndVersionResponseDetails)) { - return false; - } - ObjectIdAndVersionResponseDetails that = (ObjectIdAndVersionResponseDetails) o; - return objectId.equals(that.objectId) && version.equals(that.version); - } - - @Override - public int hashCode() { - return Objects.hash(objectId, version); - } - - @Override - public String toString() { - return "ObjectIdAndVersionResponseDetails{" - + "objectId='" - + objectId - + '\'' - + ", version=" - + version - + '}'; - } - } - - /** The type Object id higher version response details. */ - public static class ObjectIdHigherVersionResponseDetails implements ObjectResponseDetails { - - @SuppressWarnings("checkstyle:MemberName") - private String object_id; - - @SuppressWarnings("checkstyle:MemberName") - private Long asked_version; - - @SuppressWarnings("checkstyle:MemberName") - private Long latest_version; - - /** - * Gets object id. - * - * @return the object id - */ - public String getObject_id() { - return object_id; - } - - /** - * Sets object id. - * - * @param object_id the object id - */ - @SuppressWarnings("checkstyle:ParameterName") - public void setObject_id(String object_id) { - this.object_id = object_id; - } - - /** - * Gets asked version. - * - * @return the asked version - */ - public Long getAsked_version() { - return asked_version; - } - - /** - * Sets asked version. - * - * @param asked_version the asked version - */ - @SuppressWarnings("checkstyle:ParameterName") - public void setAsked_version(Long asked_version) { - this.asked_version = asked_version; - } - - /** - * Gets latest version. - * - * @return the latest version - */ - public Long getLatest_version() { - return latest_version; - } - - /** - * Sets latest version. - * - * @param latest_version the latest version - */ - @SuppressWarnings("checkstyle:ParameterName") - public void setLatest_version(Long latest_version) { - this.latest_version = latest_version; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ObjectIdHigherVersionResponseDetails)) { - return false; - } - ObjectIdHigherVersionResponseDetails that = (ObjectIdHigherVersionResponseDetails) o; - return object_id.equals(that.object_id) - && asked_version.equals(that.asked_version) - && latest_version.equals(that.latest_version); - } - - @Override - public int hashCode() { - return Objects.hash(object_id, asked_version, latest_version); - } - - @Override - public String toString() { - return "ObjectIdHigherVersionResponseDetails{" - + "object_id='" - + object_id - + '\'' - + ", asked_version=" - + asked_version - + ", latest_version=" - + latest_version - + '}'; - } - } - private ObjectStatus status; private ObjectResponseDetails details; @@ -322,7 +148,7 @@ public String toString() { */ public SuiObjectRef getObjectRef() { if (Exists == this.getStatus()) { - return ((SuiObject) this.getDetails()).getReference(); + return ((SuiObjectData) this.getDetails()).getRef(); } else if (Deleted == this.getStatus()) { return (SuiObjectRef) this.getDetails(); } diff --git a/src/main/java/io/sui/models/objects/ObjectResponseQuery.java b/src/main/java/io/sui/models/objects/ObjectResponseQuery.java index 97f0ad8..ca72415 100644 --- a/src/main/java/io/sui/models/objects/ObjectResponseQuery.java +++ b/src/main/java/io/sui/models/objects/ObjectResponseQuery.java @@ -1,7 +1,91 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/20 - * Time: 16:10 - */public class ObjectResponseQuery { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Objects; + +/** + * The type Object response query. + * + * @author grapebaba + * @since 2023.03 + */ +public class ObjectResponseQuery { + + private ObjectDataOptions options; + + private ObjectDataFilter filter; + + /** + * Gets options. + * + * @return the options + */ + public ObjectDataOptions getOptions() { + return options; + } + + /** + * Sets options. + * + * @param options the options + */ + public void setOptions(ObjectDataOptions options) { + this.options = options; + } + + /** + * Gets filter. + * + * @return the filter + */ + public ObjectDataFilter getFilter() { + return filter; + } + + /** + * Sets filter. + * + * @param filter the filter + */ + public void setFilter(ObjectDataFilter filter) { + this.filter = filter; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ObjectResponseQuery)) { + return false; + } + ObjectResponseQuery that = (ObjectResponseQuery) o; + return options.equals(that.options) && filter.equals(that.filter); + } + + @Override + public int hashCode() { + return Objects.hash(options, filter); + } + + @Override + public String toString() { + return "ObjectResponseQuery{" + "options=" + options + ", filter=" + filter + '}'; + } } diff --git a/src/main/java/io/sui/models/objects/PaginatedObjectsResponse.java b/src/main/java/io/sui/models/objects/PaginatedObjectsResponse.java index 5849a79..6c00a1e 100644 --- a/src/main/java/io/sui/models/objects/PaginatedObjectsResponse.java +++ b/src/main/java/io/sui/models/objects/PaginatedObjectsResponse.java @@ -1,7 +1,122 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/20 - * Time: 16:31 - */public class PaginatedObjectsResponse { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.List; +import java.util.Objects; + +/** + * The type Paginated objects response. + * + * @author grapebaba + * @since 2023.03 + */ +public class PaginatedObjectsResponse { + + private List data; + + private CheckpointedObjectId nextCursor; + + private boolean hasNextPage; + + /** + * Gets data. + * + * @return the data + */ + public List getData() { + return data; + } + + /** + * Sets data. + * + * @param data the data + */ + public void setData(List data) { + this.data = data; + } + + /** + * Gets next cursor. + * + * @return the next cursor + */ + public CheckpointedObjectId getNextCursor() { + return nextCursor; + } + + /** + * Sets next cursor. + * + * @param nextCursor the next cursor + */ + public void setNextCursor(CheckpointedObjectId nextCursor) { + this.nextCursor = nextCursor; + } + + /** + * Is has next page boolean. + * + * @return the boolean + */ + public boolean isHasNextPage() { + return hasNextPage; + } + + /** + * Sets has next page. + * + * @param hasNextPage the has next page + */ + public void setHasNextPage(boolean hasNextPage) { + this.hasNextPage = hasNextPage; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PaginatedObjectsResponse)) { + return false; + } + PaginatedObjectsResponse that = (PaginatedObjectsResponse) o; + return hasNextPage == that.hasNextPage + && data.equals(that.data) + && nextCursor.equals(that.nextCursor); + } + + @Override + public int hashCode() { + return Objects.hash(data, nextCursor, hasNextPage); + } + + @Override + public String toString() { + return "PaginatedObjectsResponse{" + + "data=" + + data + + ", nextCursor='" + + nextCursor + + '\'' + + ", hasNextPage=" + + hasNextPage + + '}'; + } } diff --git a/src/main/java/io/sui/models/objects/SuiObjectData.java b/src/main/java/io/sui/models/objects/SuiObjectData.java index b2cc4ff..d5a64b1 100644 --- a/src/main/java/io/sui/models/objects/SuiObjectData.java +++ b/src/main/java/io/sui/models/objects/SuiObjectData.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -18,6 +18,7 @@ import io.sui.models.objects.ObjectResponse.ObjectResponseDetails; +import java.util.Map; import java.util.Objects; /** @@ -26,7 +27,7 @@ * @author grapebaba * @since 2022.11 */ -public class SuiObject implements ObjectResponseDetails { +public class SuiObjectData implements ObjectResponseDetails { private String objectId; @@ -36,30 +37,124 @@ public class SuiObject implements ObjectResponseDetails { private String type; + private SuiParsedData content; + + private SuiRawData bcs; + private SuiObjectOwner owner; private String previousTransaction; private Long storageRebate; - private SuiObjectRef reference; + private Map display; + + /** + * Gets object id. + * + * @return the object id + */ + public String getObjectId() { + return objectId; + } + + /** + * Sets object id. + * + * @param objectId the object id + */ + public void setObjectId(String objectId) { + this.objectId = objectId; + } + + /** + * Gets version. + * + * @return the version + */ + public Long getVersion() { + return version; + } + + /** + * Sets version. + * + * @param version the version + */ + public void setVersion(Long version) { + this.version = version; + } + + /** + * Gets digest. + * + * @return the digest + */ + public String getDigest() { + return digest; + } + + /** + * Sets digest. + * + * @param digest the digest + */ + public void setDigest(String digest) { + this.digest = digest; + } + + /** + * Gets type. + * + * @return the type + */ + public String getType() { + return type; + } + + /** + * Sets type. + * + * @param type the type + */ + public void setType(String type) { + this.type = type; + } + + /** + * Gets content. + * + * @return the content + */ + public SuiParsedData getContent() { + return content; + } + + /** + * Sets content. + * + * @param content the content + */ + public void setContent(SuiParsedData content) { + this.content = content; + } /** - * Gets data. + * Gets bcs. * - * @return the data + * @return the bcs */ - public SuiRawData getData() { - return data; + public SuiRawData getBcs() { + return bcs; } /** - * Sets data. + * Sets bcs. * - * @param data the data + * @param bcs the bcs */ - public void setData(SuiRawData data) { - this.data = data; + public void setBcs(SuiRawData bcs) { + this.bcs = bcs; } /** @@ -117,21 +212,21 @@ public void setStorageRebate(Long storageRebate) { } /** - * Gets reference. + * Gets display. * - * @return the reference + * @return the display */ - public SuiObjectRef getReference() { - return reference; + public Map getDisplay() { + return display; } /** - * Sets reference. + * Sets display. * - * @param reference the reference + * @param display the display */ - public void setReference(SuiObjectRef reference) { - this.reference = reference; + public void setDisplay(Map display) { + this.display = display; } @Override @@ -139,27 +234,55 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o == null || getClass() != o.getClass()) { + if (!(o instanceof SuiObjectData)) { return false; } - SuiObject suiObject = (SuiObject) o; - return data.equals(suiObject.data) - && owner.equals(suiObject.owner) - && previousTransaction.equals(suiObject.previousTransaction) - && storageRebate.equals(suiObject.storageRebate) - && reference.equals(suiObject.reference); + SuiObjectData that = (SuiObjectData) o; + return objectId.equals(that.objectId) + && version.equals(that.version) + && digest.equals(that.digest) + && type.equals(that.type) + && content.equals(that.content) + && bcs.equals(that.bcs) + && owner.equals(that.owner) + && previousTransaction.equals(that.previousTransaction) + && storageRebate.equals(that.storageRebate) + && display.equals(that.display); } @Override public int hashCode() { - return Objects.hash(data, owner, previousTransaction, storageRebate, reference); + return Objects.hash( + objectId, + version, + digest, + type, + content, + bcs, + owner, + previousTransaction, + storageRebate, + display); } @Override public String toString() { - return "SuiObject{" - + "data=" - + data + return "SuiObjectData{" + + "objectId='" + + objectId + + '\'' + + ", version=" + + version + + ", digest='" + + digest + + '\'' + + ", type='" + + type + + '\'' + + ", content=" + + content + + ", bcs=" + + bcs + ", owner=" + owner + ", previousTransaction='" @@ -167,8 +290,21 @@ public String toString() { + '\'' + ", storageRebate=" + storageRebate - + ", reference=" - + reference + + ", display=" + + display + '}'; } + + /** + * Gets ref. + * + * @return the ref + */ + public SuiObjectRef getRef() { + SuiObjectRef suiObjectRef = new SuiObjectRef(); + suiObjectRef.setObjectId(this.objectId); + suiObjectRef.setDigest(this.digest); + suiObjectRef.setVersion(this.version); + return suiObjectRef; + } } diff --git a/src/main/java/io/sui/models/objects/SuiObjectResponse.java b/src/main/java/io/sui/models/objects/SuiObjectResponse.java index e747541..80a57b0 100644 --- a/src/main/java/io/sui/models/objects/SuiObjectResponse.java +++ b/src/main/java/io/sui/models/objects/SuiObjectResponse.java @@ -1,7 +1,104 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/7 - * Time: 20:34 - */public class SuiObjectResponse { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import io.sui.clients.SuiObjectNotFoundException; +import java.util.Objects; + +/** + * The type Sui object response. + * + * @author grapebaba + * @since 2023.04 + */ +public class SuiObjectResponse { + + private SuiObjectData data; + + private SuiObjectResponseError error; + + /** + * Gets data. + * + * @return the data + */ + public SuiObjectData getData() { + return data; + } + + /** + * Sets data. + * + * @param data the data + */ + public void setData(SuiObjectData data) { + this.data = data; + } + + /** + * Gets error. + * + * @return the error + */ + public SuiObjectResponseError getError() { + return error; + } + + /** + * Sets error. + * + * @param error the error + */ + public void setError(SuiObjectResponseError error) { + this.error = error; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SuiObjectResponse)) { + return false; + } + SuiObjectResponse that = (SuiObjectResponse) o; + return data.equals(that.data) && error.equals(that.error); + } + + @Override + public int hashCode() { + return Objects.hash(data, error); + } + + @Override + public String toString() { + return "SuiObjectResponse{" + "data=" + data + ", error=" + error + '}'; + } + + /** + * Gets object ref. + * + * @return the object ref + */ + public SuiObjectRef getObjectRef() { + if (this.error != null) { + throw new SuiObjectNotFoundException(); + } + return this.getData().getRef(); + } } diff --git a/src/main/java/io/sui/models/objects/SuiObjectResponseError.java b/src/main/java/io/sui/models/objects/SuiObjectResponseError.java index eab02c8..6e1375d 100644 --- a/src/main/java/io/sui/models/objects/SuiObjectResponseError.java +++ b/src/main/java/io/sui/models/objects/SuiObjectResponseError.java @@ -1,7 +1,148 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/7 - * Time: 20:26 - */public class SuiObjectResponseError { +/* + * Copyright 2022-2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Objects; + +/** + * The type Sui object response error. + * + * @author grapebaba + * @since 2023.04 + */ +public class SuiObjectResponseError { + + private String tag; + + @SuppressWarnings("checkstyle:MemberName") + private String object_id; + + private Long version; + + private String digest; + + /** + * Gets tag. + * + * @return the tag + */ + public String getTag() { + return tag; + } + + /** + * Sets tag. + * + * @param tag the tag + */ + public void setTag(String tag) { + this.tag = tag; + } + + /** + * Gets object id. + * + * @return the object id + */ + public String getObject_id() { + return object_id; + } + + /** + * Sets object id. + * + * @param object_id the object id + */ + @SuppressWarnings("checkstyle:ParameterName") + public void setObject_id(String object_id) { + this.object_id = object_id; + } + + /** + * Gets version. + * + * @return the version + */ + public Long getVersion() { + return version; + } + + /** + * Sets version. + * + * @param version the version + */ + public void setVersion(Long version) { + this.version = version; + } + + /** + * Gets digest. + * + * @return the digest + */ + public String getDigest() { + return digest; + } + + /** + * Sets digest. + * + * @param digest the digest + */ + public void setDigest(String digest) { + this.digest = digest; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SuiObjectResponseError)) { + return false; + } + SuiObjectResponseError that = (SuiObjectResponseError) o; + return tag.equals(that.tag) + && object_id.equals(that.object_id) + && version.equals(that.version) + && digest.equals(that.digest); + } + + @Override + public int hashCode() { + return Objects.hash(tag, object_id, version, digest); + } + + @Override + public String toString() { + return "SuiObjectResponseError{" + + "tag='" + + tag + + '\'' + + ", object_id='" + + object_id + + '\'' + + ", version=" + + version + + ", digest='" + + digest + + '\'' + + '}'; + } } diff --git a/src/main/java/io/sui/models/objects/SuiParsedData.java b/src/main/java/io/sui/models/objects/SuiParsedData.java index 3272e33..52e144d 100644 --- a/src/main/java/io/sui/models/objects/SuiParsedData.java +++ b/src/main/java/io/sui/models/objects/SuiParsedData.java @@ -1,7 +1,172 @@ -package io.sui.models.objects;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/3/19 - * Time: 20:38 - */public class SuiParsedData { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.objects; + + +import java.util.Map; +import java.util.Objects; + +/** + * The type Sui parsed data. + * + * @author grapebaba + * @since 2023.03 + */ +public abstract class SuiParsedData { + + /** The type Move object. */ + public static class MoveObject extends SuiParsedData { + + private String type; + + private Map fields; + + private boolean hasPublicTransfer; + + /** + * Gets type. + * + * @return the type + */ + public String getType() { + return type; + } + + /** + * Sets type. + * + * @param type the type + */ + public void setType(String type) { + this.type = type; + } + + /** + * Gets fields. + * + * @return the fields + */ + public Map getFields() { + return fields; + } + + /** + * Sets fields. + * + * @param fields the fields + */ + public void setFields(Map fields) { + this.fields = fields; + } + + /** + * Is has public transfer boolean. + * + * @return the boolean + */ + public boolean isHasPublicTransfer() { + return hasPublicTransfer; + } + + /** + * Sets has public transfer. + * + * @param hasPublicTransfer the has public transfer + */ + public void setHasPublicTransfer(boolean hasPublicTransfer) { + this.hasPublicTransfer = hasPublicTransfer; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MoveObject)) { + return false; + } + MoveObject that = (MoveObject) o; + return hasPublicTransfer == that.hasPublicTransfer + && type.equals(that.type) + && fields.equals(that.fields); + } + + @Override + public int hashCode() { + return Objects.hash(type, fields, hasPublicTransfer); + } + + @Override + public String toString() { + return "MoveObject{" + + "type='" + + type + + '\'' + + ", fields=" + + fields + + ", hasPublicTransfer=" + + hasPublicTransfer + + '}'; + } + } + + /** The type Package object. */ + public static class PackageObject extends SuiParsedData { + + private Map disassembled; + + /** + * Gets disassembled. + * + * @return the disassembled + */ + public Map getDisassembled() { + return disassembled; + } + + /** + * Sets disassembled. + * + * @param disassembled the disassembled + */ + public void setDisassembled(Map disassembled) { + this.disassembled = disassembled; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PackageObject)) { + return false; + } + PackageObject that = (PackageObject) o; + return disassembled.equals(that.disassembled); + } + + @Override + public int hashCode() { + return Objects.hash(disassembled); + } + + @Override + public String toString() { + return "PackageObject{" + "disassembled=" + disassembled + '}'; + } + } } diff --git a/src/main/java/io/sui/models/objects/SuiRawData.java b/src/main/java/io/sui/models/objects/SuiRawData.java index 26abfdd..1975fae 100644 --- a/src/main/java/io/sui/models/objects/SuiRawData.java +++ b/src/main/java/io/sui/models/objects/SuiRawData.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -26,12 +26,10 @@ * @author grapebaba * @since 2022.11 */ -public abstract class SuiData { +public abstract class SuiRawData { - /** - * The type Package object. - */ - public static class PackageObject extends SuiData { + /** The type Package object. */ + public static class PackageObject extends SuiRawData { private String id; @@ -82,8 +80,9 @@ public boolean equals(Object o) { return false; } PackageObject that = (PackageObject) o; - return id.equals(that.id) && dataType.equals(that.dataType) && moduleMap.equals( - that.moduleMap) + return id.equals(that.id) + && dataType.equals(that.dataType) + && moduleMap.equals(that.moduleMap) && version.equals(that.version); } @@ -94,19 +93,23 @@ public int hashCode() { @Override public String toString() { - return "PackageObject{" + - "id='" + id + '\'' + - ", dataType='" + dataType + '\'' + - ", moduleMap=" + moduleMap + - ", version=" + version + - '}'; + return "PackageObject{" + + "id='" + + id + + '\'' + + ", dataType='" + + dataType + + '\'' + + ", moduleMap=" + + moduleMap + + ", version=" + + version + + '}'; } } - /** - * The type Move object. - */ - public static class MoveObject extends SuiData { + /** The type Move object. */ + public static class MoveObject extends SuiRawData { private String dataType; @@ -199,9 +202,11 @@ public boolean equals(Object o) { return false; } MoveObject that = (MoveObject) o; - return hasPublicTransfer == that.hasPublicTransfer && dataType.equals(that.dataType) - && type.equals(that.type) && version.equals(that.version) && bcsBytes.equals( - that.bcsBytes); + return hasPublicTransfer == that.hasPublicTransfer + && dataType.equals(that.dataType) + && type.equals(that.type) + && version.equals(that.version) + && bcsBytes.equals(that.bcsBytes); } @Override @@ -211,13 +216,21 @@ public int hashCode() { @Override public String toString() { - return "MoveObject{" + - "dataType='" + dataType + '\'' + - ", hasPublicTransfer=" + hasPublicTransfer + - ", type='" + type + '\'' + - ", version=" + version + - ", bcsBytes='" + bcsBytes + '\'' + - '}'; + return "MoveObject{" + + "dataType='" + + dataType + + '\'' + + ", hasPublicTransfer=" + + hasPublicTransfer + + ", type='" + + type + + '\'' + + ", version=" + + version + + ", bcsBytes='" + + bcsBytes + + '\'' + + '}'; } } } diff --git a/src/main/java/io/sui/models/transactions/PaginatedTransactionResponse.java b/src/main/java/io/sui/models/transactions/PaginatedTransactionResponse.java index 9aa01aa..84bc865 100644 --- a/src/main/java/io/sui/models/transactions/PaginatedTransactionResponse.java +++ b/src/main/java/io/sui/models/transactions/PaginatedTransactionResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -26,18 +26,20 @@ * @author grapebaba * @since 2022.11 */ -public class PaginatedTransactionDigests { +public class PaginatedTransactionResponse { - private List data; + private List data; private String nextCursor; + private boolean hasNextPage; + /** * Gets data. * * @return the data */ - public List getData() { + public List getData() { return data; } @@ -46,7 +48,7 @@ public List getData() { * * @param data the data */ - public void setData(List data) { + public void setData(List data) { this.data = data; } @@ -68,31 +70,53 @@ public void setNextCursor(String nextCursor) { this.nextCursor = nextCursor; } + /** + * Is has next page boolean. + * + * @return the boolean + */ + public boolean isHasNextPage() { + return hasNextPage; + } + + /** + * Sets has next page. + * + * @param hasNextPage the has next page + */ + public void setHasNextPage(boolean hasNextPage) { + this.hasNextPage = hasNextPage; + } + @Override public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof PaginatedTransactionDigests)) { + if (!(o instanceof PaginatedTransactionResponse)) { return false; } - PaginatedTransactionDigests that = (PaginatedTransactionDigests) o; - return data.equals(that.data) && nextCursor.equals(that.nextCursor); + PaginatedTransactionResponse that = (PaginatedTransactionResponse) o; + return hasNextPage == that.hasNextPage + && data.equals(that.data) + && nextCursor.equals(that.nextCursor); } @Override public String toString() { - return "PaginatedTransactionDigests{" + return "PaginatedTransactionResponse{" + "data=" + data + ", nextCursor='" + nextCursor + '\'' + + ", hasNextPage=" + + hasNextPage + '}'; } @Override public int hashCode() { - return Objects.hash(data, nextCursor); + return Objects.hash(data, nextCursor, hasNextPage); } } diff --git a/src/main/java/io/sui/models/transactions/ParsedMergeCoinResponse.java b/src/main/java/io/sui/models/transactions/ParsedMergeCoinResponse.java index 2389286..0f310a9 100644 --- a/src/main/java/io/sui/models/transactions/ParsedMergeCoinResponse.java +++ b/src/main/java/io/sui/models/transactions/ParsedMergeCoinResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -17,7 +17,7 @@ package io.sui.models.transactions; -import io.sui.models.objects.SuiObject; +import io.sui.models.objects.SuiObjectData; import java.util.Objects; /** @@ -28,16 +28,16 @@ */ public class ParsedMergeCoinResponse { - private SuiObject updatedCoin; + private SuiObjectData updatedCoin; - private SuiObject updatedGas; + private SuiObjectData updatedGas; /** * Gets updated coin. * * @return the updated coin */ - public SuiObject getUpdatedCoin() { + public SuiObjectData getUpdatedCoin() { return updatedCoin; } @@ -46,7 +46,7 @@ public SuiObject getUpdatedCoin() { * * @param updatedCoin the updated coin */ - public void setUpdatedCoin(SuiObject updatedCoin) { + public void setUpdatedCoin(SuiObjectData updatedCoin) { this.updatedCoin = updatedCoin; } @@ -55,7 +55,7 @@ public void setUpdatedCoin(SuiObject updatedCoin) { * * @return the updated gas */ - public SuiObject getUpdatedGas() { + public SuiObjectData getUpdatedGas() { return updatedGas; } @@ -64,7 +64,7 @@ public SuiObject getUpdatedGas() { * * @param updatedGas the updated gas */ - public void setUpdatedGas(SuiObject updatedGas) { + public void setUpdatedGas(SuiObjectData updatedGas) { this.updatedGas = updatedGas; } diff --git a/src/main/java/io/sui/models/transactions/ParsedPublishResponse.java b/src/main/java/io/sui/models/transactions/ParsedPublishResponse.java index a84fdb9..ebc8703 100644 --- a/src/main/java/io/sui/models/transactions/ParsedPublishResponse.java +++ b/src/main/java/io/sui/models/transactions/ParsedPublishResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -17,7 +17,7 @@ package io.sui.models.transactions; -import io.sui.models.objects.SuiObject; +import io.sui.models.objects.SuiObjectData; import io.sui.models.objects.SuiObjectRef; import java.util.List; import java.util.Objects; @@ -30,18 +30,18 @@ */ public class ParsedPublishResponse { - private List createdObjects; + private List createdObjects; private SuiObjectRef suiPackage; - private SuiObject updatedGas; + private SuiObjectData updatedGas; /** * Gets created objects. * * @return the created objects */ - public List getCreatedObjects() { + public List getCreatedObjects() { return createdObjects; } @@ -50,7 +50,7 @@ public List getCreatedObjects() { * * @param createdObjects the created objects */ - public void setCreatedObjects(List createdObjects) { + public void setCreatedObjects(List createdObjects) { this.createdObjects = createdObjects; } @@ -77,7 +77,7 @@ public void setSuiPackage(SuiObjectRef suiPackage) { * * @return the updated gas */ - public SuiObject getUpdatedGas() { + public SuiObjectData getUpdatedGas() { return updatedGas; } @@ -86,7 +86,7 @@ public SuiObject getUpdatedGas() { * * @param updatedGas the updated gas */ - public void setUpdatedGas(SuiObject updatedGas) { + public void setUpdatedGas(SuiObjectData updatedGas) { this.updatedGas = updatedGas; } diff --git a/src/main/java/io/sui/models/transactions/ParsedSplitCoinResponse.java b/src/main/java/io/sui/models/transactions/ParsedSplitCoinResponse.java index cb20c39..c1eb15c 100644 --- a/src/main/java/io/sui/models/transactions/ParsedSplitCoinResponse.java +++ b/src/main/java/io/sui/models/transactions/ParsedSplitCoinResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -17,7 +17,7 @@ package io.sui.models.transactions; -import io.sui.models.objects.SuiObject; +import io.sui.models.objects.SuiObjectData; import java.util.List; import java.util.Objects; @@ -29,18 +29,18 @@ */ public class ParsedSplitCoinResponse { - private SuiObject updatedCoin; + private SuiObjectData updatedCoin; - private List newCoins; + private List newCoins; - private SuiObject updatedGas; + private SuiObjectData updatedGas; /** * Gets updated coin. * * @return the updated coin */ - public SuiObject getUpdatedCoin() { + public SuiObjectData getUpdatedCoin() { return updatedCoin; } @@ -49,7 +49,7 @@ public SuiObject getUpdatedCoin() { * * @param updatedCoin the updated coin */ - public void setUpdatedCoin(SuiObject updatedCoin) { + public void setUpdatedCoin(SuiObjectData updatedCoin) { this.updatedCoin = updatedCoin; } @@ -58,7 +58,7 @@ public void setUpdatedCoin(SuiObject updatedCoin) { * * @return the new coins */ - public List getNewCoins() { + public List getNewCoins() { return newCoins; } @@ -67,7 +67,7 @@ public List getNewCoins() { * * @param newCoins the new coins */ - public void setNewCoins(List newCoins) { + public void setNewCoins(List newCoins) { this.newCoins = newCoins; } @@ -76,7 +76,7 @@ public void setNewCoins(List newCoins) { * * @return the updated gas */ - public SuiObject getUpdatedGas() { + public SuiObjectData getUpdatedGas() { return updatedGas; } @@ -85,7 +85,7 @@ public SuiObject getUpdatedGas() { * * @param updatedGas the updated gas */ - public void setUpdatedGas(SuiObject updatedGas) { + public void setUpdatedGas(SuiObjectData updatedGas) { this.updatedGas = updatedGas; } diff --git a/src/main/java/io/sui/models/transactions/StructTag.java b/src/main/java/io/sui/models/transactions/StructTag.java index 517f4ee..720a555 100644 --- a/src/main/java/io/sui/models/transactions/StructTag.java +++ b/src/main/java/io/sui/models/transactions/StructTag.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -17,6 +17,7 @@ package io.sui.models.transactions; +import com.google.common.collect.Lists; import java.util.List; import java.util.Objects; @@ -34,7 +35,7 @@ public class StructTag { private String name; - private List typeParams; + private List typeParams = Lists.newArrayList(); /** * Gets address. diff --git a/src/main/java/io/sui/models/transactions/TransactionBlockResponse.java b/src/main/java/io/sui/models/transactions/TransactionBlockResponse.java index 65559db..c53b1fd 100644 --- a/src/main/java/io/sui/models/transactions/TransactionBlockResponse.java +++ b/src/main/java/io/sui/models/transactions/TransactionBlockResponse.java @@ -28,7 +28,7 @@ * @author grapebaba * @since 2022.11 */ -public class TransactionResponse { +public class TransactionBlockResponse { private String digest; @@ -216,10 +216,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof TransactionResponse)) { + if (!(o instanceof TransactionBlockResponse)) { return false; } - TransactionResponse that = (TransactionResponse) o; + TransactionBlockResponse that = (TransactionBlockResponse) o; return confirmedLocalExecution == that.confirmedLocalExecution && digest.equals(that.digest) && transaction.equals(that.transaction) diff --git a/src/main/java/io/sui/models/transactions/TransactionBlockResponseOptions.java b/src/main/java/io/sui/models/transactions/TransactionBlockResponseOptions.java index d0f9b8d..9d83ff3 100644 --- a/src/main/java/io/sui/models/transactions/TransactionBlockResponseOptions.java +++ b/src/main/java/io/sui/models/transactions/TransactionBlockResponseOptions.java @@ -25,7 +25,7 @@ * @author grapebaba * @since 2023.03 */ -public class TransactionResponseOptions { +public class TransactionBlockResponseOptions { private boolean showInput; @@ -114,10 +114,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof TransactionResponseOptions)) { + if (!(o instanceof TransactionBlockResponseOptions)) { return false; } - TransactionResponseOptions that = (TransactionResponseOptions) o; + TransactionBlockResponseOptions that = (TransactionBlockResponseOptions) o; return showInput == that.showInput && showEffects == that.showEffects && showEvents == that.showEvents @@ -131,7 +131,7 @@ public int hashCode() { @Override public String toString() { - return "TransactionResponseOptions{" + return "TransactionBlockResponseOptions{" + "show_input=" + showInput + ", show_effects=" diff --git a/src/main/java/io/sui/models/transactions/TransactionBlockResponseQuery.java b/src/main/java/io/sui/models/transactions/TransactionBlockResponseQuery.java index dc3ea39..e4c15ce 100644 --- a/src/main/java/io/sui/models/transactions/TransactionBlockResponseQuery.java +++ b/src/main/java/io/sui/models/transactions/TransactionBlockResponseQuery.java @@ -1,7 +1,91 @@ -package io.sui.models.transactions;/** - * Created by IntelliJ IDEA. - * Author: kaichen - * Date: 2023/4/10 - * Time: 19:35 - */public class TransactionBlockResponseQuery { +/* + * Copyright 2023 281165273grape@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package io.sui.models.transactions; + + +import java.util.Objects; + +/** + * The type Transaction block response query. + * + * @author grapebaba + * @since 2023.04 + */ +public class TransactionBlockResponseQuery { + + private TransactionFilter filter; + + private TransactionBlockResponseOptions options; + + /** + * Gets filter. + * + * @return the filter + */ + public TransactionFilter getFilter() { + return filter; + } + + /** + * Sets filter. + * + * @param filter the filter + */ + public void setFilter(TransactionFilter filter) { + this.filter = filter; + } + + /** + * Gets options. + * + * @return the options + */ + public TransactionBlockResponseOptions getOptions() { + return options; + } + + /** + * Sets options. + * + * @param options the options + */ + public void setOptions(TransactionBlockResponseOptions options) { + this.options = options; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TransactionBlockResponseQuery)) { + return false; + } + TransactionBlockResponseQuery that = (TransactionBlockResponseQuery) o; + return filter.equals(that.filter) && options.equals(that.options); + } + + @Override + public int hashCode() { + return Objects.hash(filter, options); + } + + @Override + public String toString() { + return "TransactionBlockResponseQuery{" + "filter=" + filter + ", options=" + options + '}'; + } } diff --git a/src/main/java/io/sui/models/transactions/TransactionBytes.java b/src/main/java/io/sui/models/transactions/TransactionBytes.java index 7628c69..eb503b0 100644 --- a/src/main/java/io/sui/models/transactions/TransactionBytes.java +++ b/src/main/java/io/sui/models/transactions/TransactionBytes.java @@ -30,7 +30,7 @@ */ public class TransactionBytes { - private SuiObjectRef gas; + private List gas; private List inputObjects; @@ -38,10 +38,20 @@ public class TransactionBytes { private io.sui.bcsgen.TransactionData localTxBytes; + /** + * Gets local tx bytes. + * + * @return the local tx bytes + */ public io.sui.bcsgen.TransactionData getLocalTxBytes() { return localTxBytes; } + /** + * Sets local tx bytes. + * + * @param localTxBytes the local tx bytes + */ public void setLocalTxBytes(io.sui.bcsgen.TransactionData localTxBytes) { this.localTxBytes = localTxBytes; } @@ -51,7 +61,7 @@ public void setLocalTxBytes(io.sui.bcsgen.TransactionData localTxBytes) { * * @return the gas */ - public SuiObjectRef getGas() { + public List getGas() { return gas; } @@ -60,7 +70,7 @@ public SuiObjectRef getGas() { * * @param gas the gas */ - public void setGas(SuiObjectRef gas) { + public void setGas(List gas) { this.gas = gas; } diff --git a/src/main/java/io/sui/models/transactions/TransactionFilter.java b/src/main/java/io/sui/models/transactions/TransactionFilter.java index 754d724..6453cc5 100644 --- a/src/main/java/io/sui/models/transactions/TransactionFilter.java +++ b/src/main/java/io/sui/models/transactions/TransactionFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 281165273grape@gmail.com + * Copyright 2022-2023 281165273grape@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with @@ -25,12 +25,10 @@ * @author grapebaba * @since 2022.11 */ -public abstract class TransactionQuery { +public abstract class TransactionFilter { - /** - * The type Move function query. - */ - public static class MoveFunctionQuery extends TransactionQuery { + /** The type Move function query. */ + public static class MoveFunctionFilter extends TransactionFilter { @SuppressWarnings("checkstyle:MemberName") private MoveFunction MoveFunction; @@ -58,10 +56,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof MoveFunctionQuery)) { + if (!(o instanceof MoveFunctionFilter)) { return false; } - MoveFunctionQuery that = (MoveFunctionQuery) o; + MoveFunctionFilter that = (MoveFunctionFilter) o; return MoveFunction.equals(that.MoveFunction); } @@ -72,14 +70,12 @@ public int hashCode() { @Override public String toString() { - return "MoveFunctionQuery{" + "MoveFunction=" + MoveFunction + '}'; + return "MoveFunctionFilter{" + "MoveFunction=" + MoveFunction + '}'; } } - /** - * The type Input object query. - */ - public static class InputObjectQuery extends TransactionQuery { + /** The type Input object query. */ + public static class InputObjectFilter extends TransactionFilter { @SuppressWarnings("checkstyle:MemberName") private String InputObject; @@ -107,10 +103,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof InputObjectQuery)) { + if (!(o instanceof InputObjectFilter)) { return false; } - InputObjectQuery that = (InputObjectQuery) o; + InputObjectFilter that = (InputObjectFilter) o; return InputObject.equals(that.InputObject); } @@ -121,14 +117,12 @@ public int hashCode() { @Override public String toString() { - return "InputObjectQuery{" + "InputObject='" + InputObject + '\'' + '}'; + return "InputObjectFilter{" + "InputObject='" + InputObject + '\'' + '}'; } } - /** - * The type Mutated object query. - */ - public static class ChangedObjectQuery extends TransactionQuery { + /** The type Mutated object query. */ + public static class ChangedObjectFilter extends TransactionFilter { @SuppressWarnings("checkstyle:MemberName") private String ChangedObject; @@ -156,10 +150,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof ChangedObjectQuery)) { + if (!(o instanceof ChangedObjectFilter)) { return false; } - ChangedObjectQuery that = (ChangedObjectQuery) o; + ChangedObjectFilter that = (ChangedObjectFilter) o; return ChangedObject.equals(that.ChangedObject); } @@ -174,10 +168,8 @@ public String toString() { } } - /** - * The type From address query. - */ - public static class FromAddressQuery extends TransactionQuery { + /** The type From address query. */ + public static class FromAddressFilter extends TransactionFilter { @SuppressWarnings("checkstyle:MemberName") private String FromAddress; @@ -205,10 +197,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof FromAddressQuery)) { + if (!(o instanceof FromAddressFilter)) { return false; } - FromAddressQuery that = (FromAddressQuery) o; + FromAddressFilter that = (FromAddressFilter) o; return FromAddress.equals(that.FromAddress); } @@ -219,14 +211,12 @@ public int hashCode() { @Override public String toString() { - return "FromAddressQuery{" + "FromAddress='" + FromAddress + '\'' + '}'; + return "FromAddressFilter{" + "FromAddress='" + FromAddress + '\'' + '}'; } } - /** - * The type To address query. - */ - public static class ToAddressQuery extends TransactionQuery { + /** The type To address query. */ + public static class ToAddressFilter extends TransactionFilter { @SuppressWarnings("checkstyle:MemberName") private String ToAddress; @@ -254,10 +244,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof ToAddressQuery)) { + if (!(o instanceof ToAddressFilter)) { return false; } - ToAddressQuery that = (ToAddressQuery) o; + ToAddressFilter that = (ToAddressFilter) o; return ToAddress.equals(that.ToAddress); } @@ -268,7 +258,7 @@ public int hashCode() { @Override public String toString() { - return "ToAddressQuery{" + "ToAddress='" + ToAddress + '\'' + '}'; + return "ToAddressFilter{" + "ToAddress='" + ToAddress + '\'' + '}'; } } } diff --git a/src/test/java/io/sui/crypto/ED25519KeyPairTest.java b/src/test/java/io/sui/crypto/ED25519KeyPairTest.java index 57807fb..1cec4b9 100644 --- a/src/test/java/io/sui/crypto/ED25519KeyPairTest.java +++ b/src/test/java/io/sui/crypto/ED25519KeyPairTest.java @@ -40,16 +40,17 @@ class ED25519KeyPairTest { /** Address. */ @Test void address() { - final String base64 = "ADfbVnAT2QLG7W+bM+1ENzEKAxnoUx10+WfGg5zx8VRm"; + final String base64 = "AGppxlDnjjspxa/5JSzPXx9s4QfqhDN7prZ9ZSpk/1qk"; final ED25519KeyPair keyPair = ED25519KeyPair.decodeBase64(Base64.decode(base64)); - assertEquals("0x0a7421363a1f6a82800f7c9340ac02b5905798cb", keyPair.address()); + assertEquals( + "0x0e842f5339d01f22f9b6412884cee3defdccb0d8c092755e2a043c842941b6ab", keyPair.address()); } - /** Decode base 64. */ + /** Decode base 64. @throws CryptoException the crypto exception */ @Test void decodeBase64() throws CryptoException { - final String base64 = "ADfbVnAT2QLG7W+bM+1ENzEKAxnoUx10+WfGg5zx8VRm"; + final String base64 = "AGppxlDnjjspxa/5JSzPXx9s4QfqhDN7prZ9ZSpk/1qk"; final ED25519KeyPair ed25519KeyPair = ED25519KeyPair.decodeBase64(Base64.decode(base64)); Signer signer = new Ed25519Signer(); diff --git a/src/test/java/io/sui/crypto/FileBasedKeyStoreTest.java b/src/test/java/io/sui/crypto/FileBasedKeyStoreTest.java index 7b21827..176f72b 100644 --- a/src/test/java/io/sui/crypto/FileBasedKeyStoreTest.java +++ b/src/test/java/io/sui/crypto/FileBasedKeyStoreTest.java @@ -52,13 +52,13 @@ void initKeyPairs() { assertEquals(7, fileBasedKeyStore.keys.size()); String expected = - "0x0a7421363a1f6a82800f7c9340ac02b5905798cb\n" - + "0x64e1714eb06c22dff8ac7dab7eb302d4abededf9\n" - + "0xa0fd2a6814cff90d4463fb7e5b5b81d01d763472\n" - + "0xd456963facd4c40adfc3858d1a33c93d4d759664\n" - + "0xee3752e38e25a52c5d35cff23695d1115d3a0149\n" - + "0xf76f8c0e679c55a9d17229b9cbda702645836aa7\n" - + "0xfa423b6448e5e83d03e0d98ce00b5be32da5ee86\n"; + "0x078ad0970cacfec86cd404e6382a86de441ec14c310e3f8c0e310733802f4992\n" + + "0x0e842f5339d01f22f9b6412884cee3defdccb0d8c092755e2a043c842941b6ab\n" + + "0x16aa1d0462fe9b4a97d2f9ad1a1f299b21c5002f7f1b7320d83ff3c8ee97d951\n" + + "0x1b8321a438ab8eea0ab6eb94e1dd0b2da347b1697a066cbe5e5122f5d7debe6c\n" + + "0x49e14eea497baef59ed20be791790ae152d63209bfc4b5235c608f60caba82bd\n" + + "0x508bbbb2d623e7718a298e13cf78e8d667b2299e77d87407f6e32c84a4c3dc37\n" + + "0xb43d0468fbc80c81931b73a4b9ef4663e671b65a07ae5b336a0e7d8a70ac0646\n"; StringBuilder actual = new StringBuilder(); for (String key : fileBasedKeyStore.keys.navigableKeySet()) { actual.append(key).append("\n"); @@ -66,11 +66,13 @@ void initKeyPairs() { assertEquals(expected, actual.toString()); } - // ED25519 0x4e0cc5c559ee61c36d61d0624c924cc43348b764 - // "feel acid liar execute insane midnight oval oyster slot uncle bitter person" + // ED25519 0xf6959f5969790295e2fe37615fe78f1b2e9311ff93fe560ac08b0d2963efe7c5 + // "version final youth crush olive light leg perfect fashion able rally cotton pulse giraffe hurt + // blush type devote provide leopard echo print mention leg" - // Secp256k1 0x6604964784bd9792e53dca3750d29ab39fb053e5 - // heart position turkey bus virtual host panther pioneer ready lesson fence what + // Secp256k1 0x16aa1d0462fe9b4a97d2f9ad1a1f299b21c5002f7f1b7320d83ff3c8ee97d951 + // chest shuffle jar trophy nurse fish board member dove rival adjust awful wool camp rebuild fire + // bunker verify message velvet save oblige net twice @Test void importFromMnemonicTest() throws Exception { @@ -80,14 +82,16 @@ void importFromMnemonicTest() throws Exception { // test data from sui client String[] mnemonics = new String[] { - "feel acid liar execute insane midnight oval oyster slot uncle bitter person", - "heart position turkey bus virtual host panther pioneer ready lesson fence what", + "version final youth crush olive light leg perfect fashion able rally cotton pulse " + + "giraffe hurt blush type devote provide leopard echo print mention leg", + "chest shuffle jar trophy nurse fish board member dove rival adjust awful wool camp " + + "rebuild fire bunker verify message velvet save oblige net twice", }; String[] addresses = new String[] { - "0x4e0cc5c559ee61c36d61d0624c924cc43348b764", - "0x6604964784bd9792e53dca3750d29ab39fb053e5", + "0xf6959f5969790295e2fe37615fe78f1b2e9311ff93fe560ac08b0d2963efe7c5", + "0x16aa1d0462fe9b4a97d2f9ad1a1f299b21c5002f7f1b7320d83ff3c8ee97d951", }; String addr = fileBasedKeyStore.importFromMnemonic(mnemonics[0], SignatureScheme.ED25519); diff --git a/src/test/java/io/sui/crypto/SECP256K1KeyPairTest.java b/src/test/java/io/sui/crypto/SECP256K1KeyPairTest.java index 3b34a3f..f512fc6 100644 --- a/src/test/java/io/sui/crypto/SECP256K1KeyPairTest.java +++ b/src/test/java/io/sui/crypto/SECP256K1KeyPairTest.java @@ -37,16 +37,18 @@ class SECP256K1KeyPairTest { /** Address. */ @Test void address() { - final String base64 = "ABw1fhWdG+Ni9eFfyLdfdmsiMWyirHCV/UVC9jcloBm8"; + final String base64 = "AfdfC5Tf7gNYm2ElFQsOxnKhYWk7gLW0yXctlAHYQjFe"; final SuiKeyPair secp256K1KeyPair = SECP256K1KeyPair.decodeBase64(Base64.decode(base64)); - assertEquals("0xea650e4199befc011d2373decabc4c3deb0275d8", secp256K1KeyPair.address()); + assertEquals( + "0x078ad0970cacfec86cd404e6382a86de441ec14c310e3f8c0e310733802f4992", + secp256K1KeyPair.address()); } /** Decode base 64. */ @Test void decodeBase64() { - final String base64 = "ABw1fhWdG+Ni9eFfyLdfdmsiMWyirHCV/UVC9jcloBm8"; + final String base64 = "AfdfC5Tf7gNYm2ElFQsOxnKhYWk7gLW0yXctlAHYQjFe"; final SuiKeyPair secp256K1KeyPair = SECP256K1KeyPair.decodeBase64(Base64.decode(base64)); final String msg = "test"; final ECDSASignature signature = secp256K1KeyPair.keyPair.sign(Sha256Hash.of(msg.getBytes())); diff --git a/src/test/java/io/sui/crypto/SuiKeyPairTest.java b/src/test/java/io/sui/crypto/SuiKeyPairTest.java index 82d97d8..f4b2e06 100644 --- a/src/test/java/io/sui/crypto/SuiKeyPairTest.java +++ b/src/test/java/io/sui/crypto/SuiKeyPairTest.java @@ -34,7 +34,7 @@ class SuiKeyPairTest { /** Decode base 64. */ @Test void decodeBase64() { - final String base64 = "ADfbVnAT2QLG7W+bM+1ENzEKAxnoUx10+WfGg5zx8VRm"; + final String base64 = "AUsCQlGEBz1TLmEfRsxUzxcyI3yywp+1/k4UZ5wV05CE"; try { SuiKeyPair.decodeBase64(base64); } catch (SignatureSchemeNotSupportedException e) { diff --git a/src/test/resources/config/sui.keystore b/src/test/resources/config/sui.keystore index 517623f..fde80f8 100644 --- a/src/test/resources/config/sui.keystore +++ b/src/test/resources/config/sui.keystore @@ -1,9 +1,9 @@ [ - "ADfbVnAT2QLG7W+bM+1ENzEKAxnoUx10+WfGg5zx8VRm", - "AWe4FkcXsOj4VyovvBPIelOdFCoRcEikbDY3owNCHU9v", - "AKq86eFhwsImf6AmQU47bJsKn7zIQkDbxDboke06+2LW", - "AfbiK0DiFbFcQlxhT8qy5wFw9AdjhFMUVXHKt0NPTSnD", - "ADuyofQrqgbSBhocqgkaSPLagvru0WJVT9OlZxl5aRru", - "ABw1fhWdG+Ni9eFfyLdfdmsiMWyirHCV/UVC9jcloBm8", - "AN8gQvDgucRoQM3zK+oyLr8ZUdhlnUa2JhN9PcBxNq2U" + "AfdfC5Tf7gNYm2ElFQsOxnKhYWk7gLW0yXctlAHYQjFe", + "AGppxlDnjjspxa/5JSzPXx9s4QfqhDN7prZ9ZSpk/1qk", + "AUsCQlGEBz1TLmEfRsxUzxcyI3yywp+1/k4UZ5wV05CE", + "ABwNtnCDodPoz6KP3Zzip/Iec27ecXzH1CS9dsYiX3Zv", + "ALjsPBnpDXh6IWc7nFMBVmRS8hQpKGOii9LLAcMGvGRl", + "ALARRJdOh7MHToFpNP7wfnT6qXmODD6UF5qi/64RMBL9", + "AIHUweYVU2FGgk1X9NZaZ0u3UqvJwF/3ZzmOUJxvfG7c" ] \ No newline at end of file