From d6a7b60898597ef8957e7026cd705a54c5962f35 Mon Sep 17 00:00:00 2001 From: overcat <4catcode@gmail.com> Date: Thu, 20 Jul 2023 19:23:45 +0800 Subject: [PATCH] Add support for parsing InvokeHostFunctionOperationResponse. --- .../sdk/responses/OperationDeserializer.java | 2 + .../InvokeHostFunctionOperationResponse.java | 152 ++++++++++++++++++ .../responses/OperationDeserializerTest.java | 143 +++++++++++++--- 3 files changed, 276 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/stellar/sdk/responses/operations/InvokeHostFunctionOperationResponse.java diff --git a/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java b/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java index c16e9b0f0..961cc1474 100644 --- a/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java +++ b/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java @@ -87,6 +87,8 @@ public OperationResponse deserialize( return gson.fromJson(json, LiquidityPoolDepositOperationResponse.class); case LIQUIDITY_POOL_WITHDRAW: return gson.fromJson(json, LiquidityPoolWithdrawOperationResponse.class); + case INVOKE_HOST_FUNCTION: + return gson.fromJson(json, InvokeHostFunctionOperationResponse.class); default: throw new RuntimeException("Invalid operation type"); } diff --git a/src/main/java/org/stellar/sdk/responses/operations/InvokeHostFunctionOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/InvokeHostFunctionOperationResponse.java new file mode 100644 index 000000000..73e205801 --- /dev/null +++ b/src/main/java/org/stellar/sdk/responses/operations/InvokeHostFunctionOperationResponse.java @@ -0,0 +1,152 @@ +package org.stellar.sdk.responses.operations; + +import com.google.common.collect.ImmutableList; +import com.google.gson.annotations.SerializedName; + +/** + * Represents InvokeHostFunction operation response. + * + * @see Operation documentation + * @see org.stellar.sdk.requests.OperationsRequestBuilder + * @see org.stellar.sdk.Server#operations() + */ +public class InvokeHostFunctionOperationResponse extends OperationResponse { + @SerializedName("function") + private final String function; + + @SerializedName("parameters") + private final ImmutableList parameters; + + @SerializedName("address") + private final String address; + + @SerializedName("salt") + private final String salt; + + @SerializedName("asset_balance_changes") + private final ImmutableList assetBalanceChanges; + + public InvokeHostFunctionOperationResponse( + String function, + ImmutableList parameters, + String address, + String salt, + ImmutableList assetBalanceChanges) { + this.function = function; + this.parameters = parameters; + this.address = address; + this.salt = salt; + this.assetBalanceChanges = assetBalanceChanges; + } + + public String getFunction() { + return function; + } + + public ImmutableList getParameters() { + return parameters; + } + + public String getAddress() { + return address; + } + + public String getSalt() { + return salt; + } + + public ImmutableList getAssetBalanceChanges() { + return assetBalanceChanges; + } + + public static class HostFunctionParameter { + + @SerializedName("type") + private final String type; + + @SerializedName("value") + private final String value; + + HostFunctionParameter(String type, String value) { + this.type = type; + this.value = value; + } + + public String getType() { + return type; + } + + public String getValue() { + return value; + } + } + + public static class AssetContractBalanceChange { + @SerializedName("asset_type") + private final String assetType; + + @SerializedName("asset_code") + private final String assetCode; + + @SerializedName("asset_issuer") + private final String assetIssuer; + + @SerializedName("type") + private final String type; + + @SerializedName("from") + private final String from; + + @SerializedName("to") + private final String to; + + @SerializedName("amount") + private final String amount; + + AssetContractBalanceChange( + String assetType, + String assetCode, + String assetIssuer, + String type, + String from, + String to, + String amount) { + this.assetType = assetType; + this.assetCode = assetCode; + this.assetIssuer = assetIssuer; + this.type = type; + this.from = from; + this.to = to; + this.amount = amount; + } + + public String getAssetType() { + return assetType; + } + + public String getAssetCode() { + return assetCode; + } + + public String getAssetIssuer() { + return assetIssuer; + } + + public String getType() { + return type; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public String getAmount() { + return amount; + } + } +} diff --git a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java index 4864dac56..a8303bf85 100644 --- a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java @@ -16,27 +16,7 @@ import org.stellar.sdk.FormatException; import org.stellar.sdk.Predicate; import org.stellar.sdk.Price; -import org.stellar.sdk.responses.operations.AccountMergeOperationResponse; -import org.stellar.sdk.responses.operations.AllowTrustOperationResponse; -import org.stellar.sdk.responses.operations.BumpSequenceOperationResponse; -import org.stellar.sdk.responses.operations.ChangeTrustOperationResponse; -import org.stellar.sdk.responses.operations.ClaimClaimableBalanceOperationResponse; -import org.stellar.sdk.responses.operations.ClawbackClaimableBalanceOperationResponse; -import org.stellar.sdk.responses.operations.ClawbackOperationResponse; -import org.stellar.sdk.responses.operations.CreateAccountOperationResponse; -import org.stellar.sdk.responses.operations.CreateClaimableBalanceOperationResponse; -import org.stellar.sdk.responses.operations.EndSponsoringFutureReservesOperationResponse; -import org.stellar.sdk.responses.operations.InflationOperationResponse; -import org.stellar.sdk.responses.operations.LiquidityPoolDepositOperationResponse; -import org.stellar.sdk.responses.operations.LiquidityPoolWithdrawOperationResponse; -import org.stellar.sdk.responses.operations.ManageBuyOfferOperationResponse; -import org.stellar.sdk.responses.operations.ManageDataOperationResponse; -import org.stellar.sdk.responses.operations.OperationResponse; -import org.stellar.sdk.responses.operations.PathPaymentStrictReceiveOperationResponse; -import org.stellar.sdk.responses.operations.PathPaymentStrictSendOperationResponse; -import org.stellar.sdk.responses.operations.PaymentOperationResponse; -import org.stellar.sdk.responses.operations.SetOptionsOperationResponse; -import org.stellar.sdk.responses.operations.SetTrustLineFlagsOperationResponse; +import org.stellar.sdk.responses.operations.*; public class OperationDeserializerTest extends TestCase { @Test @@ -1834,4 +1814,125 @@ public void testDeserializeCreateClaimableBalanceOperation() { operation.getClaimants().get(1).getPredicate().getClass(), Predicate.Unconditional.class); assertEquals(operation.getType(), "create_claimable_balance"); } + + @Test + public void testDeserializeInvokeHostFunctionOperation() { + String json = + "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"http://127.0.0.1:8000/operations/2224793063425\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"http://127.0.0.1:8000/transactions/4ef3d81fba4b7db959080e4894cb8b2575418b8da9aa484f6306a79a3f63de3d\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"http://127.0.0.1:8000/operations/2224793063425/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"http://127.0.0.1:8000/effects?order=desc&cursor=2224793063425\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"http://127.0.0.1:8000/effects?order=asc&cursor=2224793063425\"\n" + + " }\n" + + " },\n" + + " \"id\": \"2224793063425\",\n" + + " \"paging_token\": \"2224793063425\",\n" + + " \"transaction_successful\": true,\n" + + " \"source_account\": \"GDAT5HWTGIU4TSSZ4752OUC4SABDLTLZFRPZUJ3D6LKBNEPA7V2CIG54\",\n" + + " \"type\": \"invoke_host_function\",\n" + + " \"type_i\": 24,\n" + + " \"created_at\": \"2023-07-20T10:44:56Z\",\n" + + " \"transaction_hash\": \"4ef3d81fba4b7db959080e4894cb8b2575418b8da9aa484f6306a79a3f63de3d\",\n" + + " \"function\": \"HostFunctionTypeHostFunctionTypeInvokeContract\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"value\": \"AAAAEgAAAAGw7oy+G8a9SeTIE5E/EuJYl5JfwF0eZJWk8S7LmE7fwA==\",\n" + + " \"type\": \"Address\"\n" + + " },\n" + + " {\n" + + " \"value\": \"AAAADwAAAAh0cmFuc2Zlcg==\",\n" + + " \"type\": \"Sym\"\n" + + " },\n" + + " {\n" + + " \"value\": \"AAAAEgAAAAAAAAAAwT6e0zIpycpZ5/unUFyQAjXNeSxfmidj8tQWkeD9dCQ=\",\n" + + " \"type\": \"Address\"\n" + + " },\n" + + " {\n" + + " \"value\": \"AAAAEgAAAAAAAAAAWLfEosjyl6qPPSRxKB/fzOyv5I5WYzE+wY4Spz7KmKE=\",\n" + + " \"type\": \"Address\"\n" + + " },\n" + + " {\n" + + " \"value\": \"AAAACgAAAAAAAAAAAAAAASoF8gA=\",\n" + + " \"type\": \"I128\"\n" + + " }\n" + + " ],\n" + + " \"address\": \"\",\n" + + " \"salt\": \"\",\n" + + " \"asset_balance_changes\": [\n" + + " {\n" + + " \"asset_type\": \"credit_alphanum12\",\n" + + " \"asset_code\": \"Hello\",\n" + + " \"asset_issuer\": \"GDJKBIYIPBE2NC5XIZX6GCFZHVWFUA7ONMQUOOVTLIM3BESTI4BYADAN\",\n" + + " \"type\": \"transfer\",\n" + + " \"from\": \"GDAT5HWTGIU4TSSZ4752OUC4SABDLTLZFRPZUJ3D6LKBNEPA7V2CIG54\",\n" + + " \"to\": \"GBMLPRFCZDZJPKUPHUSHCKA737GOZL7ERZLGGMJ6YGHBFJZ6ZKMKCZTM\",\n" + + " \"amount\": \"500.0000000\"\n" + + " }\n" + + " ]\n" + + "}"; + + InvokeHostFunctionOperationResponse operation = + (InvokeHostFunctionOperationResponse) + GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + assertEquals( + operation.getLinks().getSelf().getHref(), "http://127.0.0.1:8000/operations/2224793063425"); + assertEquals(operation.getId().longValue(), 2224793063425L); + assertEquals(operation.getPagingToken(), "2224793063425"); + // TODO: add transaction_successful field to the response + // assertEquals(operation.getTransactionSuccessful(), true); + assertEquals( + operation.getSourceAccount(), "GDAT5HWTGIU4TSSZ4752OUC4SABDLTLZFRPZUJ3D6LKBNEPA7V2CIG54"); + assertEquals(operation.getType(), "invoke_host_function"); + // TODO: add type_i field to the response + assertEquals(operation.getCreatedAt(), "2023-07-20T10:44:56Z"); + assertEquals( + operation.getTransactionHash(), + "4ef3d81fba4b7db959080e4894cb8b2575418b8da9aa484f6306a79a3f63de3d"); + assertEquals(operation.getFunction(), "HostFunctionTypeHostFunctionTypeInvokeContract"); + assertEquals(operation.getParameters().size(), 5); + assertEquals(operation.getParameters().get(0).getType(), "Address"); + assertEquals( + operation.getParameters().get(0).getValue(), + "AAAAEgAAAAGw7oy+G8a9SeTIE5E/EuJYl5JfwF0eZJWk8S7LmE7fwA=="); + assertEquals(operation.getParameters().get(1).getType(), "Sym"); + assertEquals(operation.getParameters().get(1).getValue(), "AAAADwAAAAh0cmFuc2Zlcg=="); + assertEquals(operation.getParameters().get(2).getType(), "Address"); + assertEquals( + operation.getParameters().get(2).getValue(), + "AAAAEgAAAAAAAAAAwT6e0zIpycpZ5/unUFyQAjXNeSxfmidj8tQWkeD9dCQ="); + assertEquals(operation.getParameters().get(3).getType(), "Address"); + assertEquals( + operation.getParameters().get(3).getValue(), + "AAAAEgAAAAAAAAAAWLfEosjyl6qPPSRxKB/fzOyv5I5WYzE+wY4Spz7KmKE="); + assertEquals(operation.getParameters().get(4).getType(), "I128"); + assertEquals(operation.getParameters().get(4).getValue(), "AAAACgAAAAAAAAAAAAAAASoF8gA="); + + assertEquals(operation.getAddress(), ""); + assertEquals(operation.getSalt(), ""); + assertEquals(operation.getAssetBalanceChanges().size(), 1); + assertEquals(operation.getAssetBalanceChanges().get(0).getAssetType(), "credit_alphanum12"); + assertEquals(operation.getAssetBalanceChanges().get(0).getAssetCode(), "Hello"); + assertEquals( + operation.getAssetBalanceChanges().get(0).getAssetIssuer(), + "GDJKBIYIPBE2NC5XIZX6GCFZHVWFUA7ONMQUOOVTLIM3BESTI4BYADAN"); + assertEquals(operation.getAssetBalanceChanges().get(0).getType(), "transfer"); + assertEquals( + operation.getAssetBalanceChanges().get(0).getFrom(), + "GDAT5HWTGIU4TSSZ4752OUC4SABDLTLZFRPZUJ3D6LKBNEPA7V2CIG54"); + assertEquals( + operation.getAssetBalanceChanges().get(0).getTo(), + "GBMLPRFCZDZJPKUPHUSHCKA737GOZL7ERZLGGMJ6YGHBFJZ6ZKMKCZTM"); + assertEquals(operation.getAssetBalanceChanges().get(0).getAmount(), "500.0000000"); + } }