Skip to content

Commit

Permalink
Horizon v1.0.0 Compatibility (#265)
Browse files Browse the repository at this point in the history
* feat: add support for `/offers` end-point with query parameters.

* feat: add support for `/accounts` end-point with ?signer and ?asset filters.

* feat: extend offer call builder to return a single offer.

* test: add more tests for account and offer endpoint.
  • Loading branch information
overcat authored Feb 24, 2020
1 parent b7ea488 commit e461cd5
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 17 deletions.
34 changes: 34 additions & 0 deletions src/main/java/org/stellar/sdk/requests/AccountsRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.stellar.sdk.AssetTypeCreditAlphaNum;
import org.stellar.sdk.responses.AccountResponse;
import org.stellar.sdk.responses.Page;

Expand All @@ -14,6 +15,9 @@
* Builds requests connected to accounts.
*/
public class AccountsRequestBuilder extends RequestBuilder {
private static final String ASSET_PARAMETER_NAME = "asset";
private static final String SIGNER_PARAMETER_NAME = "signer";

public AccountsRequestBuilder(OkHttpClient httpClient, HttpUrl serverURI) {
super(httpClient, serverURI, "accounts");
}
Expand Down Expand Up @@ -44,6 +48,36 @@ public AccountResponse account(String account) throws IOException {
return this.account(this.buildUri());
}

/**
* Returns all accounts that contain a specific signer.
*
* @param signer Account ID
* @return current {@link AccountsRequestBuilder} instance
* @see <a href="https://www.stellar.org/developers/horizon/reference/endpoints/accounts.html">Accounts</a>
*/
public AccountsRequestBuilder forSigner(String signer) {
if (uriBuilder.build().queryParameter(ASSET_PARAMETER_NAME) != null) {
throw new RuntimeException("cannot set both signer and asset");
}
uriBuilder.setQueryParameter(SIGNER_PARAMETER_NAME, signer);
return this;
}

/**
* Returns all accounts who are trustees to a specific asset.
*
* @param asset An issued asset
* @return current {@link AccountsRequestBuilder} instance
* @see <a href="https://www.stellar.org/developers/horizon/reference/endpoints/accounts.html">Accounts</a>
*/
public AccountsRequestBuilder forAsset(AssetTypeCreditAlphaNum asset) {
if (uriBuilder.build().queryParameter(SIGNER_PARAMETER_NAME) != null) {
throw new RuntimeException("cannot set both signer and asset");
}
setAssetParameter(ASSET_PARAMETER_NAME, asset);
return this;
}

/**
* Requests specific <code>uri</code> and returns {@link Page} of {@link AccountResponse}.
* This method is helpful for getting the next set of results.
Expand Down
70 changes: 67 additions & 3 deletions src/main/java/org/stellar/sdk/requests/OffersRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.stellar.sdk.Asset;
import org.stellar.sdk.responses.OfferResponse;
import org.stellar.sdk.responses.Page;

Expand All @@ -21,16 +22,80 @@ public OffersRequestBuilder(OkHttpClient httpClient, HttpUrl serverURI) {
}

/**
* Builds request to <code>GET /accounts/{account}/offers</code>
* @see <a href="https://www.stellar.org/developers/horizon/reference/offers-for-account.html">Offers for Account</a>
* Requests specific <code>uri</code> and returns {@link OfferResponse}.
* This method is helpful for getting the links.
* @throws IOException
*/
public OfferResponse offer(HttpUrl uri) throws IOException {
TypeToken type = new TypeToken<OfferResponse>() {};
ResponseHandler<OfferResponse> responseHandler = new ResponseHandler<OfferResponse>(type);

Request request = new Request.Builder().get().url(uri).build();
Response response = httpClient.newCall(request).execute();

return responseHandler.handleResponse(response);
}

/**
* The offer details endpoint provides information on a single offer.
* @param offerId specifies which offer to load.
* @return The offer details.
* @throws IOException
*/
public OfferResponse offer(long offerId) throws IOException {
this.setSegments("offers", String.valueOf(offerId));
return this.offer(this.buildUri());
}

/**
* @param account Account for which to get offers
* @see <a href="https://www.stellar.org/developers/horizon/reference/offers-for-account.html">Offers for Account</a>
* @deprecated Use {@link OffersRequestBuilder#forSeller}
* Builds request to <code>GET /accounts/{account}/offers</code>
*/
@Deprecated
public OffersRequestBuilder forAccount(String account) {
account = checkNotNull(account, "account cannot be null");
this.setSegments("accounts", account, "offers");
return this;
}

/**
* Returns all offers where the given account is the seller.
*
* @param seller Account ID of the offer creator.
* @return current {@link OffersRequestBuilder} instance
* @see <a href="https://www.stellar.org/developers/horizon/reference/endpoints/offers.html">Offers</a>
*/
public OffersRequestBuilder forSeller(String seller) {
uriBuilder.setQueryParameter("seller", seller);
return this;
}

/**
* Returns all offers buying an asset.
*
* @param asset The Asset being bought.
* @return current {@link OffersRequestBuilder} instance
* @see <a href="https://www.stellar.org/developers/horizon/reference/endpoints/offers.html">Offers</a>
*/
public OffersRequestBuilder forBuyingAsset(Asset asset) {
setAssetParameter("buying", asset);
return this;
}

/**
* Returns all offers selling an asset.
*
* @param asset The Asset being sold.
* @return current {@link OffersRequestBuilder} instance
* @see <a href="https://www.stellar.org/developers/horizon/reference/endpoints/offers.html">Offers</a>
*/
public OffersRequestBuilder forSellingAsset(Asset asset) {
setAssetParameter("selling", asset);
return this;
}

/**
* Requests specific <code>uri</code> and returns {@link Page} of {@link OfferResponse}.
* This method is helpful for getting the next set of results.
Expand All @@ -48,7 +113,6 @@ public static Page<OfferResponse> execute(OkHttpClient httpClient, HttpUrl uri)
return responseHandler.handleResponse(response);
}


/**
* Allows to stream SSE events from horizon.
* Certain endpoints in Horizon can be called in streaming mode using Server-Sent Events.
Expand Down
34 changes: 25 additions & 9 deletions src/main/java/org/stellar/sdk/requests/RequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,41 @@ public RequestBuilder order(Order direction) {

/**
* Sets a parameter consisting of a comma separated list of assets on the request.
* @param name the name of the query parameter
*
* @param name the name of the query parameter
* @param assets the list of assets to be serialized into the query parameter value
*/
public RequestBuilder setAssetsParameter(String name, List<Asset> assets) {
List<String> assetStrings = Lists.newArrayList();
for (Asset asset : assets) {
if (asset instanceof AssetTypeNative) {
assetStrings.add("native");
} else if (asset instanceof AssetTypeCreditAlphaNum) {
AssetTypeCreditAlphaNum creditAsset = (AssetTypeCreditAlphaNum) asset;
assetStrings.add(creditAsset.getCode()+":"+creditAsset.getIssuer());
} else {
throw new RuntimeException("unsupported asset "+ asset.getType());
}
assetStrings.add(encodeAsset(asset));
}
uriBuilder.setQueryParameter(name, Joiner.on(",").join(assetStrings));
return this;
}

/**
* Sets a parameter consisting of an asset represented as "assetCode:assetIssue" on the request.
*
* @param name the name of the query parameter
* @param asset the asset to be serialized into the query parameter value
*/
public RequestBuilder setAssetParameter(String name, Asset asset) {
uriBuilder.setQueryParameter(name, encodeAsset(asset));
return this;
}

private String encodeAsset(Asset asset) {
if (asset instanceof AssetTypeNative) {
return "native";
} else if (asset instanceof AssetTypeCreditAlphaNum) {
AssetTypeCreditAlphaNum creditAsset = (AssetTypeCreditAlphaNum) asset;
return creditAsset.getCode() + ":" + creditAsset.getIssuer();
} else {
throw new RuntimeException("unsupported asset " + asset.getType());
}
}

HttpUrl buildUri() {
if (segments.size() > 0) {
for (String segment : segments) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import okhttp3.HttpUrl;
import org.junit.Test;
import org.stellar.sdk.Network;
import org.stellar.sdk.Server;
import org.stellar.sdk.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class AccountsRequestBuilderTest {
@Test
Expand All @@ -18,4 +18,48 @@ public void testAccounts() {
.buildUri();
assertEquals("https://horizon-testnet.stellar.org/accounts?cursor=13537736921089&limit=200&order=asc", uri.toString());
}

@Test
public void testForSigner() {
Server server = new Server("https://horizon-testnet.stellar.org");
HttpUrl uri = server.accounts()
.forSigner("GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN")
.buildUri();
assertEquals("https://horizon-testnet.stellar.org/accounts?signer=GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN", uri.toString());
}

@Test
public void testForCreditAlphanum4Asset() {
Server server = new Server("https://horizon-testnet.stellar.org");
AssetTypeCreditAlphaNum asset = new AssetTypeCreditAlphaNum4("USD", "GDVDKQFP665JAO7A2LSHNLQIUNYNAAIGJ6FYJVMG4DT3YJQQJSRBLQDG");
HttpUrl uri = server.accounts()
.forAsset(asset)
.buildUri();
assertEquals("https://horizon-testnet.stellar.org/accounts?asset=USD%3AGDVDKQFP665JAO7A2LSHNLQIUNYNAAIGJ6FYJVMG4DT3YJQQJSRBLQDG", uri.toString());
}

@Test
public void testForCreditAlphanum12Asset() {
Server server = new Server("https://horizon-testnet.stellar.org");
AssetTypeCreditAlphaNum asset = new AssetTypeCreditAlphaNum12("STELLAR", "GDVDKQFP665JAO7A2LSHNLQIUNYNAAIGJ6FYJVMG4DT3YJQQJSRBLQDG");
HttpUrl uri = server.accounts()
.forAsset(asset)
.buildUri();
assertEquals("https://horizon-testnet.stellar.org/accounts?asset=STELLAR%3AGDVDKQFP665JAO7A2LSHNLQIUNYNAAIGJ6FYJVMG4DT3YJQQJSRBLQDG", uri.toString());
}

@Test
public void testForSignerAndAssetInvalid() {
Server server = new Server("https://horizon-testnet.stellar.org");
AssetTypeCreditAlphaNum asset = new AssetTypeCreditAlphaNum4("USD", "GDVDKQFP665JAO7A2LSHNLQIUNYNAAIGJ6FYJVMG4DT3YJQQJSRBLQDG");
try {
server.accounts()
.forSigner("GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN")
.forAsset(asset)
.buildUri();
fail();
} catch (RuntimeException e) {
assertEquals("cannot set both signer and asset", e.getMessage());
}
}
}
Loading

0 comments on commit e461cd5

Please sign in to comment.