Skip to content

Commit

Permalink
Add support for parsing InvokeHostFunctionOperationResponse.
Browse files Browse the repository at this point in the history
  • Loading branch information
overcat committed Jul 24, 2023
1 parent 5860fea commit 188bcbe
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/main/java/org/stellar/sdk/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,23 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import org.stellar.sdk.xdr.*;
import org.stellar.sdk.xdr.AccountID;
import org.stellar.sdk.xdr.ClaimableBalanceID;
import org.stellar.sdk.xdr.ClaimableBalanceIDType;
import org.stellar.sdk.xdr.DecoratedSignature;
import org.stellar.sdk.xdr.EnvelopeType;
import org.stellar.sdk.xdr.Hash;
import org.stellar.sdk.xdr.HashIDPreimage;
import org.stellar.sdk.xdr.Int64;
import org.stellar.sdk.xdr.SequenceNumber;
import org.stellar.sdk.xdr.SorobanTransactionData;
import org.stellar.sdk.xdr.TransactionEnvelope;
import org.stellar.sdk.xdr.TransactionSignaturePayload;
import org.stellar.sdk.xdr.TransactionV0;
import org.stellar.sdk.xdr.TransactionV0Envelope;
import org.stellar.sdk.xdr.TransactionV1Envelope;
import org.stellar.sdk.xdr.Uint32;
import org.stellar.sdk.xdr.XdrDataOutputStream;

/**
* Represents <a href="https://developers.stellar.org/docs/glossary/transactions/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package org.stellar.sdk.responses.operations;

import com.google.common.collect.ImmutableList;
import com.google.gson.annotations.SerializedName;
import org.stellar.sdk.xdr.HostFunctionType;

/**
* Represents InvokeHostFunction operation response.
*
* @see <a href="https://developers.stellar.org/api/horizon/resources/operations"
* target="_blank">Operation documentation</a>
* @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<HostFunctionParameter> parameters;

@SerializedName("address")
private final String address;

@SerializedName("salt")
private final String salt;

@SerializedName("asset_balance_changes")
private final ImmutableList<AssetContractBalanceChange> assetBalanceChanges;

public InvokeHostFunctionOperationResponse(
String function,
ImmutableList<HostFunctionParameter> parameters,
String address,
String salt,
ImmutableList<AssetContractBalanceChange> assetBalanceChanges) {
this.function = function;
this.parameters = parameters;
this.address = address;
this.salt = salt;
this.assetBalanceChanges = assetBalanceChanges;
}

/**
* Returns the function type ({@link HostFunctionType}), which can have one of the following
* values:
*
* <ul>
* <li>"HostFunctionTypeHostFunctionTypeInvokeContract"
* <li>"HostFunctionTypeHostFunctionTypeCreateContract"
* <li>"HostFunctionTypeHostFunctionTypeUploadContractWasm"
* </ul>
*
* @return the function type of the host function
*/
public String getFunction() {
return function;
}

public ImmutableList<HostFunctionParameter> getParameters() {
return parameters;
}

public String getAddress() {
return address;
}

public String getSalt() {
return salt;
}

public ImmutableList<AssetContractBalanceChange> 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;
}
}
}
122 changes: 122 additions & 0 deletions src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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.InvokeHostFunctionOperationResponse;
import org.stellar.sdk.responses.operations.LiquidityPoolDepositOperationResponse;
import org.stellar.sdk.responses.operations.LiquidityPoolWithdrawOperationResponse;
import org.stellar.sdk.responses.operations.ManageBuyOfferOperationResponse;
Expand Down Expand Up @@ -1834,4 +1835,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");
}
}

0 comments on commit 188bcbe

Please sign in to comment.