diff --git a/src/main/java/org/stellar/sdk/CreatePassiveOfferOperation.java b/src/main/java/org/stellar/sdk/CreatePassiveOfferOperation.java index ffbf89f90..dc5a5d6b8 100644 --- a/src/main/java/org/stellar/sdk/CreatePassiveOfferOperation.java +++ b/src/main/java/org/stellar/sdk/CreatePassiveOfferOperation.java @@ -1,13 +1,137 @@ package org.stellar.sdk; +import org.stellar.sdk.xdr.CreatePassiveSellOfferOp; +import org.stellar.sdk.xdr.Int64; +import org.stellar.sdk.xdr.OperationType; + +import static com.google.common.base.Preconditions.checkNotNull; + /** - * @deprecated Use {@link CreatePassiveSellOfferOperation} + * @see List of Operations + * @deprecated As the protocol is upgraded to version 11, CreatePassiveOffer has been renamed to CreatePassiveSellOffer, in order to avoid some unknown errors, please use {@link CreatePassiveSellOfferOperation} immediately. Will be removed in version 0.8.0. + * Represents CreatePassiveOffer operation. */ -@Deprecated public class CreatePassiveOfferOperation extends Operation { + private final Asset selling; + private final Asset buying; + private final String amount; + private final String price; + + private CreatePassiveOfferOperation(Asset selling, Asset buying, String amount, String price) { + this.selling = checkNotNull(selling, "selling cannot be null"); + this.buying = checkNotNull(buying, "buying cannot be null"); + this.amount = checkNotNull(amount, "amount cannot be null"); + this.price = checkNotNull(price, "price cannot be null"); + } + + /** + * The asset being sold in this operation + */ + public Asset getSelling() { + return selling; + } + + /** + * The asset being bought in this operation + */ + public Asset getBuying() { + return buying; + } + + /** + * Amount of selling being sold. + */ + public String getAmount() { + return amount; + } + + /** + * Price of 1 unit of selling in terms of buying. + */ + public String getPrice() { + return price; + } @Override org.stellar.sdk.xdr.Operation.OperationBody toOperationBody() { - return null; + CreatePassiveSellOfferOp op = new CreatePassiveSellOfferOp(); + op.setSelling(selling.toXdr()); + op.setBuying(buying.toXdr()); + Int64 amount = new Int64(); + amount.setInt64(Operation.toXdrAmount(this.amount)); + op.setAmount(amount); + Price price = Price.fromString(this.price); + op.setPrice(price.toXdr()); + + org.stellar.sdk.xdr.Operation.OperationBody body = new org.stellar.sdk.xdr.Operation.OperationBody(); + body.setDiscriminant(OperationType.CREATE_PASSIVE_SELL_OFFER); + body.setCreatePassiveSellOfferOp(op); + + return body; + } + + /** + * Builds CreatePassiveOffer operation. + * + * @see CreatePassiveOfferOperation + */ + public static class Builder { + + private final Asset selling; + private final Asset buying; + private final String amount; + private final String price; + + private KeyPair mSourceAccount; + + /** + * Construct a new CreatePassiveOffer builder from a CreatePassiveSellOfferOp XDR. + * + * @param op + */ + Builder(CreatePassiveSellOfferOp op) { + selling = Asset.fromXdr(op.getSelling()); + buying = Asset.fromXdr(op.getBuying()); + amount = Operation.fromXdrAmount(op.getAmount().getInt64().longValue()); + price = Price.fromXdr(op.getPrice()).toString(); + } + + /** + * Creates a new CreatePassiveOffer builder. + * + * @param selling The asset being sold in this operation + * @param buying The asset being bought in this operation + * @param amount Amount of selling being sold. + * @param price Price of 1 unit of selling in terms of buying. + * @throws ArithmeticException when amount has more than 7 decimal places. + */ + public Builder(Asset selling, Asset buying, String amount, String price) { + this.selling = checkNotNull(selling, "selling cannot be null"); + this.buying = checkNotNull(buying, "buying cannot be null"); + this.amount = checkNotNull(amount, "amount cannot be null"); + this.price = checkNotNull(price, "price cannot be null"); + } + + /** + * Sets the source account for this operation. + * + * @param sourceAccount The operation's source account. + * @return Builder object so you can chain methods. + */ + public Builder setSourceAccount(KeyPair sourceAccount) { + mSourceAccount = checkNotNull(sourceAccount, "sourceAccount cannot be null"); + return this; + } + + /** + * Builds an operation + */ + public CreatePassiveOfferOperation build() { + CreatePassiveOfferOperation operation = new CreatePassiveOfferOperation(selling, buying, amount, price); + if (mSourceAccount != null) { + operation.setSourceAccount(mSourceAccount); + } + return operation; + } } -} +} \ No newline at end of file diff --git a/src/main/java/org/stellar/sdk/ManageOfferOperation.java b/src/main/java/org/stellar/sdk/ManageOfferOperation.java index 4389f6435..48ecf9947 100644 --- a/src/main/java/org/stellar/sdk/ManageOfferOperation.java +++ b/src/main/java/org/stellar/sdk/ManageOfferOperation.java @@ -1,14 +1,164 @@ package org.stellar.sdk; +import org.stellar.sdk.xdr.*; + +import static com.google.common.base.Preconditions.checkNotNull; + /** - * @deprecated Use {@link ManageSellOfferOperation} + * Represents ManageOffer operation. + * + * @see List of Operations + * @deprecated As the protocol is upgraded to version 11, ManageOffer has been renamed to ManageSellOffer, in order to avoid some unknown errors, please use {@link ManageSellOfferOperation} immediately. Will be removed in version 0.8.0. */ -@Deprecated public class ManageOfferOperation extends Operation { + private final Asset selling; + private final Asset buying; + private final String amount; + private final String price; + private final long offerId; + + private ManageOfferOperation(Asset selling, Asset buying, String amount, String price, long offerId) { + this.selling = checkNotNull(selling, "selling cannot be null"); + this.buying = checkNotNull(buying, "buying cannot be null"); + this.amount = checkNotNull(amount, "amount cannot be null"); + this.price = checkNotNull(price, "price cannot be null"); + // offerId can be null + this.offerId = offerId; + } + + /** + * The asset being sold in this operation + */ + public Asset getSelling() { + return selling; + } + + /** + * The asset being bought in this operation + */ + public Asset getBuying() { + return buying; + } + + /** + * Amount of selling being sold. + */ + public String getAmount() { + return amount; + } + + /** + * Price of 1 unit of selling in terms of buying. + */ + public String getPrice() { + return price; + } + + /** + * The ID of the offer. + */ + public long getOfferId() { + return offerId; + } @Override org.stellar.sdk.xdr.Operation.OperationBody toOperationBody() { - return null; + ManageSellOfferOp op = new ManageSellOfferOp(); + op.setSelling(selling.toXdr()); + op.setBuying(buying.toXdr()); + Int64 amount = new Int64(); + amount.setInt64(Operation.toXdrAmount(this.amount)); + op.setAmount(amount); + Price price = Price.fromString(this.price); + op.setPrice(price.toXdr()); + Int64 offerId = new Int64(); + offerId.setInt64(Long.valueOf(this.offerId)); + op.setOfferID(offerId); + + org.stellar.sdk.xdr.Operation.OperationBody body = new org.stellar.sdk.xdr.Operation.OperationBody(); + body.setDiscriminant(OperationType.MANAGE_SELL_OFFER); + body.setManageSellOfferOp(op); + + return body; + } + + /** + * Builds ManageOffer operation. If you want to update existing offer use + * {@link org.stellar.sdk.ManageOfferOperation.Builder#setOfferId(long)}. + * + * @see ManageOfferOperation + */ + public static class Builder { + + private final Asset selling; + private final Asset buying; + private final String amount; + private final String price; + private long offerId = 0; + + private KeyPair mSourceAccount; + + /** + * Construct a new ManageOfferOperation builder from a ManageSellOfferOp XDR. + * + * @param op {@link ManageSellOfferOp} + */ + Builder(ManageSellOfferOp op) { + selling = Asset.fromXdr(op.getSelling()); + buying = Asset.fromXdr(op.getBuying()); + amount = Operation.fromXdrAmount(op.getAmount().getInt64().longValue()); + price = Price.fromXdr(op.getPrice()).toString(); + offerId = op.getOfferID().getInt64().longValue(); + } + + /** + * Creates a new ManageOffer builder. If you want to update existing offer use + * {@link org.stellar.sdk.ManageOfferOperation.Builder#setOfferId(long)}. + * + * @param selling The asset being sold in this operation + * @param buying The asset being bought in this operation + * @param amount Amount of selling being sold. + * @param price Price of 1 unit of selling in terms of buying. + * @throws ArithmeticException when amount has more than 7 decimal places. + */ + public Builder(Asset selling, Asset buying, String amount, String price) { + this.selling = checkNotNull(selling, "selling cannot be null"); + this.buying = checkNotNull(buying, "buying cannot be null"); + this.amount = checkNotNull(amount, "amount cannot be null"); + this.price = checkNotNull(price, "price cannot be null"); + } + + /** + * Sets offer ID. 0 creates a new offer. Set to existing offer ID to change it. + * + * @param offerId + */ + public Builder setOfferId(long offerId) { + this.offerId = offerId; + return this; + } + + /** + * Sets the source account for this operation. + * + * @param sourceAccount The operation's source account. + * @return Builder object so you can chain methods. + */ + public Builder setSourceAccount(KeyPair sourceAccount) { + mSourceAccount = checkNotNull(sourceAccount, "sourceAccount cannot be null"); + return this; + } + + /** + * Builds an operation + */ + public ManageOfferOperation build() { + ManageOfferOperation operation = new ManageOfferOperation(selling, buying, amount, price, offerId); + if (mSourceAccount != null) { + operation.setSourceAccount(mSourceAccount); + } + return operation; + } } -} +} \ No newline at end of file diff --git a/src/test/java/org/stellar/sdk/OperationTest.java b/src/test/java/org/stellar/sdk/OperationTest.java index cc07f1ecb..5b7c050be 100644 --- a/src/test/java/org/stellar/sdk/OperationTest.java +++ b/src/test/java/org/stellar/sdk/OperationTest.java @@ -387,6 +387,44 @@ public void testSetOptionsOperationPreAuthTxSigner() { operation.toXdrBase64()); } + // TODO: remove in 0.8.0 + @Test + public void testManageOfferOperation() throws IOException, FormatException { + // GC5SIC4E3V56VOHJ3OZAX5SJDTWY52JYI2AFK6PUGSXFVRJQYQXXZBZF + KeyPair source = KeyPair.fromSecretSeed("SC4CGETADVYTCR5HEAVZRB3DZQY5Y4J7RFNJTRA6ESMHIPEZUSTE2QDK"); + // GBCP5W2VS7AEWV2HFRN7YYC623LTSV7VSTGIHFXDEJU7S5BAGVCSETRR + KeyPair issuer = KeyPair.fromSecretSeed("SA64U7C5C7BS5IHWEPA7YWFN3Z6FE5L6KAMYUIT4AQ7KVTVLD23C6HEZ"); + + Asset selling = new AssetTypeNative(); + Asset buying = Asset.createNonNativeAsset("USD", issuer); + String amount = "0.00001"; + String price = "0.85334384"; // n=5333399 d=6250000 + Price priceObj = Price.fromString(price); + long offerId = 1; + + ManageOfferOperation operation = new ManageOfferOperation.Builder(selling, buying, amount, price) + .setOfferId(offerId) + .setSourceAccount(source) + .build(); + + org.stellar.sdk.xdr.Operation xdr = operation.toXdr(); + ManageSellOfferOperation parsedOperation = (ManageSellOfferOperation) ManageOfferOperation.fromXdr(xdr); + + assertEquals(100L, xdr.getBody().getManageSellOfferOp().getAmount().getInt64().longValue()); + assertTrue(parsedOperation.getSelling() instanceof AssetTypeNative); + assertTrue(parsedOperation.getBuying() instanceof AssetTypeCreditAlphaNum4); + assertTrue(parsedOperation.getBuying().equals(buying)); + assertEquals(amount, parsedOperation.getAmount()); + assertEquals(price, parsedOperation.getPrice()); + assertEquals(priceObj.getNumerator(), 5333399); + assertEquals(priceObj.getDenominator(), 6250000); + assertEquals(offerId, parsedOperation.getOfferId()); + + assertEquals( + "AAAAAQAAAAC7JAuE3XvquOnbsgv2SRztjuk4RoBVefQ0rlrFMMQvfAAAAAMAAAAAAAAAAVVTRAAAAAAARP7bVZfAS1dHLFv8YF7W1zlX9ZTMg5bjImn5dCA1RSIAAAAAAAAAZABRYZcAX14QAAAAAAAAAAE=", + operation.toXdrBase64()); + } + @Test public void testManageSellOfferOperation() throws IOException, FormatException { // GC5SIC4E3V56VOHJ3OZAX5SJDTWY52JYI2AFK6PUGSXFVRJQYQXXZBZF @@ -478,6 +516,41 @@ public void testManageSellOfferOperation_BadArithmeticRegression() throws IOExce } + @Test + public void testCreatePassiveSellOfferOperation() throws IOException, FormatException { + // GC5SIC4E3V56VOHJ3OZAX5SJDTWY52JYI2AFK6PUGSXFVRJQYQXXZBZF + KeyPair source = KeyPair.fromSecretSeed("SC4CGETADVYTCR5HEAVZRB3DZQY5Y4J7RFNJTRA6ESMHIPEZUSTE2QDK"); + // GBCP5W2VS7AEWV2HFRN7YYC623LTSV7VSTGIHFXDEJU7S5BAGVCSETRR + KeyPair issuer = KeyPair.fromSecretSeed("SA64U7C5C7BS5IHWEPA7YWFN3Z6FE5L6KAMYUIT4AQ7KVTVLD23C6HEZ"); + + Asset selling = new AssetTypeNative(); + Asset buying = Asset.createNonNativeAsset("USD", issuer); + String amount = "0.00001"; + String price = "2.93850088"; // n=36731261 d=12500000 + Price priceObj = Price.fromString(price); + + CreatePassiveSellOfferOperation operation = new CreatePassiveSellOfferOperation.Builder(selling, buying, amount, price) + .setSourceAccount(source) + .build(); + + org.stellar.sdk.xdr.Operation xdr = operation.toXdr(); + CreatePassiveSellOfferOperation parsedOperation = (CreatePassiveSellOfferOperation) CreatePassiveSellOfferOperation.fromXdr(xdr); + + assertEquals(100L, xdr.getBody().getCreatePassiveSellOfferOp().getAmount().getInt64().longValue()); + assertTrue(parsedOperation.getSelling() instanceof AssetTypeNative); + assertTrue(parsedOperation.getBuying() instanceof AssetTypeCreditAlphaNum4); + assertTrue(parsedOperation.getBuying().equals(buying)); + assertEquals(amount, parsedOperation.getAmount()); + assertEquals(price, parsedOperation.getPrice()); + assertEquals(priceObj.getNumerator(), 36731261); + assertEquals(priceObj.getDenominator(), 12500000); + + assertEquals( + "AAAAAQAAAAC7JAuE3XvquOnbsgv2SRztjuk4RoBVefQ0rlrFMMQvfAAAAAQAAAAAAAAAAVVTRAAAAAAARP7bVZfAS1dHLFv8YF7W1zlX9ZTMg5bjImn5dCA1RSIAAAAAAAAAZAIweX0Avrwg", + operation.toXdrBase64()); + } + + // TODO: remove in 0.8.0 @Test public void testCreatePassiveOfferOperation() throws IOException, FormatException { // GC5SIC4E3V56VOHJ3OZAX5SJDTWY52JYI2AFK6PUGSXFVRJQYQXXZBZF @@ -491,7 +564,7 @@ public void testCreatePassiveOfferOperation() throws IOException, FormatExceptio String price = "2.93850088"; // n=36731261 d=12500000 Price priceObj = Price.fromString(price); - CreatePassiveSellOfferOperation operation = new CreatePassiveSellOfferOperation.Builder(selling, buying, amount, price) + CreatePassiveOfferOperation operation = new CreatePassiveOfferOperation.Builder(selling, buying, amount, price) .setSourceAccount(source) .build();