mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-27 15:55:54 +00:00
Add cancel order and get orders by address API support.
Added getAccountsOrders asset repository call to facilitate the above.
This commit is contained in:
parent
2497ac256c
commit
b2ca63ce88
@ -15,6 +15,7 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
@ -27,6 +28,7 @@ import org.qora.asset.Asset;
|
||||
import org.qora.crypto.Crypto;
|
||||
import org.qora.data.account.AccountBalanceData;
|
||||
import org.qora.data.account.AccountData;
|
||||
import org.qora.data.asset.OrderData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
@ -281,4 +283,38 @@ public class AddressesResource {
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/assetorders/{address}")
|
||||
@Operation(
|
||||
summary = "Asset orders created by this address",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "Asset orders",
|
||||
content = @Content(array = @ArraySchema(schema = @Schema(implementation = OrderData.class)))
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.ADDRESS_NO_EXISTS, ApiError.REPOSITORY_ISSUE})
|
||||
public List<OrderData> getAssetOrders(@PathParam("address") String address, @QueryParam("includeClosed") boolean includeClosed, @QueryParam("includeFulfilled") boolean includeFulfilled) {
|
||||
if (!Crypto.isValidAddress(address))
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
AccountData accountData = repository.getAccountRepository().getAccount(address);
|
||||
|
||||
if (accountData == null)
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS);
|
||||
|
||||
byte[] publicKey = accountData.getPublicKey();
|
||||
if (publicKey == null)
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS);
|
||||
|
||||
return repository.getAssetRepository().getAccountsOrders(publicKey, includeClosed, includeFulfilled);
|
||||
} catch (ApiException e) {
|
||||
throw e;
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.CancelOrderTransactionData;
|
||||
import org.qora.data.transaction.CreateOrderTransactionData;
|
||||
import org.qora.data.transaction.IssueAssetTransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
@ -40,6 +41,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.CancelOrderTransactionTransformer;
|
||||
import org.qora.transform.transaction.CreateOrderTransactionTransformer;
|
||||
import org.qora.transform.transaction.IssueAssetTransactionTransformer;
|
||||
import org.qora.utils.Base58;
|
||||
@ -232,6 +234,47 @@ public class AssetsResource {
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/order/delete")
|
||||
@Operation(
|
||||
summary = "Cancel existing asset order",
|
||||
requestBody = @RequestBody(
|
||||
required = true,
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(implementation = CancelOrderTransactionData.class)
|
||||
)
|
||||
),
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "raw, unsigned, CANCEL_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 cancelOrder(CancelOrderTransactionData 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 = CancelOrderTransactionTransformer.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);
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/issue")
|
||||
@Operation(
|
||||
|
@ -4,8 +4,10 @@ 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;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@ -15,12 +17,14 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
public class CancelOrderTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
@Schema(description = "order ID to cancel", example = "2zYCM8P3PSzUxFNPAKFsSdwg9dWQcYTPCuKkuQbx3GVxTUVjXAUwEmEnvUUss11SZ3p38C16UfYb3cbXP9sRuqFx")
|
||||
private byte[] orderId;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
protected CancelOrderTransactionData() {
|
||||
super(TransactionType.CANCEL_ASSET_ORDER);
|
||||
}
|
||||
|
||||
public CancelOrderTransactionData(byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
@ -39,4 +43,17 @@ public class CancelOrderTransactionData extends TransactionData {
|
||||
return this.orderId;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ 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)
|
||||
@ -17,9 +16,9 @@ import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||
public class CreateOrderTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
@Schema(description = "asset on offer to give by order creator")
|
||||
@Schema(description = "ID of asset on offer to give by order creator", example = "1")
|
||||
private long haveAssetId;
|
||||
@Schema(description = "asset wanted to receive by order creator")
|
||||
@Schema(description = "ID of asset wanted to receive by order creator", example = "0")
|
||||
private long wantAssetId;
|
||||
@Schema(description = "amount of \"have\" asset to trade")
|
||||
private BigDecimal amount;
|
||||
|
@ -32,6 +32,8 @@ public interface AssetRepository {
|
||||
|
||||
public List<OrderData> getOpenOrders(long haveAssetId, long wantAssetId) throws DataException;
|
||||
|
||||
public List<OrderData> getAccountsOrders(byte[] publicKey, boolean includeClosed, boolean includeFulfilled) throws DataException;
|
||||
|
||||
public void save(OrderData orderData) throws DataException;
|
||||
|
||||
public void delete(byte[] orderId) throws DataException;
|
||||
|
@ -201,6 +201,44 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OrderData> getAccountsOrders(byte[] publicKey, boolean includeClosed, boolean includeFulfilled) throws DataException {
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
|
||||
String sql = "SELECT asset_order_id, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
|
||||
+ "FROM AssetOrders WHERE creator = ?";
|
||||
if (!includeClosed)
|
||||
sql += " AND is_closed = FALSE";
|
||||
if (!includeFulfilled)
|
||||
sql += " AND is_fulfilled = FALSE";
|
||||
sql += " ORDER BY ordered ASC";
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, publicKey)) {
|
||||
if (resultSet == null)
|
||||
return orders;
|
||||
|
||||
do {
|
||||
byte[] orderId = resultSet.getBytes(1);
|
||||
long haveAssetId = resultSet.getLong(2);
|
||||
long wantAssetId = resultSet.getLong(3);
|
||||
BigDecimal amount = resultSet.getBigDecimal(4);
|
||||
BigDecimal fulfilled = resultSet.getBigDecimal(5);
|
||||
BigDecimal price = resultSet.getBigDecimal(6);
|
||||
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||
boolean isClosed = resultSet.getBoolean(8);
|
||||
boolean isFulfilled = resultSet.getBoolean(9);
|
||||
|
||||
OrderData order = new OrderData(orderId, publicKey, haveAssetId, wantAssetId, amount, fulfilled, price, timestamp, isClosed,
|
||||
isFulfilled);
|
||||
orders.add(order);
|
||||
} while (resultSet.next());
|
||||
|
||||
return orders;
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch account's asset orders from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(OrderData orderData) throws DataException {
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("AssetOrders");
|
||||
|
Loading…
x
Reference in New Issue
Block a user