diff --git a/pom.xml b/pom.xml
index 1e42d8f1..36d73da7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.qora
qora-core
2.0.0-SNAPSHOT
- bundle
+ jar
UTF-8
1.60
diff --git a/src/main/java/org/qora/api/resource/AssetsResource.java b/src/main/java/org/qora/api/resource/AssetsResource.java
index a6e89697..9c0df73a 100644
--- a/src/main/java/org/qora/api/resource/AssetsResource.java
+++ b/src/main/java/org/qora/api/resource/AssetsResource.java
@@ -32,6 +32,7 @@ import org.qora.data.account.AccountBalanceData;
import org.qora.data.asset.AssetData;
import org.qora.data.asset.OrderData;
import org.qora.data.asset.TradeData;
+import org.qora.data.transaction.CreateOrderTransactionData;
import org.qora.data.transaction.IssueAssetTransactionData;
import org.qora.repository.DataException;
import org.qora.repository.Repository;
@@ -39,6 +40,7 @@ import org.qora.repository.RepositoryManager;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ValidationResult;
import org.qora.transform.TransformationException;
+import org.qora.transform.transaction.CreateOrderTransactionTransformer;
import org.qora.transform.transaction.IssueAssetTransactionTransformer;
import org.qora.utils.Base58;
@@ -243,7 +245,7 @@ public class AssetsResource {
),
responses = {
@ApiResponse(
- description = "raw, unsigned payment transaction encoded in Base58",
+ description = "raw, unsigned, ISSUE_ASSET transaction encoded in Base58",
content = @Content(
mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(
@@ -271,4 +273,45 @@ public class AssetsResource {
}
}
+ @POST
+ @Path("/order")
+ @Operation(
+ summary = "Create asset order",
+ requestBody = @RequestBody(
+ required = true,
+ content = @Content(
+ mediaType = MediaType.APPLICATION_JSON,
+ schema = @Schema(implementation = CreateOrderTransactionData.class)
+ )
+ ),
+ responses = {
+ @ApiResponse(
+ description = "raw, unsigned, CREATE_ORDER transaction encoded in Base58",
+ content = @Content(
+ mediaType = MediaType.TEXT_PLAIN,
+ schema = @Schema(
+ type = "string"
+ )
+ )
+ )
+ }
+ )
+ @ApiErrors({ApiError.TRANSFORMATION_ERROR, ApiError.REPOSITORY_ISSUE, ApiError.TRANSACTION_INVALID})
+ public String createOrder(CreateOrderTransactionData transactionData) {
+ try (final Repository repository = RepositoryManager.getRepository()) {
+ Transaction transaction = Transaction.fromData(repository, transactionData);
+
+ ValidationResult result = transaction.isValidUnconfirmed();
+ if (result != ValidationResult.OK)
+ throw TransactionsResource.createTransactionInvalidException(request, result);
+
+ byte[] bytes = CreateOrderTransactionTransformer.toBytes(transactionData);
+ return Base58.encode(bytes);
+ } catch (TransformationException e) {
+ throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSFORMATION_ERROR, e);
+ } catch (DataException e) {
+ throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
+ }
+ }
+
}
diff --git a/src/main/java/org/qora/api/resource/NamesResource.java b/src/main/java/org/qora/api/resource/NamesResource.java
index f4a8a684..b6332567 100644
--- a/src/main/java/org/qora/api/resource/NamesResource.java
+++ b/src/main/java/org/qora/api/resource/NamesResource.java
@@ -38,7 +38,7 @@ public class NamesResource {
@POST
@Path("/register")
@Operation(
- summary = "Build raw, unsigned REGISTER_NAME transaction",
+ summary = "Build raw, unsigned, REGISTER_NAME transaction",
requestBody = @RequestBody(
required = true,
content = @Content(
@@ -50,7 +50,7 @@ public class NamesResource {
),
responses = {
@ApiResponse(
- description = "raw, unsigned REGISTER_NAME transaction encoded in Base58",
+ description = "raw, unsigned, REGISTER_NAME transaction encoded in Base58",
content = @Content(
mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(
diff --git a/src/main/java/org/qora/api/resource/PaymentsResource.java b/src/main/java/org/qora/api/resource/PaymentsResource.java
index a37a9f44..ddce2712 100644
--- a/src/main/java/org/qora/api/resource/PaymentsResource.java
+++ b/src/main/java/org/qora/api/resource/PaymentsResource.java
@@ -38,7 +38,7 @@ public class PaymentsResource {
@POST
@Path("/pay")
@Operation(
- summary = "Build raw, unsigned payment transaction",
+ summary = "Build raw, unsigned, PAYMENT transaction",
requestBody = @RequestBody(
required = true,
content = @Content(
@@ -50,7 +50,7 @@ public class PaymentsResource {
),
responses = {
@ApiResponse(
- description = "raw, unsigned payment transaction encoded in Base58",
+ description = "raw, unsigned, PAYMENT transaction encoded in Base58",
content = @Content(
mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(
diff --git a/src/main/java/org/qora/data/transaction/CreateOrderTransactionData.java b/src/main/java/org/qora/data/transaction/CreateOrderTransactionData.java
index 8e3f0233..324cb85b 100644
--- a/src/main/java/org/qora/data/transaction/CreateOrderTransactionData.java
+++ b/src/main/java/org/qora/data/transaction/CreateOrderTransactionData.java
@@ -4,10 +4,12 @@ import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
// All properties to be converted to JSON via JAX-RS
@XmlAccessorType(XmlAccessType.FIELD)
@@ -15,15 +17,20 @@ import io.swagger.v3.oas.annotations.media.Schema;
public class CreateOrderTransactionData extends TransactionData {
// Properties
+ @Schema(description = "asset on offer to give by order creator")
private long haveAssetId;
+ @Schema(description = "asset wanted to receive by order creator")
private long wantAssetId;
+ @Schema(description = "amount of \"have\" asset to trade")
private BigDecimal amount;
+ @Schema(description = "amount of \"want\" asset to receive per unit of \"have\" asset traded")
private BigDecimal price;
// Constructors
// For JAX-RS
protected CreateOrderTransactionData() {
+ super(TransactionType.CREATE_ASSET_ORDER);
}
public CreateOrderTransactionData(byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price, BigDecimal fee,
@@ -59,4 +66,17 @@ public class CreateOrderTransactionData extends TransactionData {
return this.price;
}
+ // Re-expose creatorPublicKey for this transaction type for JAXB
+ @XmlElement(name = "creatorPublicKey")
+ @Schema(name = "creatorPublicKey", description = "order creator's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP")
+ public byte[] getOrderCreatorPublicKey() {
+ return this.creatorPublicKey;
+ }
+
+ @XmlElement(name = "creatorPublicKey")
+ @Schema(name = "creatorPublicKey", description = "order creator's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP")
+ public void setOrderCreatorPublicKey(byte[] creatorPublicKey) {
+ this.creatorPublicKey = creatorPublicKey;
+ }
+
}
diff --git a/src/main/java/org/qora/data/transaction/PaymentTransactionData.java b/src/main/java/org/qora/data/transaction/PaymentTransactionData.java
index 2352fd40..d9b82aef 100644
--- a/src/main/java/org/qora/data/transaction/PaymentTransactionData.java
+++ b/src/main/java/org/qora/data/transaction/PaymentTransactionData.java
@@ -22,9 +22,9 @@ public class PaymentTransactionData extends TransactionData {
private String recipient;
@Schema(description = "amount to send", example = "123.456")
@XmlJavaTypeAdapter(
- type = BigDecimal.class,
- value = org.qora.api.BigDecimalTypeAdapter.class
- )
+ type = BigDecimal.class,
+ value = org.qora.api.BigDecimalTypeAdapter.class
+ )
private BigDecimal amount;
// Constructors
diff --git a/src/main/java/org/qora/transaction/Transaction.java b/src/main/java/org/qora/transaction/Transaction.java
index e535224b..d51a777a 100644
--- a/src/main/java/org/qora/transaction/Transaction.java
+++ b/src/main/java/org/qora/transaction/Transaction.java
@@ -108,6 +108,7 @@ public abstract class Transaction {
AT_IS_FINISHED(40),
ASSET_DOES_NOT_MATCH_AT(41),
ASSET_ALREADY_EXISTS(43),
+ MISSING_CREATOR(44),
NOT_YET_RELEASED(1000);
public final int value;
@@ -364,6 +365,9 @@ public abstract class Transaction {
* @throws DataException
*/
protected Account getCreator() throws DataException {
+ if (this.transactionData.getCreatorPublicKey() == null)
+ return null;
+
return new PublicKeyAccount(this.repository, this.transactionData.getCreatorPublicKey());
}
@@ -432,6 +436,9 @@ public abstract class Transaction {
public ValidationResult isValidUnconfirmed() throws DataException {
try {
Account creator = this.getCreator();
+ if (creator == null)
+ return ValidationResult.MISSING_CREATOR;
+
creator.setLastReference(creator.getUnconfirmedLastReference());
return this.isValid();
} finally {