diff --git a/CHANGELOG.md b/CHANGELOG.md index 88187c365..3c3b58bc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ As this project is pre 1.0, breaking changes may happen for minor version bumps. * Add opt-in support for [SEP23](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0023.md) M-strkeys for `MuxedAccount`s * Add `getClaimableBalanceId()` method to `Transaction` class which returns the claimable balance id for a given operation. +* Add support for additional _muxed and _muxed_id optional fields in Horizon's JSON responses (available since Horizon 2.4, following what's described in SEP 23). ## 0.25.0 diff --git a/src/main/java/org/stellar/sdk/responses/ImmutableListDeserializer.java b/src/main/java/org/stellar/sdk/responses/ImmutableListDeserializer.java new file mode 100644 index 000000000..9726d208e --- /dev/null +++ b/src/main/java/org/stellar/sdk/responses/ImmutableListDeserializer.java @@ -0,0 +1,24 @@ +package org.stellar.sdk.responses; + +import com.google.common.collect.ImmutableList; +import com.google.common.reflect.TypeToken; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +import java.lang.reflect.Type; +import java.util.List; + +public class ImmutableListDeserializer implements JsonDeserializer> { + + @Override + public ImmutableList deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + @SuppressWarnings("unchecked") + final TypeToken> immutableListToken = (TypeToken>) TypeToken.of(type); + final TypeToken> listToken = immutableListToken.getSupertype(List.class); + final List list = context.deserialize(json, listToken.getType()); + return ImmutableList.copyOf(list); + } + +} diff --git a/src/main/java/org/stellar/sdk/responses/MuxedAccount.java b/src/main/java/org/stellar/sdk/responses/MuxedAccount.java new file mode 100644 index 000000000..84e3f574a --- /dev/null +++ b/src/main/java/org/stellar/sdk/responses/MuxedAccount.java @@ -0,0 +1,43 @@ +package org.stellar.sdk.responses; + +import com.google.common.base.Objects; + +public class MuxedAccount { + private final String muxedAddress; + private final String unmuxedAddress; + private final Long id; + + public MuxedAccount(String muxedAddress, String unmuxedAddress, Long id) { + this.muxedAddress = muxedAddress; + this.unmuxedAddress = unmuxedAddress; + this.id = id; + } + + @Override + public String toString() { + return muxedAddress; + } + + public Long getId() { + return id; + } + + public String getUnmuxedAddress() { + return unmuxedAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (getClass() == o.getClass()) && Objects.equal(muxedAddress, ((MuxedAccount)o).muxedAddress) + && Objects.equal(unmuxedAddress, ((MuxedAccount)o).unmuxedAddress) + && Objects.equal(id, ((MuxedAccount)o).id); + } + + @Override + public int hashCode() { + return Objects.hashCode(muxedAddress, unmuxedAddress, id); + } +} diff --git a/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java b/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java index 1575988f5..6453c96d1 100644 --- a/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java +++ b/src/main/java/org/stellar/sdk/responses/OperationDeserializer.java @@ -1,5 +1,6 @@ package org.stellar.sdk.responses; +import com.google.common.collect.ImmutableList; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; @@ -23,6 +24,7 @@ public OperationResponse deserialize(JsonElement json, Type typeOfT, JsonDeseria .registerTypeAdapter(Asset.class, new AssetDeserializer()) .registerTypeAdapter(Predicate.class, new PredicateDeserializer()) .registerTypeAdapter(TransactionResponse.class, new TransactionDeserializer()) + .registerTypeAdapter(ImmutableList.class, new ImmutableListDeserializer()) .create(); int type = json.getAsJsonObject().get("type_i").getAsInt(); diff --git a/src/main/java/org/stellar/sdk/responses/TransactionResponse.java b/src/main/java/org/stellar/sdk/responses/TransactionResponse.java index 4d5c9c08d..7d58afa2f 100644 --- a/src/main/java/org/stellar/sdk/responses/TransactionResponse.java +++ b/src/main/java/org/stellar/sdk/responses/TransactionResponse.java @@ -17,86 +17,66 @@ */ public class TransactionResponse extends Response implements Pageable { @SerializedName("hash") - private final String hash; + private String hash; @SerializedName("ledger") - private final Long ledger; + private Long ledger; @SerializedName("created_at") - private final String createdAt; + private String createdAt; @SerializedName("source_account") - private final String sourceAccount; + private String sourceAccount; @SerializedName("fee_account") - private final String feeAccount; + private String feeAccount; @SerializedName("successful") - private final Boolean successful; + private Boolean successful; @SerializedName("paging_token") - private final String pagingToken; + private String pagingToken; @SerializedName("source_account_sequence") - private final Long sourceAccountSequence; + private Long sourceAccountSequence; @SerializedName("max_fee") - private final Long maxFee; + private Long maxFee; @SerializedName("fee_charged") - private final Long feeCharged; + private Long feeCharged; @SerializedName("operation_count") - private final Integer operationCount; + private Integer operationCount; @SerializedName("envelope_xdr") - private final String envelopeXdr; + private String envelopeXdr; @SerializedName("result_xdr") - private final String resultXdr; + private String resultXdr; @SerializedName("result_meta_xdr") - private final String resultMetaXdr; + private String resultMetaXdr; @SerializedName("signatures") - private final List signatures; + private List signatures; @SerializedName("fee_bump_transaction") - private final FeeBumpTransaction feeBumpTransaction; + private FeeBumpTransaction feeBumpTransaction; @SerializedName("inner_transaction") - private final InnerTransaction innerTransaction; + private InnerTransaction innerTransaction; + @SerializedName("account_muxed") + private String accountMuxed; + @SerializedName("account_muxed_id") + private Long accountMuxedId; + @SerializedName("fee_account_muxed") + private String feeAccountMuxed; + @SerializedName("fee_account_muxed_id") + private Long feeAccountMuxedId; @SerializedName("_links") - private final Links links; + private Links links; // GSON won't serialize `transient` variables automatically. We need this behaviour // because Memo is an abstract class and GSON tries to instantiate it. private transient Memo memo; - TransactionResponse( - String hash, - Long ledger, - String createdAt, - String sourceAccount, - String feeAccount, - Boolean successful, - String pagingToken, - Long sourceAccountSequence, - Long maxFee, - Long feeCharged, - Integer operationCount, - String envelopeXdr, - String resultXdr, - String resultMetaXdr, - Memo memo, - List signatures, - FeeBumpTransaction feeBumpTransaction, - InnerTransaction innerTransaction, - Links links - ) { - this.hash = hash; - this.ledger = ledger; - this.createdAt = createdAt; - this.sourceAccount = sourceAccount; - this.feeAccount = feeAccount; - this.successful = successful; - this.pagingToken = pagingToken; - this.sourceAccountSequence = sourceAccountSequence; - this.maxFee = maxFee; - this.feeCharged = feeCharged; - this.operationCount = operationCount; - this.envelopeXdr = envelopeXdr; - this.resultXdr = resultXdr; - this.resultMetaXdr = resultMetaXdr; - this.memo = memo; - this.signatures = signatures; - this.feeBumpTransaction = feeBumpTransaction; - this.innerTransaction = innerTransaction; - this.links = links; + public Optional getSourceAccountMuxed() { + if (this.accountMuxed == null || this.accountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.accountMuxed, this.sourceAccount, this.accountMuxedId)); + } + + public Optional getFeeAccountMuxed() { + if (this.feeAccountMuxed == null || this.feeAccountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.feeAccountMuxed, this.feeAccount, this.feeAccountMuxedId)); } public String getHash() { @@ -190,9 +170,9 @@ public Links getLinks() { */ public static class FeeBumpTransaction { @SerializedName("hash") - private final String hash; + private String hash; @SerializedName("signatures") - private final List signatures; + private List signatures; FeeBumpTransaction(String hash, List signatures) { this.hash = hash; @@ -216,11 +196,11 @@ public List getSignatures() { */ public static class InnerTransaction { @SerializedName("hash") - private final String hash; + private String hash; @SerializedName("signatures") - private final List signatures; + private List signatures; @SerializedName("max_fee") - private final Long maxFee; + private Long maxFee; InnerTransaction(String hash, List signatures, Long maxFee) { @@ -248,19 +228,19 @@ public Long getMaxFee() { */ public static class Links { @SerializedName("account") - private final Link account; + private Link account; @SerializedName("effects") - private final Link effects; + private Link effects; @SerializedName("ledger") - private final Link ledger; + private Link ledger; @SerializedName("operations") - private final Link operations; + private Link operations; @SerializedName("precedes") - private final Link precedes; + private Link precedes; @SerializedName("self") - private final Link self; + private Link self; @SerializedName("succeeds") - private final Link succeeds; + private Link succeeds; Links(Link account, Link effects, Link ledger, Link operations, Link self, Link precedes, Link succeeds) { this.account = account; diff --git a/src/main/java/org/stellar/sdk/responses/effects/EffectResponse.java b/src/main/java/org/stellar/sdk/responses/effects/EffectResponse.java index 83f9f37fe..fedee9ac2 100644 --- a/src/main/java/org/stellar/sdk/responses/effects/EffectResponse.java +++ b/src/main/java/org/stellar/sdk/responses/effects/EffectResponse.java @@ -1,8 +1,10 @@ package org.stellar.sdk.responses.effects; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.responses.Link; +import org.stellar.sdk.responses.MuxedAccount; import org.stellar.sdk.responses.Pageable; import org.stellar.sdk.responses.Response; @@ -14,15 +16,19 @@ */ public abstract class EffectResponse extends Response implements Pageable { @SerializedName("id") - protected String id; + private String id; @SerializedName("account") - protected String account; + private String account; + @SerializedName("account_muxed") + private String accountMuxed; + @SerializedName("account_muxed_id") + private Long accountMuxedId; @SerializedName("type") - protected String type; + private String type; @SerializedName("created_at") - protected String createdAt; + private String createdAt; @SerializedName("paging_token") - protected String pagingToken; + private String pagingToken; @SerializedName("_links") private Links links; @@ -34,6 +40,13 @@ public String getAccount() { return account; } + public Optional getAccountMuxed() { + if (this.accountMuxed == null || this.accountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.accountMuxed, this.account, this.accountMuxedId)); + } + /** *

