Skip to content

Commit

Permalink
Add support for CAP 35 operations when building transactions (#325)
Browse files Browse the repository at this point in the history
This PR adds support for building transactions using the operations introduced in CAP 35
  • Loading branch information
tamirms authored Mar 17, 2021
1 parent 2fbae8f commit 7889349
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 48 deletions.
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,54 @@

As this project is pre 1.0, breaking changes may happen for minor version bumps. A breaking change will get clearly notified in this log.

## 0.24.0

### Deprecations

* Operation `allow_trust` is deprecated in favor of `set_trust_line_flags` (although it will still be supported by the network)

* Effects `trustline_authorized`, `trustline_authorized_to_maintain_liabilities` and `trustline_deauthorized` are deprecated in favor of `trustline_flags_updated`. Note how we intentionally didn't add a new `trustline_authorized_clawback_enabled` effect.

For uniformity, the `allow_trust` operation will start producing `trustline_flags_updated` from this release.

For now `trustline_authorized`, `trustline_authorized_to_maintain_liabilities` and `trustline_deauthorized` will continue to be emitted as a result of the `allow_trust` operation but in the future we may stop doing so.


Deprecated | New class
-|-
`org.stellar.sdk.AllowTrustOperation` | `org.stellar.sdk.SetTrustlineFlagsOperation`
`org.stellar.sdk.responses.operations.AllowTrustOperationResponse` | `org.stellar.sdk.responses.operations.SetTrustLineFlagsOperationResponse`
`org.stellar.sdk.responses.effects.TrustlineAuthorizedEffectResponse` | `org.stellar.sdk.responses.effects.TrustlineFlagsUpdatedEffectResponse`
`org.stellar.sdk.responses.effects.TrustlineAuthorizedToMaintainLiabilitiesEffectResponse` | `org.stellar.sdk.responses.effects.TrustlineFlagsUpdatedEffectResponse`
`org.stellar.sdk.responses.effects.TrustlineDeauthorizedEffectResponse` | `org.stellar.sdk.responses.effects.TrustlineFlagsUpdatedEffectResponse`


### Changes

## New Operations

* `clawback` implemented in `org.stellar.sdk.ClawbackOperation` claws back a trustline from a given asset holder.

* `clawback_claimable_balance` implemented in `org.stellar.sdk.ClawbackClaimableBalanceOperation` claws back a claimable balance.

* `set_trust_line_flags` implemented in `org.stellar.sdk.SetTrustlineFlagsOperation` modifies a trustline's flags. This operation should be used instead of `org.stellar.sdk.AllowTrustOperation`.

## New effects

* `trustline_flags_updated` implemented in `org.stellar.sdk.responses.effects.TrustlineFlagsUpdatedEffectResponse`, with the following fields:
* Asset fields (like explained in the operations above):
* `asset_type`
* `asset_code`
* `asset_issuer`
* `trustor` - account whose trustline the effect refers to
* `authorized_flag` - true to indicate the flag is set, field ommited if not set
* `authorized_to_maintain_liabilites` - true to indicate the flag is set, field ommited if not set
* `clawback_enabled_flag` - true to indicate that the flag is set, field ommitted if not set


* `claimable_balance_clawed_back` implemented in `org.stellar.sdk.responses.effects.ClaimableBalanceClawedBackEffectResponse`, with the following fields:
* `balance_id` - claimable balance identifer of the claimable balance clawed back

## 0.23.0
### Breaking change
- Updates the SEP-10 utility function parameters to support [SEP-10 v3.1](https://github.com/stellar/stellar-protocol/commit/6c8c9cf6685c85509835188a136ffb8cd6b9c11c) [(#319)](https://github.com/stellar/java-stellar-sdk/pull/319)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ apply plugin: 'com.github.ben-manes.versions' // gradle dependencyUpdates -Drevi
apply plugin: 'project-report' // gradle htmlDependencyReport

sourceCompatibility = 1.6
version = '0.23.0'
version = '0.24.0'
group = 'stellar'

jar {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/stellar/sdk/AllowTrustOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static com.google.common.base.Preconditions.checkNotNull;

/**
* @deprecated As of release 0.24.0, replaced by {@link SetTrustlineFlagsOperation}
*
* Represents <a href="https://www.stellar.org/developers/learn/concepts/list-of-operations.html#allow-trust" target="_blank">AllowTrust</a> operation.
* @see <a href="https://www.stellar.org/developers/learn/concepts/list-of-operations.html" target="_blank">List of Operations</a>
*/
Expand Down
26 changes: 2 additions & 24 deletions src/main/java/org/stellar/sdk/ClaimClaimableBalanceOperation.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package org.stellar.sdk;

import com.google.common.base.Objects;
import com.google.common.io.BaseEncoding;
import org.stellar.sdk.xdr.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import static com.google.common.base.Preconditions.checkNotNull;

public class ClaimClaimableBalanceOperation extends Operation {
Expand All @@ -25,17 +20,7 @@ public String getBalanceId() {
@Override
org.stellar.sdk.xdr.Operation.OperationBody toOperationBody() {
ClaimClaimableBalanceOp op = new ClaimClaimableBalanceOp();

byte[] balanceIdBytes = BaseEncoding.base16().lowerCase().decode(balanceId.toLowerCase());
XdrDataInputStream balanceIdXdrDataInputStream = new XdrDataInputStream(new ByteArrayInputStream(balanceIdBytes));
ClaimableBalanceID id;
try {
id = ClaimableBalanceID.decode(balanceIdXdrDataInputStream);
} catch (IOException e) {
throw new IllegalArgumentException("invalid balanceId: " + balanceId, e);
}

op.setBalanceID(id);
op.setBalanceID(Util.claimableBalanceIdToXDR(balanceId));
org.stellar.sdk.xdr.Operation.OperationBody body = new org.stellar.sdk.xdr.Operation.OperationBody();
body.setDiscriminant(OperationType.CLAIM_CLAIMABLE_BALANCE);
body.setClaimClaimableBalanceOp(op);
Expand All @@ -52,14 +37,7 @@ public static class Builder {
* @param op {@link ClaimClaimableBalanceOp}
*/
Builder(ClaimClaimableBalanceOp op) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
XdrDataOutputStream xdrDataOutputStream = new XdrDataOutputStream(byteArrayOutputStream);
try {
op.getBalanceID().encode(xdrDataOutputStream);
} catch (IOException e) {
throw new IllegalArgumentException("invalid claimClaimableBalanceOp.", e);
}
balanceId = BaseEncoding.base16().lowerCase().encode(byteArrayOutputStream.toByteArray());
balanceId = Util.xdrToClaimableBalanceId(op.getBalanceID());
}

/**
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/org/stellar/sdk/ClawbackClaimableBalanceOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.stellar.sdk;

import com.google.common.base.Objects;
import org.stellar.sdk.xdr.ClawbackClaimableBalanceOp;
import org.stellar.sdk.xdr.OperationType;

import static com.google.common.base.Preconditions.checkNotNull;

/**
*
* Represents a Clawback Claimable Balance operation.
* @see <a href="https://www.stellar.org/developers/learn/concepts/list-of-operations.html" target="_blank">List of Operations</a>
*/
public class ClawbackClaimableBalanceOperation extends Operation {
private final String balanceId;

private ClawbackClaimableBalanceOperation(String balanceId) {
this.balanceId = checkNotNull(balanceId, "balanceId cannot be null");
}

/**
* The id of the claimable balance which will be clawed back.
*/
public String getBalanceId() {
return balanceId;
}


@Override
org.stellar.sdk.xdr.Operation.OperationBody toOperationBody() {
ClawbackClaimableBalanceOp op = new ClawbackClaimableBalanceOp();

op.setBalanceID(Util.claimableBalanceIdToXDR(balanceId));


org.stellar.sdk.xdr.Operation.OperationBody body = new org.stellar.sdk.xdr.Operation.OperationBody();
body.setDiscriminant(OperationType.CLAWBACK_CLAIMABLE_BALANCE);
body.setClawbackClaimableBalanceOp(op);
return body;
}

/**
* Builds ClawbackClaimableBalanceOperation.
* @see ClawbackClaimableBalanceOperation
*/
public static class Builder {
private final String balanceId;

private String mSourceAccount;

Builder(ClawbackClaimableBalanceOp op) {
balanceId = Util.xdrToClaimableBalanceId(op.getBalanceID());
}

/**
* Creates a new ClawbackClaimableBalanceOperation builder.
* @param balanceId The id of the claimable balance which will be clawed back.
*/
public Builder(String balanceId) {
this.balanceId = balanceId;
}

/**
* Set source account of this operation
* @param sourceAccount Source account
* @return Builder object so you can chain methods.
*/
public Builder setSourceAccount(String sourceAccount) {
mSourceAccount = sourceAccount;
return this;
}

/**
* Builds an operation
*/
public ClawbackClaimableBalanceOperation build() {
ClawbackClaimableBalanceOperation operation = new ClawbackClaimableBalanceOperation(
balanceId
);
if (mSourceAccount != null) {
operation.setSourceAccount(mSourceAccount);
}
return operation;
}
}

@Override
public int hashCode() {
return Objects.hashCode(
this.getSourceAccount(),
this.balanceId
);
}

@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof ClawbackClaimableBalanceOperation)) {
return false;
}

ClawbackClaimableBalanceOperation other = (ClawbackClaimableBalanceOperation) object;
return Objects.equal(this.balanceId, other.balanceId);
}
}
139 changes: 139 additions & 0 deletions src/main/java/org/stellar/sdk/ClawbackOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.stellar.sdk;

import com.google.common.base.Objects;
import org.stellar.sdk.xdr.*;

import static com.google.common.base.Preconditions.checkNotNull;

/**
*
* Represents a Clawback operation.
* @see <a href="https://www.stellar.org/developers/learn/concepts/list-of-operations.html" target="_blank">List of Operations</a>
*/
public class ClawbackOperation extends Operation {
private final String from;
private final AssetTypeCreditAlphaNum asset;
private final String amount;

private ClawbackOperation(String from, AssetTypeCreditAlphaNum asset, String amount) {
this.from = checkNotNull(from, "from cannot be null");
this.asset = checkNotNull(asset, "asset cannot be null");
this.amount = checkNotNull(amount, "amount cannot be null");
}

/**
* The account owning of the trustline.
*/
public String getFrom() {
return from;
}

/**
* The amount to be clawed back.
*/
public String getAmount() {
return amount;
}

/**
* The asset to be clawed back.
*/
public Asset getAsset() {
return asset;
}

@Override
org.stellar.sdk.xdr.Operation.OperationBody toOperationBody() {
ClawbackOp op = new ClawbackOp();

// trustor
op.setFrom(StrKey.encodeToXDRMuxedAccount(this.from));

Int64 amount = new Int64();
amount.setInt64(Operation.toXdrAmount(this.amount));
op.setAmount(amount);
op.setAsset(asset.toXdr());


org.stellar.sdk.xdr.Operation.OperationBody body = new org.stellar.sdk.xdr.Operation.OperationBody();
body.setDiscriminant(OperationType.CLAWBACK);
body.setClawbackOp(op);
return body;
}

/**
* Builds ClawbackOperation operation.
* @see ClawbackOperation
*/
public static class Builder {
private final String from;
private final AssetTypeCreditAlphaNum asset;
private final String amount;

private String mSourceAccount;

Builder(ClawbackOp op) {
from = StrKey.encodeStellarAccountId(StrKey.muxedAccountToAccountId(op.getFrom()));
amount = Operation.fromXdrAmount(op.getAmount().getInt64().longValue());
asset = Util.assertNonNativeAsset(Asset.fromXdr(op.getAsset()));
}

/**
* Creates a new ClawbackOperation builder.
* @param from The account holding the trustline.
* @param asset The asset held in the trustline.
* @param amount The amount to be clawed back.
*/
public Builder(String from, Asset asset, String amount) {
this.from = from;
this.asset = Util.assertNonNativeAsset(asset);
this.amount = amount;
}

/**
* Set source account of this operation
* @param sourceAccount Source account
* @return Builder object so you can chain methods.
*/
public Builder setSourceAccount(String sourceAccount) {
mSourceAccount = sourceAccount;
return this;
}

/**
* Builds an operation
*/
public ClawbackOperation build() {
ClawbackOperation operation = new ClawbackOperation(
from, asset, amount
);
if (mSourceAccount != null) {
operation.setSourceAccount(mSourceAccount);
}
return operation;
}
}

@Override
public int hashCode() {
return Objects.hashCode(
this.getSourceAccount(),
this.from,
this.asset,
this.amount
);
}

@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof ClawbackOperation)) {
return false;
}

ClawbackOperation other = (ClawbackOperation) object;
return Objects.equal(this.from, other.from) &&
Objects.equal(this.asset, other.asset) &&
Objects.equal(this.amount, other.amount) &&
Objects.equal(this.getSourceAccount(), other.getSourceAccount());
}
}
9 changes: 9 additions & 0 deletions src/main/java/org/stellar/sdk/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ public static Operation fromXdr(org.stellar.sdk.xdr.Operation xdr) {
throw new RuntimeException("Unknown revoke sponsorship body " + body.getRevokeSponsorshipOp().getDiscriminant());
}
break;
case CLAWBACK:
operation = new ClawbackOperation.Builder(body.getClawbackOp()).build();
break;
case CLAWBACK_CLAIMABLE_BALANCE:
operation = new ClawbackClaimableBalanceOperation.Builder(body.getClawbackClaimableBalanceOp()).build();
break;
case SET_TRUST_LINE_FLAGS:
operation = new SetTrustlineFlagsOperation.Builder(body.getSetTrustLineFlagsOp()).build();
break;
default:
throw new RuntimeException("Unknown operation body " + body.getDiscriminant());
}
Expand Down
Loading

0 comments on commit 7889349

Please sign in to comment.