forked from Qortal/qortal
API: assets & tidying
Cleaned up responses from /addresses/* endpoints in that some return text/plain instead of application/json. Removed need for class-local copy of ApiErrorFactory in AddressesResource - using getInstance() instead. Some work still needs to be done on annotating API errors. API error examples in API UI rendered incorrectly - swagger-ui issue? Removed repository-accessing code from api.models.* Added /assets/order/{orderId} for fetching info on specific asset order. NOTE: AssetRepository.getOrdersTrades() now returns trades where order is initiating or target. (Previously was initiating order only). qora.assets.Order.orphan() updated to reflect above change. block-explorer.html fixed to use new API output.
This commit is contained in:
parent
dcd19f8e42
commit
034cf5dee3
@ -88,7 +88,7 @@
|
|||||||
document.body.innerHTML = html;
|
document.body.innerHTML = html;
|
||||||
|
|
||||||
XHR({
|
XHR({
|
||||||
url: "/transactions/address/" + address,
|
url: "/transactions/search?address=" + address,
|
||||||
onload: renderAddressTransactions,
|
onload: renderAddressTransactions,
|
||||||
responseType: "json"
|
responseType: "json"
|
||||||
});
|
});
|
||||||
@ -137,7 +137,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderBlockInfo(e) {
|
function renderBlockInfo(e) {
|
||||||
var blockData = e.target.response;
|
var blockData = e.target.response.block;
|
||||||
|
|
||||||
// These properties are currently emitted as base64 by API but likely to be base58 in the future, so convert them
|
// These properties are currently emitted as base64 by API but likely to be base58 in the future, so convert them
|
||||||
var props = [ "signature", "reference", "transactionsSignature", "generatorPublicKey", "generatorSignature" ];
|
var props = [ "signature", "reference", "transactionsSignature", "generatorPublicKey", "generatorSignature" ];
|
||||||
@ -196,7 +196,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listBlock(e) {
|
function listBlock(e) {
|
||||||
var blockData = e.target.response;
|
var blockData = e.target.response.block;
|
||||||
|
|
||||||
var ourHeight = blockData.height;
|
var ourHeight = blockData.height;
|
||||||
var blockTimestamp = new Date(blockData.timestamp).toUTCString();
|
var blockTimestamp = new Date(blockData.timestamp).toUTCString();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package api;
|
package api;
|
||||||
|
|
||||||
import globalization.Translator;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.extensions.Extension;
|
import io.swagger.v3.oas.annotations.extensions.Extension;
|
||||||
@ -45,16 +44,6 @@ public class AddressesResource {
|
|||||||
@Context
|
@Context
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
private ApiErrorFactory apiErrorFactory;
|
|
||||||
|
|
||||||
public AddressesResource() {
|
|
||||||
this(new ApiErrorFactory(Translator.getInstance()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AddressesResource(ApiErrorFactory apiErrorFactory) {
|
|
||||||
this.apiErrorFactory = apiErrorFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/lastreference/{address}")
|
@Path("/lastreference/{address}")
|
||||||
@Operation(
|
@Operation(
|
||||||
@ -72,7 +61,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the base64-encoded transaction signature or \"false\"",
|
description = "the base64-encoded transaction signature or \"false\"",
|
||||||
content = @Content(schema = @Schema(implementation = String.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -83,7 +72,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public String getLastReference(@Parameter(ref = "address") @PathParam("address") String address) {
|
public String getLastReference(@Parameter(ref = "address") @PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
byte[] lastReference = null;
|
byte[] lastReference = null;
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -92,7 +81,7 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastReference == null || lastReference.length == 0) {
|
if(lastReference == null || lastReference.length == 0) {
|
||||||
@ -119,7 +108,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the base64-encoded transaction signature",
|
description = "the base64-encoded transaction signature",
|
||||||
content = @Content(schema = @Schema(implementation = String.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -130,7 +119,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public String getLastReferenceUnconfirmed(@PathParam("address") String address) {
|
public String getLastReferenceUnconfirmed(@PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
byte[] lastReference = null;
|
byte[] lastReference = null;
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -139,7 +128,7 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastReference == null || lastReference.length == 0) {
|
if(lastReference == null || lastReference.length == 0) {
|
||||||
@ -163,8 +152,7 @@ public class AddressesResource {
|
|||||||
},
|
},
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
//description = "",
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "boolean")),
|
||||||
content = @Content(schema = @Schema(implementation = Boolean.class)),
|
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -194,7 +182,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the generating balance",
|
description = "the generating balance",
|
||||||
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", format = "number")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -205,7 +193,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public BigDecimal getGeneratingBalanceOfAddress(@PathParam("address") String address) {
|
public BigDecimal getGeneratingBalanceOfAddress(@PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
Account account = new Account(repository, address);
|
Account account = new Account(repository, address);
|
||||||
@ -213,7 +201,7 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +221,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the balance",
|
description = "the balance",
|
||||||
content = @Content(schema = @Schema(name = "balance", type = "number")),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", format = "number")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -244,7 +232,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public BigDecimal getGeneratingBalance(@PathParam("address") String address) {
|
public BigDecimal getGeneratingBalance(@PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
Account account = new Account(repository, address);
|
Account account = new Account(repository, address);
|
||||||
@ -252,7 +240,7 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +261,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the balance",
|
description = "the balance",
|
||||||
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", format = "number")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -284,7 +272,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public BigDecimal getAssetBalance(@PathParam("assetid") long assetid, @PathParam("address") String address) {
|
public BigDecimal getAssetBalance(@PathParam("assetid") long assetid, @PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
Account account = new Account(repository, address);
|
Account account = new Account(repository, address);
|
||||||
@ -292,7 +280,7 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,14 +312,14 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public List<AccountBalanceData> getAssets(@PathParam("address") String address) {
|
public List<AccountBalanceData> getAssets(@PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
return repository.getAccountRepository().getAllBalances(address);
|
return repository.getAccountRepository().getAllBalances(address);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +369,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the public key",
|
description = "the public key",
|
||||||
content = @Content(schema = @Schema(implementation = String.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -392,7 +380,7 @@ public class AddressesResource {
|
|||||||
)
|
)
|
||||||
public String getPublicKey(@PathParam("address") String address) {
|
public String getPublicKey(@PathParam("address") String address) {
|
||||||
if (!Crypto.isValidAddress(address))
|
if (!Crypto.isValidAddress(address))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_ADDRESS);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
AccountData accountData = repository.getAccountRepository().getAccount(address);
|
AccountData accountData = repository.getAccountRepository().getAccount(address);
|
||||||
@ -408,13 +396,12 @@ public class AddressesResource {
|
|||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/convert/{publickey}")
|
@Path("/convert/{publickey}")
|
||||||
@Produces(MediaType.TEXT_PLAIN)
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert public key into address",
|
summary = "Convert public key into address",
|
||||||
description = "Returns account address based on supplied public key. Expects base64-encoded, 32-byte public key.",
|
description = "Returns account address based on supplied public key. Expects base64-encoded, 32-byte public key.",
|
||||||
@ -430,7 +417,7 @@ public class AddressesResource {
|
|||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "the address",
|
description = "the address",
|
||||||
content = @Content(schema = @Schema(implementation = String.class)),
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string")),
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
@ -445,19 +432,19 @@ public class AddressesResource {
|
|||||||
try {
|
try {
|
||||||
publicKeyBytes = Base64.getDecoder().decode(publicKey);
|
publicKeyBytes = Base64.getDecoder().decode(publicKey);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_PUBLIC_KEY, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_PUBLIC_KEY, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct size for public key?
|
// Correct size for public key?
|
||||||
if (publicKeyBytes.length != Transformer.PUBLIC_KEY_LENGTH)
|
if (publicKeyBytes.length != Transformer.PUBLIC_KEY_LENGTH)
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_PUBLIC_KEY);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_PUBLIC_KEY);
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
return Crypto.toAddress(publicKeyBytes);
|
return Crypto.toAddress(publicKeyBytes);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw this.apiErrorFactory.createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ public enum ApiError {
|
|||||||
JSON(1, 400),
|
JSON(1, 400),
|
||||||
NO_BALANCE(2, 422),
|
NO_BALANCE(2, 422),
|
||||||
NOT_YET_RELEASED(3, 422),
|
NOT_YET_RELEASED(3, 422),
|
||||||
UNAUTHORIZED(4, 401),
|
UNAUTHORIZED(4, 403),
|
||||||
REPOSITORY_ISSUE(5, 500),
|
REPOSITORY_ISSUE(5, 500),
|
||||||
|
|
||||||
//VALIDATION
|
//VALIDATION
|
||||||
@ -67,6 +67,8 @@ public enum ApiError {
|
|||||||
|
|
||||||
//ASSET
|
//ASSET
|
||||||
INVALID_ASSET_ID(601, 400),
|
INVALID_ASSET_ID(601, 400),
|
||||||
|
INVALID_ORDER_ID(602, 400),
|
||||||
|
ORDER_NO_EXISTS(603, 404),
|
||||||
|
|
||||||
//NAME PAYMENTS
|
//NAME PAYMENTS
|
||||||
NAME_NOT_REGISTERED(701, 422),
|
NAME_NOT_REGISTERED(701, 422),
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package api;
|
package api;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
@XmlRootElement
|
// All properties to be converted to JSON via JAX-RS
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class ApiErrorMessage {
|
public class ApiErrorMessage {
|
||||||
|
|
||||||
@XmlElement(name = "error")
|
|
||||||
public int error;
|
public int error;
|
||||||
|
|
||||||
@XmlElement(name = "message")
|
|
||||||
public String message;
|
public String message;
|
||||||
|
|
||||||
ApiErrorMessage() {
|
ApiErrorMessage() {
|
||||||
|
@ -13,6 +13,7 @@ import repository.Repository;
|
|||||||
import repository.RepositoryManager;
|
import repository.RepositoryManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -27,7 +28,9 @@ import javax.ws.rs.core.MediaType;
|
|||||||
|
|
||||||
import api.models.AssetWithHolders;
|
import api.models.AssetWithHolders;
|
||||||
import api.models.IssueAssetRequest;
|
import api.models.IssueAssetRequest;
|
||||||
|
import api.models.OrderWithTrades;
|
||||||
import api.models.TradeWithOrderInfo;
|
import api.models.TradeWithOrderInfo;
|
||||||
|
import data.account.AccountBalanceData;
|
||||||
import data.assets.AssetData;
|
import data.assets.AssetData;
|
||||||
import data.assets.OrderData;
|
import data.assets.OrderData;
|
||||||
import data.assets.TradeData;
|
import data.assets.TradeData;
|
||||||
@ -78,7 +81,7 @@ public class AssetsResource {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public AssetWithHolders getAssetInfo(@QueryParam("assetId") Integer assetId, @QueryParam("assetName") String assetName, @Parameter(ref = "includeHolders") @QueryParam("withHolders") boolean includeHolders) {
|
public AssetWithHolders getAssetInfo(@QueryParam("assetId") Integer assetId, @QueryParam("assetName") String assetName, @Parameter(ref = "includeHolders") @QueryParam("includeHolders") boolean includeHolders) {
|
||||||
if (assetId == null && (assetName == null || assetName.isEmpty()))
|
if (assetId == null && (assetName == null || assetName.isEmpty()))
|
||||||
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_CRITERIA);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_CRITERIA);
|
||||||
|
|
||||||
@ -93,7 +96,11 @@ public class AssetsResource {
|
|||||||
if (assetData == null)
|
if (assetData == null)
|
||||||
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ASSET_ID);
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ASSET_ID);
|
||||||
|
|
||||||
return new AssetWithHolders(repository, assetData, includeHolders);
|
List<AccountBalanceData> holders = null;
|
||||||
|
if (includeHolders)
|
||||||
|
holders = repository.getAccountRepository().getAssetBalances(assetData.getAssetId());
|
||||||
|
|
||||||
|
return new AssetWithHolders(assetData, holders);
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
}
|
}
|
||||||
@ -165,8 +172,11 @@ public class AssetsResource {
|
|||||||
|
|
||||||
// Expanding remaining entries
|
// Expanding remaining entries
|
||||||
List<TradeWithOrderInfo> fullTrades = new ArrayList<>();
|
List<TradeWithOrderInfo> fullTrades = new ArrayList<>();
|
||||||
for (TradeData trade : trades)
|
for (TradeData tradeData : trades) {
|
||||||
fullTrades.add(new TradeWithOrderInfo(repository, trade));
|
OrderData initiatingOrderData = repository.getAssetRepository().fromOrderId(tradeData.getInitiator());
|
||||||
|
OrderData targetOrderData = repository.getAssetRepository().fromOrderId(tradeData.getTarget());
|
||||||
|
fullTrades.add(new TradeWithOrderInfo(tradeData, initiatingOrderData, targetOrderData));
|
||||||
|
}
|
||||||
|
|
||||||
return fullTrades;
|
return fullTrades;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -174,6 +184,40 @@ public class AssetsResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/order/{orderId}")
|
||||||
|
@Operation(
|
||||||
|
summary = "Fetch asset order",
|
||||||
|
description = "Returns asset order info.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "asset order",
|
||||||
|
content = @Content(schema = @Schema(implementation = OrderData.class))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public OrderWithTrades getAssetOrder(@PathParam("orderId") String orderId64) {
|
||||||
|
// Decode orderID
|
||||||
|
byte[] orderId;
|
||||||
|
try {
|
||||||
|
orderId = Base64.getDecoder().decode(orderId64);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ORDER_ID, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
OrderData orderData = repository.getAssetRepository().fromOrderId(orderId);
|
||||||
|
if (orderData == null)
|
||||||
|
throw ApiErrorFactory.getInstance().createError(ApiError.ORDER_NO_EXISTS);
|
||||||
|
|
||||||
|
List<TradeData> trades = repository.getAssetRepository().getOrdersTrades(orderId);
|
||||||
|
|
||||||
|
return new OrderWithTrades(orderData, trades);
|
||||||
|
} catch (DataException e) {
|
||||||
|
throw ApiErrorFactory.getInstance().createError(ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/issue")
|
@Path("/issue")
|
||||||
@Operation(
|
@Operation(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package api;
|
package api;
|
||||||
|
|
||||||
import data.block.BlockData;
|
import data.block.BlockData;
|
||||||
|
import data.transaction.TransactionData;
|
||||||
import globalization.Translator;
|
import globalization.Translator;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@ -15,6 +16,7 @@ import java.math.BigDecimal;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
@ -33,11 +35,8 @@ import repository.Repository;
|
|||||||
import repository.RepositoryManager;
|
import repository.RepositoryManager;
|
||||||
|
|
||||||
@Path("blocks")
|
@Path("blocks")
|
||||||
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
|
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
|
||||||
@Extension(name = "translation", properties = {
|
@Extension(name = "translation", properties = { @ExtensionProperty(name = "path", value = "/Api/BlocksResource") })
|
||||||
@ExtensionProperty(name="path", value="/Api/BlocksResource")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@Tag(name = "Blocks")
|
@Tag(name = "Blocks")
|
||||||
public class BlocksResource {
|
public class BlocksResource {
|
||||||
|
|
||||||
@ -59,28 +58,23 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch block using base64 signature",
|
summary = "Fetch block using base64 signature",
|
||||||
description = "Returns the block that matches the given signature",
|
description = "Returns the block that matches the given signature",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET signature"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET signature"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@Extension(properties = {
|
), @Extension(properties =
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
})
|
responses =
|
||||||
},
|
{ @ApiResponse(
|
||||||
responses = {
|
description = "the block",
|
||||||
@ApiResponse(
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
description = "the block",
|
extensions =
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
extensions = {
|
) }
|
||||||
@Extension(name = "translation", properties = {
|
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BlockWithTransactions getBlock(@PathParam("signature") String signature, @Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
public BlockWithTransactions getBlock(@PathParam("signature") String signature,
|
||||||
|
@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
||||||
// Decode signature
|
// Decode signature
|
||||||
byte[] signatureBytes;
|
byte[] signatureBytes;
|
||||||
try {
|
try {
|
||||||
@ -91,7 +85,7 @@ public class BlocksResource {
|
|||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
BlockData blockData = repository.getBlockRepository().fromSignature(signatureBytes);
|
BlockData blockData = repository.getBlockRepository().fromSignature(signatureBytes);
|
||||||
return new BlockWithTransactions(repository, blockData, includeTransactions);
|
return packageBlockData(repository, blockData, includeTransactions);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -104,26 +98,23 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch genesis block",
|
summary = "Fetch genesis block",
|
||||||
description = "Returns the genesis block",
|
description = "Returns the genesis block",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET first"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET first"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the block",
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
description = "the block",
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BlockWithTransactions getFirstBlock(@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
public BlockWithTransactions getFirstBlock(@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
BlockData blockData = repository.getBlockRepository().fromHeight(1);
|
BlockData blockData = repository.getBlockRepository().fromHeight(1);
|
||||||
return new BlockWithTransactions(repository, blockData, includeTransactions);
|
return packageBlockData(repository, blockData, includeTransactions);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -136,26 +127,23 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch last/newest block in blockchain",
|
summary = "Fetch last/newest block in blockchain",
|
||||||
description = "Returns the last valid block",
|
description = "Returns the last valid block",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET last"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET last"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the block",
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
description = "the block",
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BlockWithTransactions getLastBlock(@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
public BlockWithTransactions getLastBlock(@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
BlockData blockData = repository.getBlockRepository().getLastBlock();
|
BlockData blockData = repository.getBlockRepository().getLastBlock();
|
||||||
return new BlockWithTransactions(repository, blockData, includeTransactions);
|
return packageBlockData(repository, blockData, includeTransactions);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -168,28 +156,23 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch child block using base64 signature of parent block",
|
summary = "Fetch child block using base64 signature of parent block",
|
||||||
description = "Returns the child block of the block that matches the given signature",
|
description = "Returns the child block of the block that matches the given signature",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET child:signature"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET child:signature"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@Extension(properties = {
|
), @Extension(properties =
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
})
|
responses =
|
||||||
},
|
{ @ApiResponse(
|
||||||
responses = {
|
description = "the block",
|
||||||
@ApiResponse(
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
description = "the block",
|
extensions =
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
extensions = {
|
) }
|
||||||
@Extension(name = "translation", properties = {
|
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BlockWithTransactions getChild(@PathParam("signature") String signature, @Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
public BlockWithTransactions getChild(@PathParam("signature") String signature,
|
||||||
|
@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
||||||
// Decode signature
|
// Decode signature
|
||||||
byte[] signatureBytes;
|
byte[] signatureBytes;
|
||||||
try {
|
try {
|
||||||
@ -202,16 +185,13 @@ public class BlocksResource {
|
|||||||
BlockData blockData = repository.getBlockRepository().fromSignature(signatureBytes);
|
BlockData blockData = repository.getBlockRepository().fromSignature(signatureBytes);
|
||||||
|
|
||||||
// Check block exists
|
// Check block exists
|
||||||
if(blockData == null)
|
if (blockData == null)
|
||||||
throw this.apiErrorFactory.createError(ApiError.BLOCK_NO_EXISTS);
|
throw this.apiErrorFactory.createError(ApiError.BLOCK_NO_EXISTS);
|
||||||
|
|
||||||
BlockData childBlockData = repository.getBlockRepository().fromReference(signatureBytes);
|
BlockData childBlockData = repository.getBlockRepository().fromReference(signatureBytes);
|
||||||
|
|
||||||
// Check child exists
|
// Checking child exists is handled by packageBlockData()
|
||||||
if(childBlockData == null)
|
return packageBlockData(repository, childBlockData, includeTransactions);
|
||||||
throw this.apiErrorFactory.createError(ApiError.BLOCK_NO_EXISTS);
|
|
||||||
|
|
||||||
return new BlockWithTransactions(repository, childBlockData, includeTransactions);
|
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -224,21 +204,18 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Generating balance of next block",
|
summary = "Generating balance of next block",
|
||||||
description = "Calculates the generating balance of the block that will follow the last block",
|
description = "Calculates the generating balance of the block that will follow the last block",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET generatingbalance"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET generatingbalance"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the generating balance",
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
description = "the generating balance",
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BigDecimal getGeneratingBalance() {
|
public BigDecimal getGeneratingBalance() {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -257,26 +234,21 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Generating balance of block after specific block",
|
summary = "Generating balance of block after specific block",
|
||||||
description = "Calculates the generating balance of the block that will follow the block that matches the signature",
|
description = "Calculates the generating balance of the block that will follow the block that matches the signature",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET generatingbalance:signature"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET generatingbalance:signature"),
|
||||||
@Extension(properties = {
|
@ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
), @Extension(properties =
|
||||||
})
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
},
|
responses =
|
||||||
responses = {
|
{ @ApiResponse(
|
||||||
@ApiResponse(
|
description = "the block",
|
||||||
description = "the block",
|
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
||||||
content = @Content(schema = @Schema(implementation = BigDecimal.class)),
|
extensions =
|
||||||
extensions = {
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
@Extension(name = "translation", properties = {
|
) }
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BigDecimal getGeneratingBalance(@PathParam("signature") String signature) {
|
public BigDecimal getGeneratingBalance(@PathParam("signature") String signature) {
|
||||||
// Decode signature
|
// Decode signature
|
||||||
@ -308,21 +280,18 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Estimated time to forge next block",
|
summary = "Estimated time to forge next block",
|
||||||
description = "Calculates the time it should take for the network to generate the next block",
|
description = "Calculates the time it should take for the network to generate the next block",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET time"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET time"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the time in seconds", // in seconds?
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = long.class)),
|
description = "the time in seconds", // in seconds?
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public long getTimePerBlock() {
|
public long getTimePerBlock() {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -340,21 +309,18 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Estimated time to forge block given generating balance",
|
summary = "Estimated time to forge block given generating balance",
|
||||||
description = "Calculates the time it should take for the network to generate blocks based on specified generating balance",
|
description = "Calculates the time it should take for the network to generate blocks based on specified generating balance",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET time:generatingbalance"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET time:generatingbalance"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the time", // in seconds?
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = long.class)),
|
description = "the time", // in seconds?
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public long getTimePerBlock(@PathParam("generating") BigDecimal generatingbalance) {
|
public long getTimePerBlock(@PathParam("generating") BigDecimal generatingbalance) {
|
||||||
return Block.calcForgingDelay(generatingbalance);
|
return Block.calcForgingDelay(generatingbalance);
|
||||||
@ -365,21 +331,18 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Current blockchain height",
|
summary = "Current blockchain height",
|
||||||
description = "Returns the block height of the last block.",
|
description = "Returns the block height of the last block.",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET height"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET height"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
responses = {
|
),
|
||||||
@ApiResponse(
|
responses =
|
||||||
description = "the height",
|
{ @ApiResponse(
|
||||||
content = @Content(schema = @Schema(implementation = int.class)),
|
description = "the height",
|
||||||
extensions = {
|
content = @Content(schema = @Schema(implementation = int.class)),
|
||||||
@Extension(name = "translation", properties = {
|
extensions =
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
})
|
) }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -396,26 +359,20 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Height of specific block",
|
summary = "Height of specific block",
|
||||||
description = "Returns the block height of the block that matches the given signature",
|
description = "Returns the block height of the block that matches the given signature",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET height:signature"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET height:signature"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@Extension(properties = {
|
), @Extension(properties =
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
})
|
responses =
|
||||||
},
|
{ @ApiResponse(
|
||||||
responses = {
|
description = "the height",
|
||||||
@ApiResponse(
|
content = @Content(schema = @Schema(implementation = int.class)),
|
||||||
description = "the height",
|
extensions =
|
||||||
content = @Content(schema = @Schema(implementation = int.class)),
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
extensions = {
|
) }
|
||||||
@Extension(name = "translation", properties = {
|
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public int getHeight(@PathParam("signature") String signature) {
|
public int getHeight(@PathParam("signature") String signature) {
|
||||||
// Decode signature
|
// Decode signature
|
||||||
@ -446,31 +403,26 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch block using block height",
|
summary = "Fetch block using block height",
|
||||||
description = "Returns the block with given height",
|
description = "Returns the block with given height",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET byheight:height"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET byheight:height"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@Extension(properties = {
|
), @Extension(properties =
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"BLOCK_NO_EXISTS\"]", parseValue = true),
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
})
|
responses =
|
||||||
},
|
{ @ApiResponse(
|
||||||
responses = {
|
description = "the block",
|
||||||
@ApiResponse(
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
description = "the block",
|
extensions =
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
extensions = {
|
) }
|
||||||
@Extension(name = "translation", properties = {
|
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public BlockWithTransactions getByHeight(@PathParam("height") int height, @Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
public BlockWithTransactions getByHeight(@PathParam("height") int height,
|
||||||
|
@Parameter(ref = "includeTransactions") @QueryParam("includeTransactions") boolean includeTransactions) {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
BlockData blockData = repository.getBlockRepository().fromHeight(height);
|
BlockData blockData = repository.getBlockRepository().fromHeight(height);
|
||||||
return new BlockWithTransactions(repository, blockData, includeTransactions);
|
return packageBlockData(repository, blockData, includeTransactions);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -483,26 +435,20 @@ public class BlocksResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch blocks starting with given height",
|
summary = "Fetch blocks starting with given height",
|
||||||
description = "Returns blocks starting with given height.",
|
description = "Returns blocks starting with given height.",
|
||||||
extensions = {
|
extensions =
|
||||||
@Extension(name = "translation", properties = {
|
{ @Extension(
|
||||||
@ExtensionProperty(name="path", value="GET byheight:height"),
|
name = "translation",
|
||||||
@ExtensionProperty(name="description.key", value="operation:description")
|
properties =
|
||||||
}),
|
{ @ExtensionProperty(name = "path", value = "GET byheight:height"), @ExtensionProperty(name = "description.key", value = "operation:description") }
|
||||||
@Extension(properties = {
|
), @Extension(properties =
|
||||||
@ExtensionProperty(name="apiErrors", value="[\"BLOCK_NO_EXISTS\"]", parseValue = true),
|
{ @ExtensionProperty(name = "apiErrors", value = "[\"BLOCK_NO_EXISTS\"]", parseValue = true), }) },
|
||||||
})
|
responses =
|
||||||
},
|
{ @ApiResponse(
|
||||||
responses = {
|
description = "blocks",
|
||||||
@ApiResponse(
|
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
||||||
description = "blocks",
|
extensions =
|
||||||
content = @Content(schema = @Schema(implementation = BlockWithTransactions.class)),
|
{ @Extension(name = "translation", properties = { @ExtensionProperty(name = "description.key", value = "success_response:description") }) }
|
||||||
extensions = {
|
) }
|
||||||
@Extension(name = "translation", properties = {
|
|
||||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
public List<BlockWithTransactions> getBlockRange(@PathParam("height") int height, @Parameter(ref = "count") @QueryParam("count") int count) {
|
public List<BlockWithTransactions> getBlockRange(@PathParam("height") int height, @Parameter(ref = "count") @QueryParam("count") int count) {
|
||||||
boolean includeTransactions = false;
|
boolean includeTransactions = false;
|
||||||
@ -516,7 +462,7 @@ public class BlocksResource {
|
|||||||
// Run out of blocks!
|
// Run out of blocks!
|
||||||
break;
|
break;
|
||||||
|
|
||||||
blocks.add(new BlockWithTransactions(repository, blockData, includeTransactions));
|
blocks.add(packageBlockData(repository, blockData, includeTransactions));
|
||||||
}
|
}
|
||||||
|
|
||||||
return blocks;
|
return blocks;
|
||||||
@ -527,4 +473,17 @@ public class BlocksResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BlockWithTransactions packageBlockData(Repository repository, BlockData blockData, boolean includeTransactions) throws DataException {
|
||||||
|
if (blockData == null)
|
||||||
|
throw this.apiErrorFactory.createError(ApiError.BLOCK_NO_EXISTS);
|
||||||
|
|
||||||
|
List<TransactionData> transactions = null;
|
||||||
|
if (includeTransactions) {
|
||||||
|
Block block = new Block(repository, blockData);
|
||||||
|
transactions = block.getTransactions().stream().map(transaction -> transaction.getTransactionData()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BlockWithTransactions(blockData, transactions);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ public class TransactionsResource {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
public List<TransactionData> searchTransactions(@QueryParam("startBlock") Integer startBlock, @QueryParam("blockLimit") Integer blockLimit,
|
public List<TransactionData> searchTransactions(@QueryParam("startBlock") Integer startBlock, @QueryParam("blockLimit") Integer blockLimit,
|
||||||
@QueryParam("txType") Integer txTypeNum, @QueryParam("address") String address, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") int offset) {
|
@QueryParam("txType") Integer txTypeNum, @QueryParam("address") String address, @Parameter(ref = "limit") @QueryParam("limit") int limit, @Parameter(ref = "offset") @QueryParam("offset") int offset) {
|
||||||
if ((txTypeNum == null || txTypeNum == 0) && (address == null || address.isEmpty()))
|
if ((txTypeNum == null || txTypeNum == 0) && (address == null || address.isEmpty()))
|
||||||
throw this.apiErrorFactory.createError(ApiError.INVALID_CRITERIA);
|
throw this.apiErrorFactory.createError(ApiError.INVALID_CRITERIA);
|
||||||
|
|
||||||
|
@ -2,17 +2,17 @@ package api.models;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import api.ApiError;
|
|
||||||
import api.ApiErrorFactory;
|
|
||||||
import data.account.AccountBalanceData;
|
import data.account.AccountBalanceData;
|
||||||
import data.assets.AssetData;
|
import data.assets.AssetData;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import repository.DataException;
|
|
||||||
import repository.Repository;
|
|
||||||
|
|
||||||
@Schema(description = "Asset with (optional) asset holders")
|
@Schema(description = "Asset info, maybe including asset holders")
|
||||||
|
// All properties to be converted to JSON via JAX-RS
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class AssetWithHolders {
|
public class AssetWithHolders {
|
||||||
|
|
||||||
@Schema(implementation = AssetData.class, name = "asset", title = "asset data")
|
@Schema(implementation = AssetData.class, name = "asset", title = "asset data")
|
||||||
@ -22,18 +22,12 @@ public class AssetWithHolders {
|
|||||||
public List<AccountBalanceData> holders;
|
public List<AccountBalanceData> holders;
|
||||||
|
|
||||||
// For JAX-RS
|
// For JAX-RS
|
||||||
@SuppressWarnings("unused")
|
protected AssetWithHolders() {
|
||||||
private AssetWithHolders() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetWithHolders(Repository repository, AssetData assetData, boolean includeHolders) throws DataException {
|
public AssetWithHolders(AssetData assetData, List<AccountBalanceData> holders) {
|
||||||
if (assetData == null)
|
|
||||||
throw ApiErrorFactory.getInstance().createError(ApiError.INVALID_ASSET_ID);
|
|
||||||
|
|
||||||
this.assetData = assetData;
|
this.assetData = assetData;
|
||||||
|
this.holders = holders;
|
||||||
if (includeHolders)
|
|
||||||
this.holders = repository.getAccountRepository().getAssetBalances(assetData.getAssetId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
package api.models;
|
package api.models;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import api.ApiError;
|
|
||||||
import api.ApiErrorFactory;
|
|
||||||
import data.block.BlockData;
|
import data.block.BlockData;
|
||||||
import data.transaction.TransactionData;
|
import data.transaction.TransactionData;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import qora.block.Block;
|
|
||||||
import repository.DataException;
|
|
||||||
import repository.Repository;
|
|
||||||
|
|
||||||
@Schema(description = "Block with (optional) transactions")
|
@Schema(description = "Block info, maybe including transactions")
|
||||||
|
// All properties to be converted to JSON via JAX-RS
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class BlockWithTransactions {
|
public class BlockWithTransactions {
|
||||||
|
|
||||||
@ -30,16 +25,9 @@ public class BlockWithTransactions {
|
|||||||
protected BlockWithTransactions() {
|
protected BlockWithTransactions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockWithTransactions(Repository repository, BlockData blockData, boolean includeTransactions) throws DataException {
|
public BlockWithTransactions(BlockData blockData, List<TransactionData> transactions) {
|
||||||
if (blockData == null)
|
|
||||||
throw ApiErrorFactory.getInstance().createError(ApiError.BLOCK_NO_EXISTS);
|
|
||||||
|
|
||||||
this.blockData = blockData;
|
this.blockData = blockData;
|
||||||
|
this.transactions = transactions;
|
||||||
if (includeTransactions) {
|
|
||||||
Block block = new Block(repository, blockData);
|
|
||||||
this.transactions = block.getTransactions().stream().map(transaction -> transaction.getTransactionData()).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
33
src/api/models/OrderWithTrades.java
Normal file
33
src/api/models/OrderWithTrades.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package api.models;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
import data.assets.OrderData;
|
||||||
|
import data.assets.TradeData;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "Asset order info, maybe including trades")
|
||||||
|
// All properties to be converted to JSON via JAX-RS
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class OrderWithTrades {
|
||||||
|
|
||||||
|
@Schema(implementation = OrderData.class, name = "order", title = "order data")
|
||||||
|
@XmlElement(name = "order")
|
||||||
|
public OrderData orderData;
|
||||||
|
|
||||||
|
List<TradeData> trades;
|
||||||
|
|
||||||
|
// For JAX-RS
|
||||||
|
protected OrderWithTrades() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderWithTrades(OrderData orderData, List<TradeData> trades) {
|
||||||
|
this.orderData = orderData;
|
||||||
|
this.trades = trades;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
package api.models;
|
package api.models;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import data.assets.OrderData;
|
import data.assets.OrderData;
|
||||||
import data.assets.TradeData;
|
import data.assets.TradeData;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import repository.DataException;
|
|
||||||
import repository.Repository;
|
|
||||||
|
|
||||||
@Schema(description = "Asset trade, with order info")
|
@Schema(description = "Asset trade, including order info")
|
||||||
|
// All properties to be converted to JSON via JAX-RS
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class TradeWithOrderInfo {
|
public class TradeWithOrderInfo {
|
||||||
|
|
||||||
@Schema(implementation = TradeData.class, name = "trade", title = "trade data")
|
@Schema(implementation = TradeData.class, name = "trade", title = "trade data")
|
||||||
@ -27,11 +29,10 @@ public class TradeWithOrderInfo {
|
|||||||
protected TradeWithOrderInfo() {
|
protected TradeWithOrderInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TradeWithOrderInfo(Repository repository, TradeData tradeData) throws DataException {
|
public TradeWithOrderInfo(TradeData tradeData, OrderData initiatingOrderData, OrderData targetOrderData) {
|
||||||
this.tradeData = tradeData;
|
this.tradeData = tradeData;
|
||||||
|
this.initiatingOrderData = initiatingOrderData;
|
||||||
this.initiatingOrderData = repository.getAssetRepository().fromOrderId(tradeData.getInitiator());
|
this.targetOrderData = targetOrderData;
|
||||||
this.targetOrderData = repository.getAssetRepository().fromOrderId(tradeData.getTarget());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.eclipse.persistence.sessions.Session;
|
|||||||
|
|
||||||
public class TransactionClassExtractor extends ClassExtractor {
|
public class TransactionClassExtractor extends ClassExtractor {
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public Class extractClassFromRow(Record record, Session session) {
|
public Class extractClassFromRow(Record record, Session session) {
|
||||||
// Never called anyway?
|
// Never called anyway?
|
||||||
|
@ -5,7 +5,7 @@ import java.math.BigDecimal;
|
|||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
//All properties to be converted to JSON via JAX-RS
|
// All properties to be converted to JSON via JAX-RS
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class PaymentData {
|
public class PaymentData {
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package qora.assets;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -209,10 +210,11 @@ public class Order {
|
|||||||
|
|
||||||
public void orphan() throws DataException {
|
public void orphan() throws DataException {
|
||||||
// Orphan trades that occurred as a result of this order
|
// Orphan trades that occurred as a result of this order
|
||||||
for (TradeData tradeData : getTrades()) {
|
for (TradeData tradeData : getTrades())
|
||||||
Trade trade = new Trade(this.repository, tradeData);
|
if (Arrays.equals(this.orderData.getOrderId(), tradeData.getInitiator())) {
|
||||||
trade.orphan();
|
Trade trade = new Trade(this.repository, tradeData);
|
||||||
}
|
trade.orphan();
|
||||||
|
}
|
||||||
|
|
||||||
// Delete this order from repository
|
// Delete this order from repository
|
||||||
this.repository.getAssetRepository().delete(this.orderData.getOrderId());
|
this.repository.getAssetRepository().delete(this.orderData.getOrderId());
|
||||||
|
@ -40,6 +40,7 @@ public interface AssetRepository {
|
|||||||
|
|
||||||
public List<TradeData> getTrades(long haveAssetId, long wantAssetId) throws DataException;
|
public List<TradeData> getTrades(long haveAssetId, long wantAssetId) throws DataException;
|
||||||
|
|
||||||
|
/** Returns TradeData for trades where orderId was involved, i.e. either initiating OR target order */
|
||||||
public List<TradeData> getOrdersTrades(byte[] orderId) throws DataException;
|
public List<TradeData> getOrdersTrades(byte[] orderId) throws DataException;
|
||||||
|
|
||||||
public void save(TradeData tradeData) throws DataException;
|
public void save(TradeData tradeData) throws DataException;
|
||||||
|
@ -257,19 +257,21 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TradeData> getOrdersTrades(byte[] initiatingOrderId) throws DataException {
|
public List<TradeData> getOrdersTrades(byte[] orderId) throws DataException {
|
||||||
List<TradeData> trades = new ArrayList<TradeData>();
|
List<TradeData> trades = new ArrayList<TradeData>();
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository
|
try (ResultSet resultSet = this.repository.checkedExecute(
|
||||||
.checkedExecute("SELECT target_order_id, amount, price, traded FROM AssetTrades WHERE initiating_order_id = ?", initiatingOrderId)) {
|
"SELECT initiating_order_id, target_order_id, amount, price, traded FROM AssetTrades WHERE initiating_order_id = ? OR target_order_id = ?",
|
||||||
|
orderId, orderId)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return trades;
|
return trades;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
byte[] targetOrderId = resultSet.getBytes(1);
|
byte[] initiatingOrderId = resultSet.getBytes(1);
|
||||||
BigDecimal amount = resultSet.getBigDecimal(2);
|
byte[] targetOrderId = resultSet.getBytes(2);
|
||||||
BigDecimal price = resultSet.getBigDecimal(3);
|
BigDecimal amount = resultSet.getBigDecimal(3);
|
||||||
long timestamp = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
BigDecimal price = resultSet.getBigDecimal(4);
|
||||||
|
long timestamp = resultSet.getTimestamp(5, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||||
|
|
||||||
TradeData trade = new TradeData(initiatingOrderId, targetOrderId, amount, price, timestamp);
|
TradeData trade = new TradeData(initiatingOrderId, targetOrderId, amount, price, timestamp);
|
||||||
trades.add(trade);
|
trades.add(trade);
|
||||||
|
@ -310,11 +310,7 @@ public class BlockTransformer extends Transformer {
|
|||||||
Order order = orderTransaction.getOrder();
|
Order order = orderTransaction.getOrder();
|
||||||
List<TradeData> trades = order.getTrades();
|
List<TradeData> trades = order.getTrades();
|
||||||
|
|
||||||
// Filter out trades with initiatingOrderId that don't match this order
|
if (trades.stream().anyMatch(tradeData -> Arrays.equals(tradeData.getInitiator(), order.getOrderData().getOrderId()))) {
|
||||||
trades.removeIf((TradeData tradeData) -> !Arrays.equals(tradeData.getInitiator(), order.getOrderData().getOrderId()));
|
|
||||||
|
|
||||||
// Any trades left?
|
|
||||||
if (!trades.isEmpty()) {
|
|
||||||
tradesHappened = true;
|
tradesHappened = true;
|
||||||
// No need to check any further
|
// No need to check any further
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user