Returns effect type. Possible types:

*
    diff --git a/src/main/java/org/stellar/sdk/responses/effects/TradeEffectResponse.java b/src/main/java/org/stellar/sdk/responses/effects/TradeEffectResponse.java index 15fe6e95c..fc07cf6eb 100644 --- a/src/main/java/org/stellar/sdk/responses/effects/TradeEffectResponse.java +++ b/src/main/java/org/stellar/sdk/responses/effects/TradeEffectResponse.java @@ -1,9 +1,11 @@ package org.stellar.sdk.responses.effects; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.Asset; import org.stellar.sdk.AssetTypeNative; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents trade effect response. @@ -13,39 +15,38 @@ */ public class TradeEffectResponse extends EffectResponse { @SerializedName("seller") - protected final String seller; + private String seller; + @SerializedName("seller_muxed") + private String sellerMuxed; + @SerializedName("seller_muxed_id") + private Long sellerMuxedId; + @SerializedName("offer_id") - protected final Long offerId; + private Long offerId; @SerializedName("sold_amount") - protected final String soldAmount; + private String soldAmount; @SerializedName("sold_asset_type") - protected final String soldAssetType; + private String soldAssetType; @SerializedName("sold_asset_code") - protected final String soldAssetCode; + private String soldAssetCode; @SerializedName("sold_asset_issuer") - protected final String soldAssetIssuer; + private String soldAssetIssuer; @SerializedName("bought_amount") - protected final String boughtAmount; + private String boughtAmount; @SerializedName("bought_asset_type") - protected final String boughtAssetType; + private String boughtAssetType; @SerializedName("bought_asset_code") - protected final String boughtAssetCode; + private String boughtAssetCode; @SerializedName("bought_asset_issuer") - protected final String boughtAssetIssuer; + private String boughtAssetIssuer; - TradeEffectResponse(String seller, Long offerId, String soldAmount, String soldAssetType, String soldAssetCode, String soldAssetIssuer, String boughtAmount, String boughtAssetType, String boughtAssetCode, String boughtAssetIssuer) { - this.seller = seller; - this.offerId = offerId; - this.soldAmount = soldAmount; - this.soldAssetType = soldAssetType; - this.soldAssetCode = soldAssetCode; - this.soldAssetIssuer = soldAssetIssuer; - this.boughtAmount = boughtAmount; - this.boughtAssetType = boughtAssetType; - this.boughtAssetCode = boughtAssetCode; - this.boughtAssetIssuer = boughtAssetIssuer; + public Optional getSellerMuxed() { + if (this.sellerMuxed == null || this.sellerMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.sellerMuxed, this.seller, this.sellerMuxedId)); } public String getSeller() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/AccountMergeOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/AccountMergeOperationResponse.java index a1f91a84d..7ca3eb652 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/AccountMergeOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/AccountMergeOperationResponse.java @@ -1,6 +1,8 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents AccountMerge operation response. @@ -10,13 +12,31 @@ */ public class AccountMergeOperationResponse extends OperationResponse { @SerializedName("account") - protected final String account; + private String account; + @SerializedName("account_muxed") + private String accountMuxed; + @SerializedName("account_muxed_id") + private Long accountMuxedId; + @SerializedName("into") - protected final String into; + private String into; + @SerializedName("into_muxed") + private String intoMuxed; + @SerializedName("into_muxed_id") + private Long intoMuxedId; + + public Optional getAccountMuxed() { + if (this.accountMuxed == null || this.accountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.accountMuxed, this.account, this.accountMuxedId)); + } - AccountMergeOperationResponse(String account, String into) { - this.account = account; - this.into = into; + public Optional getIntoMuxed() { + if (this.intoMuxed == null || this.intoMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.intoMuxed, this.into, this.intoMuxedId)); } public String getAccount() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/AllowTrustOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/AllowTrustOperationResponse.java index 5aa65485d..6785d038c 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/AllowTrustOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/AllowTrustOperationResponse.java @@ -1,9 +1,11 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.Asset; import org.stellar.sdk.AssetTypeNative; +import org.stellar.sdk.responses.MuxedAccount; /** * @deprecated As of release 0.24.0, replaced by {@link SetTrustLineFlagsOperationResponse} @@ -15,34 +17,35 @@ */ public class AllowTrustOperationResponse extends OperationResponse { @SerializedName("trustor") - protected final String trustor; + private String trustor; @SerializedName("trustee") - protected final String trustee; + private String trustee; + @SerializedName("trustee_muxed") + private String trusteeMuxed; + @SerializedName("trustee_muxed_id") + private Long trusteeMuxedId; @SerializedName("asset_type") - protected final String assetType; + private String assetType; @SerializedName("asset_code") - protected final String assetCode; + private String assetCode; @SerializedName("asset_issuer") - protected final String assetIssuer; + private String assetIssuer; @SerializedName("authorize") - protected final boolean authorize; + private boolean authorize; @SerializedName("authorize_to_maintain_liabilities") - protected final boolean authorizeToMaintainLiabilities; - - AllowTrustOperationResponse(boolean authorize, boolean authorizeToMaintainLiabilities, String assetIssuer, String assetCode, String assetType, String trustee, String trustor) { - this.authorize = authorize; - this.authorizeToMaintainLiabilities = authorizeToMaintainLiabilities; - this.assetIssuer = assetIssuer; - this.assetCode = assetCode; - this.assetType = assetType; - this.trustee = trustee; - this.trustor = trustor; - } - + private boolean authorizeToMaintainLiabilities; + public String getTrustor() { return trustor; } + public Optional getTrusteeMuxed() { + if (this.trusteeMuxed == null || this.trusteeMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.trusteeMuxed, this.trustee, this.trusteeMuxedId)); + } + public String getTrustee() { return trustee; } diff --git a/src/main/java/org/stellar/sdk/responses/operations/ChangeTrustOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/ChangeTrustOperationResponse.java index c9b27ceb8..78f3d1281 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/ChangeTrustOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/ChangeTrustOperationResponse.java @@ -1,9 +1,11 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.Asset; import org.stellar.sdk.AssetTypeNative; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents ChangeTrust operation response. @@ -13,25 +15,27 @@ */ public class ChangeTrustOperationResponse extends OperationResponse { @SerializedName("trustor") - protected final String trustor; + private String trustor; + @SerializedName("trustor_muxed") + private String trustorMuxed; + @SerializedName("trustor_muxed_id") + private Long trustorMuxedId; @SerializedName("trustee") - protected final String trustee; + private String trustee; @SerializedName("asset_type") - protected final String assetType; + private String assetType; @SerializedName("asset_code") - protected final String assetCode; + private String assetCode; @SerializedName("asset_issuer") - protected final String assetIssuer; + private String assetIssuer; @SerializedName("limit") - protected final String limit; - - ChangeTrustOperationResponse(String trustor, String trustee, String assetType, String assetCode, String assetIssuer, String limit) { - this.trustor = trustor; - this.trustee = trustee; - this.assetType = assetType; - this.assetCode = assetCode; - this.assetIssuer = assetIssuer; - this.limit = limit; + private String limit; + + public Optional getTrustorMuxed() { + if (this.trustorMuxed == null || this.trustorMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.trustorMuxed, this.trustor, this.trustorMuxedId)); } public String getTrustor() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/ClaimClaimableBalanceOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/ClaimClaimableBalanceOperationResponse.java index 9a657ed68..b70c003ec 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/ClaimClaimableBalanceOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/ClaimClaimableBalanceOperationResponse.java @@ -1,6 +1,8 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents ClaimClaimableBalance operation response. @@ -9,13 +11,19 @@ */ public class ClaimClaimableBalanceOperationResponse extends OperationResponse { @SerializedName("balance_id") - private final String balanceId; + private String balanceId; @SerializedName("claimant") - protected final String claimant; + private String claimant; + @SerializedName("claimant_muxed") + private String claimantMuxed; + @SerializedName("claimant_muxed_id") + private Long claimantMuxedId; - public ClaimClaimableBalanceOperationResponse(String balanceId, String claimant) { - this.balanceId = balanceId; - this.claimant = claimant; + public Optional getClaimantMuxed() { + if (this.claimantMuxed == null || this.claimantMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.claimantMuxed, this.claimant, this.claimantMuxedId)); } public String getBalanceId() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/ClawbackOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/ClawbackOperationResponse.java index 2882eae42..00a7b6f89 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/ClawbackOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/ClawbackOperationResponse.java @@ -1,7 +1,9 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.Asset; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents a Clawback operation response. @@ -11,23 +13,19 @@ */ public class ClawbackOperationResponse extends OperationResponse { @SerializedName("asset_type") - protected final String assetType; + private String assetType; @SerializedName("asset_code") - protected final String assetCode; + private String assetCode; @SerializedName("asset_issuer") - protected final String assetIssuer; + private String assetIssuer; @SerializedName("amount") - protected final String amount; + private String amount; @SerializedName("from") - protected final String from; - - public ClawbackOperationResponse(String assetType, String assetCode, String assetIssuer, String amount, String from) { - this.assetType = assetType; - this.assetCode = assetCode; - this.assetIssuer = assetIssuer; - this.amount = amount; - this.from = from; - } + private String from; + @SerializedName("from_muxed") + private String fromMuxed; + @SerializedName("from_muxed_id") + private Long fromMuxedId; public String getAssetType() { return assetType; @@ -53,4 +51,11 @@ public String getFrom() { return from; } + public Optional getFromMuxed() { + if (this.fromMuxed == null || this.fromMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.fromMuxed, this.from, this.fromMuxedId)); + } + } diff --git a/src/main/java/org/stellar/sdk/responses/operations/CreateAccountOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/CreateAccountOperationResponse.java index 67194e638..61f8d6f79 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/CreateAccountOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/CreateAccountOperationResponse.java @@ -1,6 +1,8 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents CreateAccount operation response. @@ -10,16 +12,21 @@ */ public class CreateAccountOperationResponse extends OperationResponse { @SerializedName("account") - protected final String account; + private String account; @SerializedName("funder") - protected final String funder; + private String funder; + @SerializedName("funder_muxed") + private String funderAccountMuxed; + @SerializedName("funder_muxed_id") + private Long funderAccountMuxedId; @SerializedName("starting_balance") - protected final String startingBalance; + private String startingBalance; - CreateAccountOperationResponse(String funder, String startingBalance, String account) { - this.funder = funder; - this.startingBalance = startingBalance; - this.account = account; + public Optional getFunderMuxed() { + if (this.funderAccountMuxed == null || this.funderAccountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.funderAccountMuxed, this.funder, this.funderAccountMuxedId)); } public String getAccount() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/EndSponsoringFutureReservesOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/EndSponsoringFutureReservesOperationResponse.java index 3645c5de3..5a3d5cadc 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/EndSponsoringFutureReservesOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/EndSponsoringFutureReservesOperationResponse.java @@ -1,6 +1,8 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; +import org.stellar.sdk.responses.MuxedAccount; /** * Represents EndSponsoringFutureReserves operation response. @@ -9,10 +11,17 @@ */ public class EndSponsoringFutureReservesOperationResponse extends OperationResponse { @SerializedName("begin_sponsor") - private final String beginSponsor; + private String beginSponsor; + @SerializedName("begin_sponsor_muxed") + private String beginSponsorMuxed; + @SerializedName("begin_sponsor_muxed_id") + private Long beginSponsorMuxedId; - public EndSponsoringFutureReservesOperationResponse(String beginSponsor) { - this.beginSponsor = beginSponsor; + public Optional getBeginSponsorMuxed() { + if (this.beginSponsorMuxed == null || this.beginSponsorMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.beginSponsorMuxed, this.beginSponsor, this.beginSponsorMuxedId)); } public String getBeginSponsor() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/OperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/OperationResponse.java index 46a67d586..9dfbf3d86 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/OperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/OperationResponse.java @@ -3,10 +3,7 @@ import com.google.common.base.Optional; import com.google.gson.annotations.SerializedName; -import org.stellar.sdk.responses.Link; -import org.stellar.sdk.responses.Pageable; -import org.stellar.sdk.responses.Response; -import org.stellar.sdk.responses.TransactionResponse; +import org.stellar.sdk.responses.*; /** * Abstract class for operation responses. @@ -16,24 +13,35 @@ */ public abstract class OperationResponse extends Response implements Pageable { @SerializedName("id") - protected Long id; + private Long id; @SerializedName("source_account") - protected String sourceAccount; + private String sourceAccount; + @SerializedName("source_account_muxed") + private String sourceAccountMuxed; + @SerializedName("source_account_muxed_id") + private Long sourceAccountMuxedId; @SerializedName("paging_token") - protected String pagingToken; + private String pagingToken; @SerializedName("created_at") - protected String createdAt; + private String createdAt; @SerializedName("transaction_hash") - protected String transactionHash; + private String transactionHash; @SerializedName("transaction_successful") - protected Boolean transactionSuccessful; + private Boolean transactionSuccessful; @SerializedName("type") - protected String type; + private String type; @SerializedName("_links") private Links links; @SerializedName("transaction") private TransactionResponse transaction; + public Optional getSourceAccountMuxed() { + if (this.sourceAccountMuxed == null|| this.sourceAccountMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.sourceAccountMuxed, this.sourceAccount, this.sourceAccountMuxedId)); + } + public Long getId() { return id; } diff --git a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentBaseOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentBaseOperationResponse.java index 496af41c2..13e8036a1 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentBaseOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentBaseOperationResponse.java @@ -1,53 +1,48 @@ package org.stellar.sdk.responses.operations; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.gson.annotations.SerializedName; import org.stellar.sdk.Asset; import org.stellar.sdk.AssetTypeNative; +import org.stellar.sdk.responses.MuxedAccount; import java.util.List; public abstract class PathPaymentBaseOperationResponse extends OperationResponse { @SerializedName("amount") - protected final String amount; + private String amount; @SerializedName("source_amount") - protected final String sourceAmount; + private String sourceAmount; @SerializedName("from") - protected final String from; + private String from; + @SerializedName("from_muxed") + private String fromMuxed; + @SerializedName("from_muxed_id") + private Long fromMuxedId; @SerializedName("to") - protected final String to; + private String to; + @SerializedName("to_muxed") + private String toMuxed; + @SerializedName("to_muxed_id") + private Long toMuxedId; @SerializedName("asset_type") - protected final String assetType; + private String assetType; @SerializedName("asset_code") - protected final String assetCode; + private String assetCode; @SerializedName("asset_issuer") - protected final String assetIssuer; + private String assetIssuer; @SerializedName("source_asset_type") - protected final String sourceAssetType; + private String sourceAssetType; @SerializedName("source_asset_code") - protected final String sourceAssetCode; + private String sourceAssetCode; @SerializedName("source_asset_issuer") - protected final String sourceAssetIssuer; + private String sourceAssetIssuer; @SerializedName("path") - protected final List path; - - - public PathPaymentBaseOperationResponse(String amount, String sourceAmount, String from, String to, String assetType, String assetCode, String assetIssuer, String sourceAssetType, String sourceAssetCode, String sourceAssetIssuer, List path) { - this.amount = amount; - this.sourceAmount = sourceAmount; - this.from = from; - this.to = to; - this.assetType = assetType; - this.assetCode = assetCode; - this.assetIssuer = assetIssuer; - this.sourceAssetType = sourceAssetType; - this.sourceAssetCode = sourceAssetCode; - this.sourceAssetIssuer = sourceAssetIssuer; - this.path = ImmutableList.copyOf(path); - } + private ImmutableList path; public String getAmount() { return amount; @@ -61,6 +56,20 @@ public String getFrom() { return from; } + public Optional getFromMuxed() { + if (this.fromMuxed == null || this.fromMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.fromMuxed, this.from, this.fromMuxedId)); + } + + public Optional getToMuxed() { + if (this.toMuxed == null || this.toMuxed.isEmpty()) { + return Optional.absent(); + } + return Optional.of(new MuxedAccount(this.toMuxed, this.to, this.toMuxedId)); + } + public String getTo() { return to; } diff --git a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictReceiveOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictReceiveOperationResponse.java index 6e7744ed1..7bcc7f859 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictReceiveOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictReceiveOperationResponse.java @@ -14,12 +14,7 @@ */ public class PathPaymentStrictReceiveOperationResponse extends PathPaymentBaseOperationResponse { @SerializedName("source_max") - protected final String sourceMax; - - public PathPaymentStrictReceiveOperationResponse(String amount, String sourceAmount, String sourceMax, String from, String to, String assetType, String assetCode, String assetIssuer, String sourceAssetType, String sourceAssetCode, String sourceAssetIssuer, List path) { - super(amount, sourceAmount, from, to, assetType, assetCode, assetIssuer, sourceAssetType, sourceAssetCode, sourceAssetIssuer, path); - this.sourceMax = sourceMax; - } + private String sourceMax; public String getSourceMax() { diff --git a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictSendOperationResponse.java b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictSendOperationResponse.java index 489f78647..7e54abd05 100644 --- a/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictSendOperationResponse.java +++ b/src/main/java/org/stellar/sdk/responses/operations/PathPaymentStrictSendOperationResponse.java @@ -14,12 +14,7 @@ */ public class PathPaymentStrictSendOperationResponse extends PathPaymentBaseOperationResponse { @SerializedName("destination_min") - protected final String destinationMin; - - public PathPaymentStrictSendOperationResponse(String amount, String sourceAmount, String destinationMin, String from, String to, String assetType, String assetCode, String assetIssuer, String sourceAssetType, String sourceAssetCode, String sourceAssetIssuer, List path) { - super(amount, sourceAmount, from, to, assetType, assetCode, assetIssuer, sourceAssetType, sourceAssetCode, sourceAssetIssuer, path); - this.destinationMin = destinationMin; - } + private String destinationMin; public String getDestinationMin() { return destinationMin; diff --git a/src/test/java/org/stellar/sdk/responses/EffectsPageDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/EffectsPageDeserializerTest.java index a5b722b5a..58aa5d8d6 100644 --- a/src/test/java/org/stellar/sdk/responses/EffectsPageDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/EffectsPageDeserializerTest.java @@ -8,6 +8,7 @@ import org.stellar.sdk.responses.effects.AccountCreatedEffectResponse; import org.stellar.sdk.responses.effects.EffectResponse; import org.stellar.sdk.responses.effects.SignerCreatedEffectResponse; +import org.stellar.sdk.responses.effects.TradeEffectResponse; public class EffectsPageDeserializerTest extends TestCase { @Test @@ -25,6 +26,26 @@ public void testDeserialize() { assertEquals(effectsPage.getLinks().getNext().getHref(), "http://horizon-testnet.stellar.org/effects?order=desc&limit=10&cursor=3962163165138945-3"); } + @Test + public void testTradesEffects() { + Page effectsPage = GsonSingleton.getInstance().fromJson(tradesJson, new TypeToken>() {}.getType()); + + TradeEffectResponse first = (TradeEffectResponse) effectsPage.getRecords().get(0); + TradeEffectResponse second = (TradeEffectResponse) effectsPage.getRecords().get(1); + + assertEquals(first.getAccountMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + assertFalse(second.getAccountMuxed().isPresent()); + + assertEquals(first.getSellerMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(first.getSellerMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(first.getSellerMuxed().get().getId().longValue(), 420l); + assertFalse(second.getSellerMuxed().isPresent()); + } + String json = "{\n" + " \"_links\": {\n" + " \"self\": {\n" + @@ -239,4 +260,80 @@ public void testDeserialize() { " ]\n" + " }\n" + "}"; + + String tradesJson = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/3697472920621057/effects?cursor=\\u0026limit=2\\u0026order=asc\"\n" + + " },\n" + + " \"next\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/3697472920621057/effects?cursor=3697472920621057-2\\u0026limit=2\\u0026order=asc\"\n" + + " },\n" + + " \"prev\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/3697472920621057/effects?cursor=3697472920621057-1\\u0026limit=2\\u0026order=desc\"\n" + + " }\n" + + " },\n" + + " \"_embedded\": {\n" + + " \"records\": [\n" + + " {\n" + + " \"_links\": {\n" + + " \"operation\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/3697472920621057\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=desc\\u0026cursor=3697472920621057-1\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=asc\\u0026cursor=3697472920621057-1\"\n" + + " }\n" + + " },\n" + + " \"id\": \"0003697472920621057-0000000001\",\n" + + " \"paging_token\": \"3697472920621057-1\",\n" + + " \"account\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"account_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"account_muxed_id\": \"123\",\n" + + " \"type\": \"trade\",\n" + + " \"type_i\": 33,\n" + + " \"created_at\": \"2015-11-18T03:47:47Z\",\n" + + " \"seller\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"seller_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"seller_muxed_id\": \"420\",\n" + + " \"offer_id\": \"9\",\n" + + " \"sold_amount\": \"2.6700000\",\n" + + " \"sold_asset_type\": \"credit_alphanum4\",\n" + + " \"sold_asset_code\": \"JPY\",\n" + + " \"sold_asset_issuer\": \"GBVAOIACNSB7OVUXJYC5UE2D4YK2F7A24T7EE5YOMN4CE6GCHUTOUQXM\",\n" + + " \"bought_amount\": \"10.0000000\",\n" + + " \"bought_asset_type\": \"native\"\n" + + " },\n" + + " {\n" + + " \"_links\": {\n" + + " \"operation\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/3697472920621057\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=desc\\u0026cursor=3697472920621057-2\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=asc\\u0026cursor=3697472920621057-2\"\n" + + " }\n" + + " },\n" + + " \"id\": \"0003697472920621057-0000000002\",\n" + + " \"paging_token\": \"3697472920621057-2\",\n" + + " \"account\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"type\": \"trade\",\n" + + " \"type_i\": 33,\n" + + " \"created_at\": \"2015-11-18T03:47:47Z\",\n" + + " \"seller\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"offer_id\": \"9\",\n" + + " \"sold_amount\": \"10.0000000\",\n" + + " \"sold_asset_type\": \"native\",\n" + + " \"bought_amount\": \"2.6700000\",\n" + + " \"bought_asset_type\": \"credit_alphanum4\",\n" + + " \"bought_asset_code\": \"JPY\",\n" + + " \"bought_asset_issuer\": \"GBVAOIACNSB7OVUXJYC5UE2D4YK2F7A24T7EE5YOMN4CE6GCHUTOUQXM\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; } diff --git a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java index 0a330dd68..b3aa84c14 100644 --- a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java @@ -46,6 +46,7 @@ public void testDeserializeCreateAccountOperation() { assertEquals(operation.getPagingToken(), "3936840037961729"); assertEquals(operation.getId(), new Long(3936840037961729L)); assertNull(operation.isTransactionSuccessful()); + assertFalse(operation.getFunderMuxed().isPresent()); assertEquals(operation.getAccount(), "GAR4DDXYNSN2CORG3XQFLAPWYKTUMLZYHYWV4Y2YJJ4JO6ZJFXMJD7PT"); assertEquals(operation.getStartingBalance(), "299454.904954"); @@ -58,6 +59,56 @@ public void testDeserializeCreateAccountOperation() { assertEquals(operation.getLinks().getTransaction().getHref(), "/transactions/75608563ae63757ffc0650d84d1d13c0f3cd4970a294a2a6b43e3f454e0f9e6d"); } + @Test + public void testDeserializeMuxedCreateAccountOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/3936840037961729/effects{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=3936840037961729\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/3936840037961729\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=3936840037961729\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/75608563ae63757ffc0650d84d1d13c0f3cd4970a294a2a6b43e3f454e0f9e6d\"\n" + + " }\n" + + " },\n" + + " \"account\": \"GAR4DDXYNSN2CORG3XQFLAPWYKTUMLZYHYWV4Y2YJJ4JO6ZJFXMJD7PT\",\n" + + " \"funder\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"funder_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"funder_muxed_id\": \"420\",\n" + + " \"id\": 3936840037961729,\n" + + " \"paging_token\": \"3936840037961729\",\n" + + " \"source_account\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"source_account_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"source_account_muxed_id\": \"123\",\n" + + " \"starting_balance\": \"299454.904954\",\n" + + " \"type\": \"create_account\",\n" + + " \"type_i\": 0\n" + + "}"; + CreateAccountOperationResponse operation = (CreateAccountOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getAccount(), "GAR4DDXYNSN2CORG3XQFLAPWYKTUMLZYHYWV4Y2YJJ4JO6ZJFXMJD7PT"); + + assertEquals(operation.getSourceAccountMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + + assertEquals(operation.getFunder(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getFunderMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getFunderMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getFunderMuxed().get().getId().longValue(), 420l); + } + @Test public void testDeserializePaymentOperation() { String json = "{\n" + @@ -187,6 +238,52 @@ public void testDeserializeAllowTrustOperation() { assertEquals(operation.isAuthorize(), true); assertEquals(operation.isAuthorizedToMaintainLiabilities(), false); assertEquals(operation.getAsset(), Asset.createNonNativeAsset("EUR", "GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM")); + assertFalse(operation.getTrusteeMuxed().isPresent()); + } + + @Test + public void testDeserializeMuxedAllowTrustOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/operations/3602979345141761\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/transactions/1f265c075e8559ee4c21a32ae53337658e52d7504841adad4144c37143ea01a2\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/operations/3602979345141761/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/effects?order=desc\\u0026cursor=3602979345141761\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/effects?order=asc\\u0026cursor=3602979345141761\"\n" + + " }\n" + + " },\n" + + " \"id\": \"3602979345141761\",\n" + + " \"paging_token\": \"3602979345141761\",\n" + + " \"source_account\": \"GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM\",\n" + + " \"type\": \"allow_trust\",\n" + + " \"type_i\": 7,\n" + + " \"asset_type\": \"credit_alphanum4\",\n" + + " \"asset_code\": \"EUR\",\n" + + " \"asset_issuer\": \"GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM\",\n" + + " \"trustee\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"trustee_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"trustee_muxed_id\": \"420\",\n" + + " \"trustor\": \"GDZ55LVXECRTW4G36EZPTHI4XIYS5JUC33TUS22UOETVFVOQ77JXWY4F\",\n" + + " \"authorize\": true\n," + + " \"authorize_to_maintain_liabilities\": false\n" + + " }"; + + AllowTrustOperationResponse operation = (AllowTrustOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getTrustor(), "GDZ55LVXECRTW4G36EZPTHI4XIYS5JUC33TUS22UOETVFVOQ77JXWY4F"); + assertEquals(operation.getTrustee(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getTrusteeMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getTrusteeMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getTrusteeMuxed().get().getId().longValue(), 420l); } @Test @@ -271,6 +368,51 @@ public void testDeserializeChangeTrustOperation() { assertEquals(operation.getTrustor(), "GDZ55LVXECRTW4G36EZPTHI4XIYS5JUC33TUS22UOETVFVOQ77JXWY4F"); assertEquals(operation.getLimit(), "922337203685.4775807"); assertEquals(operation.getAsset(), Asset.createNonNativeAsset("EUR", "GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM")); + assertFalse(operation.getTrustorMuxed().isPresent()); + } + + @Test + public void testDeserializeMuxedChangeTrustOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/operations/3602970755207169\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/transactions/8d409a788543895843d269c3f97a2d6a2ebca6e9f8f9a7ae593457b5c0ba6644\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/operations/3602970755207169/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/effects?order=desc\\u0026cursor=3602970755207169\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"//horizon-testnet.stellar.org/effects?order=asc\\u0026cursor=3602970755207169\"\n" + + " }\n" + + " },\n" + + " \"id\": \"3602970755207169\",\n" + + " \"paging_token\": \"3602970755207169\",\n" + + " \"source_account\": \"GDZ55LVXECRTW4G36EZPTHI4XIYS5JUC33TUS22UOETVFVOQ77JXWY4F\",\n" + + " \"type\": \"change_trust\",\n" + + " \"type_i\": 6,\n" + + " \"asset_type\": \"credit_alphanum4\",\n" + + " \"asset_code\": \"EUR\",\n" + + " \"asset_issuer\": \"GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM\",\n" + + " \"limit\": \"922337203685.4775807\",\n" + + " \"trustee\": \"GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM\",\n" + + " \"trustor\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"trustor_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"trustor_muxed_id\": \"420\"\n" + + " }"; + + ChangeTrustOperationResponse operation = (ChangeTrustOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getTrustee(), "GDIROJW2YHMSFZJJ4R5XWWNUVND5I45YEWS5DSFKXCHMADZ5V374U2LM"); + assertEquals(operation.getTrustor(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getTrustorMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getTrustorMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getTrustorMuxed().get().getId().longValue(), 420l); } @Test @@ -374,36 +516,86 @@ public void testDeserializeSetOptionsOperationWithNonEd25519Key() { @Test public void testDeserializeAccountMergeOperation() { String json = "{\n" + - " \"_links\": {\n" + - " \"self\": {\n" + - " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185\"\n" + - " },\n" + - " \"transaction\": {\n" + - " \"href\": \"http://horizon-testnet.stellar.org/transactions/68f4d37780e2a85f5698b73977126a595dff99aed852f14a7eb39221ce1f96d5\"\n" + - " },\n" + - " \"effects\": {\n" + - " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185/effects\"\n" + - " },\n" + - " \"succeeds\": {\n" + - " \"href\": \"http://horizon-testnet.stellar.org/effects?order=desc\\u0026cursor=3424497684189185\"\n" + - " },\n" + - " \"precedes\": {\n" + - " \"href\": \"http://horizon-testnet.stellar.org/effects?order=asc\\u0026cursor=3424497684189185\"\n" + - " }\n" + - " },\n" + - " \"id\": \"3424497684189185\",\n" + - " \"paging_token\": \"3424497684189185\",\n" + - " \"source_account\": \"GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2\",\n" + - " \"type\": \"account_merge\",\n" + - " \"type_i\": 8,\n" + - " \"account\": \"GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2\",\n" + - " \"into\": \"GAZWSWPDQTBHFIPBY4FEDFW2J6E2LE7SZHJWGDZO6Q63W7DBSRICO2KN\"\n" + - " }"; + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/transactions/68f4d37780e2a85f5698b73977126a595dff99aed852f14a7eb39221ce1f96d5\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/effects?order=desc\\u0026cursor=3424497684189185\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/effects?order=asc\\u0026cursor=3424497684189185\"\n" + + " }\n" + + " },\n" + + " \"id\": \"3424497684189185\",\n" + + " \"paging_token\": \"3424497684189185\",\n" + + " \"source_account\": \"GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2\",\n" + + " \"type\": \"account_merge\",\n" + + " \"type_i\": 8,\n" + + " \"account\": \"GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2\",\n" + + " \"into\": \"GAZWSWPDQTBHFIPBY4FEDFW2J6E2LE7SZHJWGDZO6Q63W7DBSRICO2KN\"\n" + + " }"; AccountMergeOperationResponse operation = (AccountMergeOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); assertEquals(operation.getAccount(), "GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2"); assertEquals(operation.getInto(), "GAZWSWPDQTBHFIPBY4FEDFW2J6E2LE7SZHJWGDZO6Q63W7DBSRICO2KN"); + assertFalse(operation.getIntoMuxed().isPresent()); + assertFalse(operation.getAccountMuxed().isPresent()); + } + + @Test + public void testDeserializeMuxedAccountMergeOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/transactions/68f4d37780e2a85f5698b73977126a595dff99aed852f14a7eb39221ce1f96d5\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/operations/3424497684189185/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/effects?order=desc\\u0026cursor=3424497684189185\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"http://horizon-testnet.stellar.org/effects?order=asc\\u0026cursor=3424497684189185\"\n" + + " }\n" + + " },\n" + + " \"id\": \"3424497684189185\",\n" + + " \"paging_token\": \"3424497684189185\",\n" + + " \"source_account\": \"GD6GKRABNDVYDETEZJQEPS7IBQMERCN44R5RCI4LJNX6BMYQM2KPGGZ2\",\n" + + " \"type\": \"account_merge\",\n" + + " \"type_i\": 8,\n" + + " \"account\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"account_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"account_muxed_id\": \"123\",\n" + + " \"into\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"into_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"into_muxed_id\": \"420\"\n" + + " }"; + + AccountMergeOperationResponse operation = (AccountMergeOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getAccount(), "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L"); + assertEquals(operation.getInto(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + + assertEquals(operation.getAccountMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + assertEquals(operation.getIntoMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getIntoMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getIntoMuxed().get().getId().longValue(), 420l); } @Test @@ -543,8 +735,11 @@ public void testDeserializePathPaymentStrictSendOperation() { PathPaymentStrictSendOperationResponse operation = (PathPaymentStrictSendOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + assertFalse(operation.getSourceAccountMuxed().isPresent()); assertEquals(operation.getFrom(), "GC45JH537XZD4DY4WTV5PCUJL4KPOIE4WMGX5OP5KSPS2OLGRUOVVIGD"); + assertFalse(operation.getFromMuxed().isPresent()); assertEquals(operation.getTo(), "GC45JH537XZD4DY4WTV5PCUJL4KPOIE4WMGX5OP5KSPS2OLGRUOVVIGD"); + assertFalse(operation.getToMuxed().isPresent()); assertEquals(operation.getAmount(), "2.5000000"); assertEquals(operation.getSourceAmount(), "1.1777000"); assertEquals(operation.getDestinationMin(), "1.1779523"); @@ -557,6 +752,64 @@ public void testDeserializePathPaymentStrictSendOperation() { assertEquals(operation.getSourceAsset(), Asset.createNonNativeAsset("XRP", "GBVOL67TMUQBGL4TZYNMY3ZQ5WGQYFPFD5VJRWXR72VA33VFNL225PL5")); } + @Test + public void testDeserializeMuxedPathPaymentStrictSendOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/75252830662840321\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"https://horizon.stellar.org/transactions/fb2f5655c70a459220ac09eb3d6870422b58dcf5c5ffb5e5b21817b4d248826e\"\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"https://horizon.stellar.org/operations/75252830662840321/effects\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=desc\\u0026cursor=75252830662840321\"\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"https://horizon.stellar.org/effects?order=asc\\u0026cursor=75252830662840321\"\n" + + " }\n" + + " },\n" + + " \"id\": \"75252830662840321\",\n" + + " \"paging_token\": \"75252830662840321\",\n" + + " \"source_account\": \"GC45JH537XZD4DY4WTV5PCUJL4KPOIE4WMGX5OP5KSPS2OLGRUOVVIGD\",\n" + + " \"type\": \"path_payment_strict_send\",\n" + + " \"type_i\": 13,\n" + + " \"created_at\": \"2018-04-24T12:58:12Z\",\n" + + " \"transaction_hash\": \"fb2f5655c70a459220ac09eb3d6870422b58dcf5c5ffb5e5b21817b4d248826e\",\n" + + " \"asset_type\": \"native\",\n" + + " \"from\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"from_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"from_muxed_id\": \"123\",\n" + + " \"to\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"to_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"to_muxed_id\": \"420\",\n" + + " \"amount\": \"2.5000000\",\n" + + " \"path\": [{\"asset_type\": \"native\"}, {\"asset_type\": \"credit_alphanum4\", \"asset_code\": \"CNY\", \"asset_issuer\": \"GAREELUB43IRHWEASCFBLKHURCGMHE5IF6XSE7EXDLACYHGRHM43RFOX\"}, {\"asset_type\": \"credit_alphanum12\", \"asset_code\": \"CNYMNL\", \"asset_issuer\": \"GAREELUB43IRHWEASCFBLKHURCGMHE5IF6XSE7EXDLACYHGRHM43RFOX\"}],\n" + + " \"source_amount\": \"1.1777000\",\n"+ + " \"destination_min\": \"1.1779523\",\n" + + " \"source_asset_type\": \"credit_alphanum4\",\n" + + " \"source_asset_code\": \"XRP\",\n" + + " \"source_asset_issuer\": \"GBVOL67TMUQBGL4TZYNMY3ZQ5WGQYFPFD5VJRWXR72VA33VFNL225PL5\"\n" + + "}"; + + PathPaymentStrictSendOperationResponse operation = (PathPaymentStrictSendOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getFrom(), "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L"); + assertEquals(operation.getFromMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + + assertEquals(operation.getTo(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getToMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getToMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getToMuxed().get().getId().longValue(), 420l); + } + @Test public void testDeserializePathPaymentOperationSourceAssetNative() { String json = "{\n" + @@ -742,6 +995,164 @@ public void testDeserializeBumpSequenceOperation() { assertEquals(operation.getBumpTo(), new Long(79473726952833048L)); } + @Test + public void testDeserializeEndSponsoringFutureReservesOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/12884914177/effects/{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/12884914177\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/12884914176\"\n" + + " }\n" + + " },\n" + + " \"id\": 12884914177,\n" + + " \"paging_token\": \"12884914177\",\n" + + " \"type_i\": 17,\n" + + " \"type\": \"end_sponsoring_future_reserves\",\n" + + " \"begin_sponsor\": \"GDRW375MAYR46ODGF2WGANQC2RRZL7O246DYHHCGWTV2RE7IHE2QUQLD\"\n" + + "}"; + + EndSponsoringFutureReservesOperationResponse operation = (EndSponsoringFutureReservesOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getId(), new Long(12884914177L)); + assertEquals(operation.getBeginSponsor(), "GDRW375MAYR46ODGF2WGANQC2RRZL7O246DYHHCGWTV2RE7IHE2QUQLD"); + assertFalse(operation.getBeginSponsorMuxed().isPresent()); + assertEquals(operation.getType(), "end_sponsoring_future_reserves"); + } + + @Test + public void testDeserializeMuxedEndSponsoringFutureReservesOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/12884914177/effects/{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/12884914177\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/12884914176\"\n" + + " }\n" + + " },\n" + + " \"id\": 12884914177,\n" + + " \"paging_token\": \"12884914177\",\n" + + " \"type_i\": 17,\n" + + " \"type\": \"end_sponsoring_future_reserves\",\n" + + " \"begin_sponsor\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"begin_sponsor_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"begin_sponsor_muxed_id\": \"420\"\n" + + "}"; + + EndSponsoringFutureReservesOperationResponse operation = (EndSponsoringFutureReservesOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getId(), new Long(12884914177L)); + assertEquals(operation.getBeginSponsor(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(operation.getBeginSponsorMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(operation.getBeginSponsorMuxed().get().getId().longValue(), 420l); + assertEquals(operation.getType(), "end_sponsoring_future_reserves"); + } + + @Test + public void testDeserializeClaimClaimableBalanceOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/12884914177/effects/{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/12884914177\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/12884914176\"\n" + + " }\n" + + " },\n" + + " \"id\": 12884914177,\n" + + " \"paging_token\": \"12884914177\",\n" + + " \"type_i\": 15,\n" + + " \"type\": \"claim_claimable_balance\",\n" + + " \"claimant\": \"GDRW375MAYR46ODGF2WGANQC2RRZL7O246DYHHCGWTV2RE7IHE2QUQLD\",\n" + + " \"balance_id\": \"00000000178826fbfe339e1f5c53417c6fedfe2c05e8bec14303143ec46b38981b09c3f9\"\n" + + "}"; + + ClaimClaimableBalanceOperationResponse operation = (ClaimClaimableBalanceOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getId(), new Long(12884914177L)); + assertEquals(operation.getBalanceId(), "00000000178826fbfe339e1f5c53417c6fedfe2c05e8bec14303143ec46b38981b09c3f9"); + assertEquals(operation.getClaimant(), "GDRW375MAYR46ODGF2WGANQC2RRZL7O246DYHHCGWTV2RE7IHE2QUQLD"); + assertFalse(operation.getClaimantMuxed().isPresent()); + assertEquals(operation.getType(), "claim_claimable_balance"); + } + + @Test + public void testDeserializeMuxedClaimClaimableBalanceOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/12884914177/effects/{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/12884914177\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/12884914176\"\n" + + " }\n" + + " },\n" + + " \"id\": 12884914177,\n" + + " \"paging_token\": \"12884914177\",\n" + + " \"type_i\": 15,\n" + + " \"type\": \"claim_claimable_balance\",\n" + + " \"claimant\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"claimant_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"claimant_muxed_id\": \"123\",\n" + + " \"balance_id\": \"00000000178826fbfe339e1f5c53417c6fedfe2c05e8bec14303143ec46b38981b09c3f9\"\n" + + "}"; + + ClaimClaimableBalanceOperationResponse operation = (ClaimClaimableBalanceOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getId(), new Long(12884914177L)); + assertEquals(operation.getBalanceId(), "00000000178826fbfe339e1f5c53417c6fedfe2c05e8bec14303143ec46b38981b09c3f9"); + assertEquals(operation.getClaimant(), "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L"); + assertEquals(operation.getClaimantMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + assertEquals(operation.getType(), "claim_claimable_balance"); + } + + @Test public void testDeserializeClawbackClaimableBalanceOperation() { String json = "{\n" + @@ -817,6 +1228,50 @@ public void testDeserializeClawbackOperation() { assertEquals(operation.getAssetIssuer(), "GCWVFBJ24754I5GXG4JOEB72GJCL3MKWC7VAEYWKGQHPVH3ENPNBSKWS"); assertEquals(operation.getAssetCode(), "EUR"); assertEquals(operation.getAssetType(), "credit_alphanum4"); + assertFalse(operation.getFromMuxed().isPresent()); + } + + @Test + public void testDeserializeMuxedClawbackOperation() { + String json = "{\n" + + " \"_links\": {\n" + + " \"effects\": {\n" + + " \"href\": \"/operations/12884914177/effects/{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=asc\"\n" + + " },\n" + + " \"self\": {\n" + + " \"href\": \"/operations/12884914177\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"/operations?cursor=12884914177\\u0026order=desc\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"/transactions/12884914176\"\n" + + " }\n" + + " },\n" + + " \"id\": 12884914177,\n" + + " \"paging_token\": \"12884914177\",\n" + + " \"type_i\": 19,\n" + + " \"type\": \"clawback\",\n" + + " \"asset_type\": \"credit_alphanum4\",\n" + + " \"asset_code\": \"EUR\",\n" + + " \"asset_issuer\": \"GCWVFBJ24754I5GXG4JOEB72GJCL3MKWC7VAEYWKGQHPVH3ENPNBSKWS\",\n" + + " \"from\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"from_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"from_muxed_id\": \"123\"\n" + + "}"; + + ClawbackOperationResponse operation = (ClawbackOperationResponse) GsonSingleton.getInstance().fromJson(json, OperationResponse.class); + + assertEquals(operation.getFrom(), "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L"); + assertEquals(operation.getFromMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); } @Test diff --git a/src/test/java/org/stellar/sdk/responses/TransactionDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/TransactionDeserializerTest.java index ff61680ef..63211835b 100644 --- a/src/test/java/org/stellar/sdk/responses/TransactionDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/TransactionDeserializerTest.java @@ -31,6 +31,9 @@ public void testDeserializeFeeBump() { assertEquals(innerTransaction.getHash(), "e98869bba8bce08c10b78406202127f3888c25454cd37b02600862452751f526"); assertEquals(innerTransaction.getMaxFee(), Long.valueOf(99)); assertEquals(innerTransaction.getSignatures(), ImmutableList.of("FBQU")); + + assertFalse(transaction.getSourceAccountMuxed().isPresent()); + assertFalse(transaction.getFeeAccountMuxed().isPresent()); } @Test @@ -42,6 +45,8 @@ public void testDeserialize() { assertEquals(transaction.getPagingToken(), "3933090531512320"); assertEquals(transaction.isSuccessful(), new Boolean(true)); assertEquals(transaction.getSourceAccount(), "GCUB7JL4APK7LKJ6MZF7Q2JTLHAGNBIUA7XIXD5SQTG52GQ2DAT6XZMK"); + assertFalse(transaction.getSourceAccountMuxed().isPresent()); + assertFalse(transaction.getFeeAccountMuxed().isPresent()); assertEquals(transaction.getSourceAccountSequence(), new Long(2373051035426646L)); assertEquals(transaction.getMaxFee(), new Long(200)); assertEquals(transaction.getFeeCharged(), new Long(100)); @@ -66,6 +71,19 @@ public void testDeserialize() { } @Test + public void testDeserializeMuxed() { + TransactionResponse transaction = GsonSingleton.getInstance().fromJson(muxed, TransactionResponse.class); + assertEquals(transaction.getSourceAccountMuxed().get(), new MuxedAccount( + "MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA", + "GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L", + 123l + )); + assertEquals(transaction.getFeeAccountMuxed().get().getUnmuxedAddress(), "GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G"); + assertEquals(transaction.getFeeAccountMuxed().get().toString(), "MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4"); + assertEquals(transaction.getFeeAccountMuxed().get().getId().longValue(), 420l); + } + + @Test public void testDeserializeWithoutMemo() { TransactionResponse transaction = GsonSingleton.getInstance().fromJson(jsonMemoNone, TransactionResponse.class); assertTrue(transaction.getMemo() instanceof MemoNone); @@ -230,4 +248,74 @@ public void testDeserializeWithoutMemo() { " \"max_fee\": \"99\"\n" + " }\n" + "}"; + + String muxed = "{\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"http://localhost/transactions/3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352\"\n" + + " },\n" + + " \"account\": {\n" + + " \"href\": \"http://localhost/accounts/GABQGAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2MX\"\n" + + " },\n" + + " \"ledger\": {\n" + + " \"href\": \"http://localhost/ledgers/123\"\n" + + " },\n" + + " \"operations\": {\n" + + " \"href\": \"http://localhost/transactions/3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352/operations{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"effects\": {\n" + + " \"href\": \"http://localhost/transactions/3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352/effects{?cursor,limit,order}\",\n" + + " \"templated\": true\n" + + " },\n" + + " \"precedes\": {\n" + + " \"href\": \"http://localhost/transactions?order=asc\\u0026cursor=528280981504\"\n" + + " },\n" + + " \"succeeds\": {\n" + + " \"href\": \"http://localhost/transactions?order=desc\\u0026cursor=528280981504\"\n" + + " },\n" + + " \"transaction\": {\n" + + " \"href\": \"http://localhost/transactions/3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352\"\n" + + " }\n" + + " },\n" + + " \"id\": \"3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352\",\n" + + " \"paging_token\": \"528280981504\",\n" + + " \"successful\": true,\n" + + " \"hash\": \"3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352\",\n" + + " \"ledger\": 123,\n" + + " \"created_at\": \"2020-04-21T10:21:26Z\",\n" + + " \"source_account\": \"GBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA7S2L\",\n" + + " \"account_muxed\": \"MBB4JST32UWKOLGYYSCEYBHBCOFL2TGBHDVOMZP462ET4ZRD4ULA6AAAAAAAAAAAPN7BA\",\n" + + " \"account_muxed_id\": \"123\",\n" + + " \"source_account_sequence\": \"97\",\n" + + " \"fee_account\": \"GAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472ZM7G\",\n" + + " \"fee_account_muxed\": \"MAVH5JM5OKXGMQDS7YPRJ4MQCPXJUGH26LYQPQJ4SOMOJ4SXY472YAAAAAAAAAABUSON4\",\n" + + " \"fee_account_muxed_id\": \"420\",\n" + + " \"fee_charged\": 123,\n" + + " \"max_fee\": 776,\n" + + " \"operation_count\": 1,\n" + + " \"envelope_xdr\": \"AAAABQAAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMIAAAAAgAAAAADAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGMAAAAAAAAAYQAAAAEAAAAAAAAAAgAAAAAAAAAEAAAAAAAAAAEAAAAAAAAACwAAAAAAAABiAAAAAAAAAAECAgICAAAAAxQUFAAAAAAAAAAAAQMDAwMAAAADHh4eAA==\",\n" + + " \"result_xdr\": \"AAAAAAAAAHsAAAAB6Yhpu6i84IwQt4QGICEn84iMJUVM03sCYAhiRSdR9SYAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAsAAAAAAAAAAAAAAAA=\",\n" + + " \"result_meta_xdr\": \"AAAAAQAAAAAAAAAA\",\n" + + " \"fee_meta_xdr\": \"AAAAAA==\",\n" + + " \"memo_type\": \"none\",\n" + + " \"signatures\": [\n" + + " \"Hh4e\"\n" + + " ],\n" + + " \"valid_after\": \"1970-01-01T00:00:02Z\",\n" + + " \"valid_before\": \"1970-01-01T00:00:04Z\",\n" + + " \"fee_bump_transaction\": {\n" + + " \"hash\": \"3dfef7d7226995b504f2827cc63d45ad41e9687bb0a8abcf08ba755fedca0352\",\n" + + " \"signatures\": [\n" + + " \"Hh4e\"\n" + + " ]\n" + + " },\n" + + " \"inner_transaction\": {\n" + + " \"hash\": \"e98869bba8bce08c10b78406202127f3888c25454cd37b02600862452751f526\",\n" + + " \"signatures\": [\n" + + " \"FBQU\"\n" + + " ],\n" + + " \"max_fee\": \"99\"\n" + + " }\n" + + "}"; }