From 8dffe1e3ac884161c08234cd5859475fcf02fde4 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 22 Jan 2023 18:59:46 +0000 Subject: [PATCH] Another rewrite of Q-App APIs, which removes the /apps/* redirects and instead calls the main APIs directly. - All APIs are now served over the gateway and domain map, with the exception of /admin/* - AdminResource moved to a "restricted" folder, so that it isn't served over the gateway/domainMap ports. - This opens the door to websites/apps calling core APIs directly for certain read-only functions, as an alternative to using qortalRequest(). --- src/main/java/org/qortal/api/ApiService.java | 3 +- .../java/org/qortal/api/DomainMapService.java | 3 +- .../java/org/qortal/api/GatewayService.java | 2 +- .../api/apps/resource/AppsResource.java | 257 ------------------ .../org/qortal/api/resource/AppsResource.java | 57 ++++ .../resource/AdminResource.java | 2 +- src/main/resources/q-apps/q-apps.js | 63 ++--- .../org/qortal/test/api/AdminApiTests.java | 2 +- 8 files changed, 89 insertions(+), 300 deletions(-) delete mode 100644 src/main/java/org/qortal/api/apps/resource/AppsResource.java create mode 100644 src/main/java/org/qortal/api/resource/AppsResource.java rename src/main/java/org/qortal/api/{ => restricted}/resource/AdminResource.java (99%) diff --git a/src/main/java/org/qortal/api/ApiService.java b/src/main/java/org/qortal/api/ApiService.java index 78bccb6a..4676fa49 100644 --- a/src/main/java/org/qortal/api/ApiService.java +++ b/src/main/java/org/qortal/api/ApiService.java @@ -14,7 +14,6 @@ import java.security.SecureRandom; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; -import org.checkerframework.checker.units.qual.A; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.rewrite.handler.RedirectPatternRule; import org.eclipse.jetty.rewrite.handler.RewriteHandler; @@ -53,7 +52,7 @@ public class ApiService { private ApiService() { this.config = new ResourceConfig(); - this.config.packages("org.qortal.api.resource", "org.qortal.api.apps.resource"); + this.config.packages("org.qortal.api.resource", "org.qortal.api.restricted.resource"); this.config.register(OpenApiResource.class); this.config.register(ApiDefinition.class); this.config.register(AnnotationPostProcessor.class); diff --git a/src/main/java/org/qortal/api/DomainMapService.java b/src/main/java/org/qortal/api/DomainMapService.java index ba0fa067..f5eb8105 100644 --- a/src/main/java/org/qortal/api/DomainMapService.java +++ b/src/main/java/org/qortal/api/DomainMapService.java @@ -3,7 +3,6 @@ package org.qortal.api; import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.rewrite.handler.RewriteHandler; -import org.eclipse.jetty.rewrite.handler.RewritePatternRule; import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.InetAccessHandler; @@ -38,7 +37,7 @@ public class DomainMapService { private DomainMapService() { this.config = new ResourceConfig(); - this.config.packages("org.qortal.api.domainmap.resource"); + this.config.packages("org.qortal.api.resource", "org.qortal.api.domainmap.resource"); this.config.register(OpenApiResource.class); this.config.register(ApiDefinition.class); this.config.register(AnnotationPostProcessor.class); diff --git a/src/main/java/org/qortal/api/GatewayService.java b/src/main/java/org/qortal/api/GatewayService.java index 0c8f471d..cebec61b 100644 --- a/src/main/java/org/qortal/api/GatewayService.java +++ b/src/main/java/org/qortal/api/GatewayService.java @@ -37,7 +37,7 @@ public class GatewayService { private GatewayService() { this.config = new ResourceConfig(); - this.config.packages("org.qortal.api.gateway.resource", "org.qortal.api.apps.resource"); + this.config.packages("org.qortal.api.resource", "org.qortal.api.gateway.resource"); this.config.register(OpenApiResource.class); this.config.register(ApiDefinition.class); this.config.register(AnnotationPostProcessor.class); diff --git a/src/main/java/org/qortal/api/apps/resource/AppsResource.java b/src/main/java/org/qortal/api/apps/resource/AppsResource.java deleted file mode 100644 index db72a13c..00000000 --- a/src/main/java/org/qortal/api/apps/resource/AppsResource.java +++ /dev/null @@ -1,257 +0,0 @@ -package org.qortal.api.apps.resource; - -import com.google.common.io.Resources; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.Hidden; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.qortal.api.*; -import org.qortal.api.model.NameSummary; -import org.qortal.api.resource.*; -import org.qortal.arbitrary.misc.Service; -import org.qortal.crosschain.SupportedBlockchain; -import org.qortal.data.account.AccountData; -import org.qortal.data.arbitrary.ArbitraryResourceInfo; -import org.qortal.data.arbitrary.ArbitraryResourceStatus; -import org.qortal.data.at.ATData; -import org.qortal.data.block.BlockData; -import org.qortal.data.chat.ChatMessage; -import org.qortal.data.group.GroupData; -import org.qortal.data.naming.NameData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.transaction.Transaction; -import org.qortal.utils.Base58; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import java.io.IOException; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.List; - - -@Path("/apps") -@Tag(name = "Apps") -public class AppsResource { - - @Context HttpServletRequest request; - @Context HttpServletResponse response; - @Context ServletContext context; - - @GET - @Path("/q-apps.js") - @Hidden // For internal Q-App API use only - @Operation( - summary = "Javascript interface for Q-Apps", - responses = { - @ApiResponse( - description = "javascript", - content = @Content( - mediaType = MediaType.TEXT_PLAIN, - schema = @Schema( - type = "string" - ) - ) - ) - } - ) - public String getQAppsJs() { - URL url = Resources.getResource("q-apps/q-apps.js"); - try { - return Resources.toString(url, StandardCharsets.UTF_8); - } catch (IOException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FILE_NOT_FOUND); - } - } - - @GET - @Path("/q-apps-helper.js") - @Hidden // For testing only - public String getQAppsHelperJs() { - URL url = Resources.getResource("q-apps/q-apps-helper.js"); - try { - return Resources.toString(url, StandardCharsets.UTF_8); - } catch (IOException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FILE_NOT_FOUND); - } - } - - @GET - @Path("/account") - @Hidden // For internal Q-App API use only - public AccountData getAccount(@QueryParam("address") String address) { - AddressesResource addressesResource = (AddressesResource) buildResource(AddressesResource.class, request, response, context); - return addressesResource.getAccountInfo(address); - } - - @GET - @Path("/account/names") - @Hidden // For internal Q-App API use only - public List getAccountNames(@QueryParam("address") String address) { - NamesResource namesResource = (NamesResource) buildResource(NamesResource.class, request, response, context); - return namesResource.getNamesByAddress(address, 0, 0 ,false); - } - - @GET - @Path("/name") - @Hidden // For internal Q-App API use only - public NameData getName(@QueryParam("name") String name) { - NamesResource namesResource = (NamesResource) buildResource(NamesResource.class, request, response, context); - return namesResource.getName(name); - } - - @GET - @Path("/chatmessages") - @Hidden // For internal Q-App API use only - public List searchChatMessages(@QueryParam("before") Long before, @QueryParam("after") Long after, @QueryParam("txGroupId") Integer txGroupId, @QueryParam("involving") List involvingAddresses, @QueryParam("reference") String reference, @QueryParam("chatReference") String chatReference, @QueryParam("hasChatReference") Boolean hasChatReference, @QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset, @QueryParam("reverse") Boolean reverse) { - ChatResource chatResource = (ChatResource) buildResource(ChatResource.class, request, response, context); - return chatResource.searchChat(before, after, txGroupId, involvingAddresses, reference, chatReference, hasChatReference, limit, offset, reverse); - } - - @GET - @Path("/resources") - @Hidden // For internal Q-App API use only - public List getResources(@QueryParam("service") Service service, @QueryParam("identifier") String identifier, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, @Parameter(description = "Filter names by list") @QueryParam("nameListFilter") String nameListFilter, @Parameter(description = "Include status") @QueryParam("includeStatus") Boolean includeStatus, @Parameter(description = "Include metadata") @QueryParam("includeMetadata") Boolean includeMetadata, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse) { - ArbitraryResource arbitraryResource = (ArbitraryResource) buildResource(ArbitraryResource.class, request, response, context); - return arbitraryResource.getResources(service, identifier, defaultResource, limit, offset, reverse, nameListFilter, includeStatus, includeMetadata); - } - - @GET - @Path("/resourcestatus") - @Hidden // For internal Q-App API use only - public ArbitraryResourceStatus getResourceStatus(@QueryParam("service") Service service, @QueryParam("name") String name, @QueryParam("identifier") String identifier) { - ArbitraryResource arbitraryResource = (ArbitraryResource) buildResource(ArbitraryResource.class, request, response, context); - ApiKey apiKey = ApiService.getInstance().getApiKey(); - return arbitraryResource.getResourceStatus(apiKey.toString(), service, name, identifier, false); - } - - @GET - @Path("/resource") - @Hidden // For internal Q-App API use only - public HttpServletResponse getResource(@QueryParam("service") Service service, @QueryParam("name") String name, @QueryParam("identifier") String identifier, @QueryParam("filepath") String filepath, @QueryParam("rebuild") boolean rebuild) { - ArbitraryResource arbitraryResource = (ArbitraryResource) buildResource(ArbitraryResource.class, request, response, context); - ApiKey apiKey = ApiService.getInstance().getApiKey(); - return arbitraryResource.get(apiKey.toString(), service, name, identifier, filepath, rebuild, false, 5); - } - - @GET - @Path("/groups") - @Hidden // For internal Q-App API use only - public List listGroups(@Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse) { - GroupsResource groupsResource = (GroupsResource) buildResource(GroupsResource.class, request, response, context); - return groupsResource.getAllGroups(limit, offset, reverse); - } - - @GET - @Path("/balance") - @Hidden // For internal Q-App API use only - public BigDecimal getBalance(@QueryParam("assetId") long assetId, @QueryParam("address") String address) { - AddressesResource addressesResource = (AddressesResource) buildResource(AddressesResource.class, request, response, context); - return addressesResource.getBalance(address, assetId); - } - - @GET - @Path("/at") - @Hidden // For internal Q-App API use only - public ATData getAT(@QueryParam("atAddress") String atAddress) { - AtResource atResource = (AtResource) buildResource(AtResource.class, request, response, context); - return atResource.getByAddress(atAddress); - } - - @GET - @Path("/atdata") - @Hidden // For internal Q-App API use only - public String getATData(@QueryParam("atAddress") String atAddress) { - AtResource atResource = (AtResource) buildResource(AtResource.class, request, response, context); - return Base58.encode(atResource.getDataByAddress(atAddress)); - } - - @GET - @Path("/ats") - @Hidden // For internal Q-App API use only - public List listATs(@QueryParam("codeHash58") String codeHash58, @QueryParam("isExecutable") Boolean isExecutable, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse) { - AtResource atResource = (AtResource) buildResource(AtResource.class, request, response, context); - return atResource.getByFunctionality(codeHash58, isExecutable, limit, offset, reverse); - } - - @GET - @Path("/block") - @Hidden // For internal Q-App API use only - public BlockData fetchBlockByHeight(@QueryParam("signature") String signature58, @QueryParam("includeOnlineSignatures") Boolean includeOnlineSignatures) { - BlocksResource blocksResource = (BlocksResource) buildResource(BlocksResource.class, request, response, context); - return blocksResource.getBlock(signature58, includeOnlineSignatures); - } - - @GET - @Path("/block/byheight") - @Hidden // For internal Q-App API use only - public BlockData fetchBlockByHeight(@QueryParam("height") int height, @QueryParam("includeOnlineSignatures") Boolean includeOnlineSignatures) { - BlocksResource blocksResource = (BlocksResource) buildResource(BlocksResource.class, request, response, context); - return blocksResource.getByHeight(height, includeOnlineSignatures); - } - - @GET - @Path("/block/range") - @Hidden // For internal Q-App API use only - public List getBlockRange(@QueryParam("height") int height, @Parameter(ref = "count") @QueryParam("count") int count, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse, @QueryParam("includeOnlineSignatures") Boolean includeOnlineSignatures) { - BlocksResource blocksResource = (BlocksResource) buildResource(BlocksResource.class, request, response, context); - return blocksResource.getBlockRange(height, count, reverse, includeOnlineSignatures); - } - - @GET - @Path("/transactions/search") - @Hidden // For internal Q-App API use only - public List searchTransactions(@QueryParam("startBlock") Integer startBlock, @QueryParam("blockLimit") Integer blockLimit, @QueryParam("txGroupId") Integer txGroupId, @QueryParam("txType") List txTypes, @QueryParam("address") String address, @Parameter() @QueryParam("confirmationStatus") TransactionsResource.ConfirmationStatus confirmationStatus, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse) { - TransactionsResource transactionsResource = (TransactionsResource) buildResource(TransactionsResource.class, request, response, context); - return transactionsResource.searchTransactions(startBlock, blockLimit, txGroupId, txTypes, address, confirmationStatus, limit, offset, reverse); - } - - @GET - @Path("/price") - @Hidden // For internal Q-App API use only - public long getPrice(@QueryParam("blockchain") SupportedBlockchain foreignBlockchain, @QueryParam("maxtrades") Integer maxtrades, @QueryParam("inverse") Boolean inverse) { - CrossChainResource crossChainResource = (CrossChainResource) buildResource(CrossChainResource.class, request, response, context); - return crossChainResource.getTradePriceEstimate(foreignBlockchain, maxtrades, inverse); - } - - - public static Object buildResource(Class resourceClass, HttpServletRequest request, HttpServletResponse response, ServletContext context) { - try { - Object resource = resourceClass.getDeclaredConstructor().newInstance(); - - Field requestField = resourceClass.getDeclaredField("request"); - requestField.setAccessible(true); - requestField.set(resource, request); - - try { - Field responseField = resourceClass.getDeclaredField("response"); - responseField.setAccessible(true); - responseField.set(resource, response); - } catch (NoSuchFieldException e) { - // Ignore - } - - try { - Field contextField = resourceClass.getDeclaredField("context"); - contextField.setAccessible(true); - contextField.set(resource, context); - } catch (NoSuchFieldException e) { - // Ignore - } - - return resource; - } catch (Exception e) { - throw new RuntimeException("Failed to build API resource " + resourceClass.getName() + ": " + e.getMessage(), e); - } - } - -} diff --git a/src/main/java/org/qortal/api/resource/AppsResource.java b/src/main/java/org/qortal/api/resource/AppsResource.java new file mode 100644 index 00000000..2d048c00 --- /dev/null +++ b/src/main/java/org/qortal/api/resource/AppsResource.java @@ -0,0 +1,57 @@ +package org.qortal.api.resource; + +import com.google.common.io.Resources; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.qortal.api.*; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; + + +@Path("/apps") +@Tag(name = "Apps") +public class AppsResource { + + @Context HttpServletRequest request; + @Context HttpServletResponse response; + @Context ServletContext context; + + @GET + @Path("/q-apps.js") + @Hidden // For internal Q-App API use only + @Operation( + summary = "Javascript interface for Q-Apps", + responses = { + @ApiResponse( + description = "javascript", + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string" + ) + ) + ) + } + ) + public String getQAppsJs() { + URL url = Resources.getResource("q-apps/q-apps.js"); + try { + return Resources.toString(url, StandardCharsets.UTF_8); + } catch (IOException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FILE_NOT_FOUND); + } + } + +} diff --git a/src/main/java/org/qortal/api/resource/AdminResource.java b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java similarity index 99% rename from src/main/java/org/qortal/api/resource/AdminResource.java rename to src/main/java/org/qortal/api/restricted/resource/AdminResource.java index 9cff1bbb..06bafcc6 100644 --- a/src/main/java/org/qortal/api/resource/AdminResource.java +++ b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java @@ -1,4 +1,4 @@ -package org.qortal.api.resource; +package org.qortal.api.restricted.resource; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index 2a2c04a5..745c750d 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -60,25 +60,25 @@ window.addEventListener("message", (event) => { switch (data.action) { case "GET_ACCOUNT_DATA": - response = httpGet("/apps/account?address=" + data.address); + response = httpGet("/addresses/" + data.address); break; case "GET_ACCOUNT_NAMES": - response = httpGet("/apps/account/names?address=" + data.address); + response = httpGet("/names/address/" + data.address); break; case "GET_NAME_DATA": - response = httpGet("/apps/name?name=" + data.name); + response = httpGet("/names/" + data.name); break; case "SEARCH_QDN_RESOURCES": - url = "/apps/resources?"; + url = "/arbitrary/resources?"; if (data.service != null) url = url.concat("&service=" + data.service); if (data.identifier != null) url = url.concat("&identifier=" + data.identifier); if (data.default != null) url = url.concat("&default=" + data.default); - if (data.nameListFilter != null) url = url.concat("&nameListFilter=" + data.nameListFilter); - if (data.includeStatus != null) url = url.concat("&includeStatus=" + new Boolean(data.includeStatus).toString()); - if (data.includeMetadata != null) url = url.concat("&includeMetadata=" + new Boolean(data.includeMetadata).toString()); + if (data.nameListFilter != null) url = url.concat("&namefilter=" + data.nameListFilter); + if (data.includeStatus != null) url = url.concat("&includestatus=" + new Boolean(data.includeStatus).toString()); + if (data.includeMetadata != null) url = url.concat("&includemetadata=" + new Boolean(data.includeMetadata).toString()); if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); if (data.reverse != null) url = url.concat("&reverse=" + new Boolean(data.reverse).toString()); @@ -86,32 +86,29 @@ window.addEventListener("message", (event) => { break; case "FETCH_QDN_RESOURCE": - url = "/apps/resource?"; - if (data.service != null) url = url.concat("&service=" + data.service); - if (data.name != null) url = url.concat("&name=" + data.name); - if (data.identifier != null) url = url.concat("&identifier=" + data.identifier); + url = "/arbitrary/" + data.service + "/" + data.name; + if (data.identifier != null) url = url.concat("/" + data.identifier); + url = url.concat("?"); if (data.filepath != null) url = url.concat("&filepath=" + data.filepath); if (data.rebuild != null) url = url.concat("&rebuild=" + new Boolean(data.rebuild).toString()) response = httpGet(url); break; case "GET_QDN_RESOURCE_STATUS": - url = "/apps/resourcestatus?"; - if (data.service != null) url = url.concat("&service=" + data.service); - if (data.name != null) url = url.concat("&name=" + data.name); - if (data.identifier != null) url = url.concat("&identifier=" + data.identifier); + url = "/arbitrary/resource/status/" + data.service + "/" + data.name; + if (data.identifier != null) url = url.concat("/" + data.identifier); response = httpGet(url); break; case "SEARCH_CHAT_MESSAGES": - url = "/apps/chatmessages?"; + url = "/chat/messages?"; if (data.before != null) url = url.concat("&before=" + data.before); if (data.after != null) url = url.concat("&after=" + data.after); if (data.txGroupId != null) url = url.concat("&txGroupId=" + data.txGroupId); if (data.involving != null) data.involving.forEach((x, i) => url = url.concat("&involving=" + x)); if (data.reference != null) url = url.concat("&reference=" + data.reference); - if (data.chatReference != null) url = url.concat("&chatReference=" + data.chatReference); - if (data.hasChatReference != null) url = url.concat("&hasChatReference=" + new Boolean(data.hasChatReference).toString()); + if (data.chatReference != null) url = url.concat("&chatreference=" + data.chatReference); + if (data.hasChatReference != null) url = url.concat("&haschatreference=" + new Boolean(data.hasChatReference).toString()); if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); if (data.reverse != null) url = url.concat("&reverse=" + new Boolean(data.reverse).toString()); @@ -119,7 +116,7 @@ window.addEventListener("message", (event) => { break; case "LIST_GROUPS": - url = "/apps/groups?"; + url = "/groups?"; if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); if (data.reverse != null) url = url.concat("&reverse=" + new Boolean(data.reverse).toString()); @@ -127,27 +124,23 @@ window.addEventListener("message", (event) => { break; case "GET_BALANCE": - url = "/apps/balance?"; + url = "/addresses/balance/" + data.address; if (data.assetId != null) url = url.concat("&assetId=" + data.assetId); - if (data.address != null) url = url.concat("&address=" + data.address); response = httpGet(url); break; case "GET_AT": - url = "/apps/at?"; - if (data.atAddress != null) url = url.concat("&atAddress=" + data.atAddress); + url = "/at" + data.atAddress; response = httpGet(url); break; case "GET_AT_DATA": - url = "/apps/atdata?"; - if (data.atAddress != null) url = url.concat("&atAddress=" + data.atAddress); + url = "/at/" + data.atAddress + "/data"; response = httpGet(url); break; case "LIST_ATS": - url = "/apps/ats?"; - if (data.codeHash58 != null) url = url.concat("&codeHash58=" + data.codeHash58); + url = "/at/byfunction/" + data.codeHash58 + "?"; if (data.isExecutable != null) url = url.concat("&isExecutable=" + data.isExecutable); if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); @@ -157,20 +150,18 @@ window.addEventListener("message", (event) => { case "FETCH_BLOCK": if (data.signature != null) { - url = "/apps/block?"; - url = url.concat("&signature=" + data.signature); + url = "/blocks/" + data.signature; } else if (data.height != null) { - url = "/apps/block/byheight?"; - url = url.concat("&height=" + data.height); + url = "/blocks/byheight/" + data.height; } + url = url.concat("?"); if (data.includeOnlineSignatures != null) url = url.concat("&includeOnlineSignatures=" + data.includeOnlineSignatures); response = httpGet(url); break; case "FETCH_BLOCK_RANGE": - url = "/apps/block/range?"; - if (data.height != null) url = url.concat("&height=" + data.height); + url = "/blocks/range/" + data.height + "?"; if (data.count != null) url = url.concat("&count=" + data.count); if (data.reverse != null) url = url.concat("&reverse=" + data.reverse); if (data.includeOnlineSignatures != null) url = url.concat("&includeOnlineSignatures=" + data.includeOnlineSignatures); @@ -178,11 +169,12 @@ window.addEventListener("message", (event) => { break; case "SEARCH_TRANSACTIONS": - url = "/apps/transactions/search?"; + url = "/transactions/search?"; if (data.startBlock != null) url = url.concat("&startBlock=" + data.startBlock); if (data.blockLimit != null) url = url.concat("&blockLimit=" + data.blockLimit); if (data.txGroupId != null) url = url.concat("&txGroupId=" + data.txGroupId); if (data.txType != null) data.txType.forEach((x, i) => url = url.concat("&txType=" + x)); + if (data.address != null) url = url.concat("&address=" + data.address); if (data.confirmationStatus != null) url = url.concat("&confirmationStatus=" + data.confirmationStatus); if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); @@ -191,8 +183,7 @@ window.addEventListener("message", (event) => { break; case "GET_PRICE": - url = "/apps/price?"; - if (data.blockchain != null) url = url.concat("&blockchain=" + data.blockchain); + url = "/crosschain/price/" + data.blockchain + "?"; if (data.maxtrades != null) url = url.concat("&maxtrades=" + data.maxtrades); if (data.inverse != null) url = url.concat("&inverse=" + data.inverse); response = httpGet(url); diff --git a/src/test/java/org/qortal/test/api/AdminApiTests.java b/src/test/java/org/qortal/test/api/AdminApiTests.java index b3e6da03..01f2ebc9 100644 --- a/src/test/java/org/qortal/test/api/AdminApiTests.java +++ b/src/test/java/org/qortal/test/api/AdminApiTests.java @@ -5,7 +5,7 @@ import static org.junit.Assert.*; import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Before; import org.junit.Test; -import org.qortal.api.resource.AdminResource; +import org.qortal.api.restricted.resource.AdminResource; import org.qortal.repository.DataException; import org.qortal.settings.Settings; import org.qortal.test.common.ApiCommon;