package org.ripple.power.txns;
import java.text.DecimalFormat;
import java.util.List;
import org.json.JSONObject;
import org.ripple.power.RippleSeedAddress;
import org.ripple.power.config.LSystem;
import org.ripple.power.txns.data.AccountInfoResponse;
import org.ripple.power.txns.data.AccountLinesResponse;
import org.ripple.power.txns.data.CancelOrderResponse;
import org.ripple.power.txns.data.CandlesResponse;
import org.ripple.power.txns.data.Line;
import org.ripple.power.txns.data.Market;
import org.ripple.power.txns.data.MarketDepthAsksResponse;
import org.ripple.power.txns.data.MarketDepthBidsResponse;
import org.ripple.power.txns.data.NewOrderResponse;
import org.ripple.power.txns.data.Offer;
import org.ripple.power.txns.data.OfferListener;
import org.ripple.power.txns.data.OffersResponse;
import org.ripple.power.txns.data.RippleResult;
import org.ripple.power.txns.data.RippleResultListener;
import org.ripple.power.txns.data.Take;
import org.ripple.power.ui.RPClient;
import com.ripple.client.enums.Command;
import com.ripple.client.requests.Request;
import com.ripple.client.responses.Response;
//select rippled api or ripple rest api
public class RippleBackendsAPI {
private final static DecimalFormat xrp_num_format = new DecimalFormat(
"0.00000");
public static enum Model {
RippleRestAPI, Rippled
}
public Model model = Model.Rippled;
private boolean _testing = false;
private RippleSeedAddress _seed;
public RippleBackendsAPI(RippleSeedAddress seed) {
this(seed, false);
}
public RippleBackendsAPI(RippleSeedAddress seed, boolean test) {
this._seed = seed;
this._testing = test;
}
public RippleBackendsAPI() {
}
public AccountInfoResponse getAccountInfo(final String address,
final Updateable update) {
if (!AccountFind.isRippleAddress(address)) {
throw new RuntimeException("not ripple address !");
}
final AccountInfoResponse accountInfo = new AccountInfoResponse();
// rippled
switch (model) {
case Rippled:
RPClient client = RPClient.ripple();
if (client != null) {
Request req = client.newRequest(Command.account_info);
req.json("account", address);
req.once(Request.OnSuccess.class, new Request.OnSuccess() {
@Override
public void called(Response response) {
JSONObject result = response.message;
if (result != null) {
accountInfo.from(result);
}
if (update != null) {
update.action(accountInfo);
}
}
});
req.once(Request.OnError.class, new Request.OnError() {
@Override
public void called(Response response) {
if (update != null) {
update.action(response.error_message);
}
}
});
req.request();
}
break;
default:
break;
}
return accountInfo;
}
public AccountLinesResponse getAccountLines(final String address,
final Updateable update) {
if (!AccountFind.isRippleAddress(address)) {
throw new RuntimeException("not ripple address !");
}
final AccountLinesResponse accountLines = new AccountLinesResponse();
// rippled
switch (model) {
case Rippled:
RPClient client = RPClient.ripple();
if (client != null) {
Request req = client.newRequest(Command.account_lines);
req.json("account", address);
req.json("ledger", "current");
req.once(Request.OnSuccess.class, new Request.OnSuccess() {
@Override
public void called(Response response) {
JSONObject result = response.message;
if (result != null) {
accountLines.from(result);
}
if (update != null) {
update.action(accountLines);
}
}
});
req.once(Request.OnError.class, new Request.OnError() {
@Override
public void called(Response response) {
if (update != null) {
update.action(response.error_message);
}
}
});
req.request();
}
break;
default:
break;
}
return null;
}
public OffersResponse getActiveOrders(final String address,
final Updateable update) {
if (!AccountFind.isRippleAddress(address)) {
throw new RuntimeException("not ripple address !");
}
final OffersResponse offers = new OffersResponse();
// rippled
switch (model) {
case Rippled:
RPClient client = RPClient.ripple();
if (client != null) {
Request req = client.newRequest(Command.account_offers);
req.json("account", address);
req.once(Request.OnSuccess.class, new Request.OnSuccess() {
@Override
public void called(Response response) {
JSONObject result = response.message;
if (result != null) {
offers.from(result);
}
if (update != null) {
update.action(offers);
}
}
});
req.once(Request.OnError.class, new Request.OnError() {
@Override
public void called(Response response) {
if (update != null) {
update.action(response.error_message);
}
}
});
req.request();
}
break;
default:
break;
}
return null;
}
public double getSynXrpBalance() {
if (_seed != null) {
return getSynXrpBalance(_seed.getPublicKey());
}
return -1;
}
public double getSynXrpBalance(final String address) {
RippleResult result = getXrpBalance(address, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof Double) {
return (double) result.data;
}
}
return -1;
}
public RippleResult getXrpBalance(final String address,
final RippleResultListener listener) {
final RippleResult result = new RippleResult();
getAccountInfo(address, new Updateable() {
@Override
public void action(Object o) {
if (o instanceof AccountInfoResponse) {
AccountInfoResponse account = (AccountInfoResponse) o;
if (account.result == null
|| account.result.account_data == null) {
result.data = -1.0;
result.success = false;
} else {
result.data = account.result.account_data
.getBalanceXrp();
result.success = true;
}
} else {
result.data = -1.0;
result.success = false;
}
if (listener != null) {
listener.update(result);
}
}
});
return result;
}
public double getSynBalance(Take dst) {
return getSynBalance(dst.issuer, dst.currency);
}
public double getSynBalance(final String issuerAddress,
final String currency) {
if (_seed != null) {
return getSynBalance(_seed.getPublicKey(), issuerAddress, currency);
}
return -1;
}
public double getSynBalance(final String address,
final String issuerAddress, final String currency) {
RippleResult result = getBalance(address, issuerAddress, currency, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof Double) {
return (double) result.data;
}
}
return -1;
}
public RippleResult getBalance(final String address,
final RippleResultListener listener) {
return getBalance(address, null, null, listener);
}
public RippleResult getBalance(final String address,
final String issuerAddress, final String currency,
final RippleResultListener listener) {
final RippleResult result = new RippleResult();
getAccountLines(address, new Updateable() {
@Override
public void action(Object o) {
if (o instanceof AccountLinesResponse) {
AccountLinesResponse account = (AccountLinesResponse) o;
if (account.result == null || account.result.lines == null) {
result.data = -1.0;
result.success = false;
} else {
List<Line> theLines = account.result.lines;
if (theLines.size() > 0) {
for (Line line : theLines) {
if (issuerAddress != null && currency != null) {
if (line.account
.equalsIgnoreCase(issuerAddress)
&& line.currency
.equalsIgnoreCase(currency)) {
result.data = line.getBalance();
result.success = true;
break;
}
} else if (currency != null) {
if (line.currency
.equalsIgnoreCase(currency)) {
result.data = line.getBalance();
result.success = true;
break;
}
} else {
result.data = theLines;
result.success = true;
break;
}
}
}
if (!result.success) {
result.data = -1.0;
result.success = false;
}
}
} else {
result.data = -1.0;
result.success = false;
}
if (listener != null) {
listener.update(result);
}
}
});
return result;
}
public Offer getSynOrderInfo(final long orderId) {
if (_seed != null) {
return getSynOrderInfo(_seed.getPublicKey(), orderId);
}
return new Offer(true);
}
public Offer getSynOrderInfo(final String address, final long orderId) {
RippleResult result = getOrderInfo(address, orderId, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof Offer) {
return (Offer) result.data;
}
}
return new Offer(true);
}
public RippleResult getOrderInfo(final String address, final long orderId,
final RippleResultListener listener) {
final RippleResult result = new RippleResult();
getActiveOrders(address, new Updateable() {
@Override
public void action(Object o) {
if (o instanceof OffersResponse) {
OffersResponse account = (OffersResponse) o;
if (account.result == null || account.result.offers == null) {
result.data = -1.0;
result.success = false;
} else {
if (orderId < 0) {
result.data = account.result.offers;
result.success = true;
} else {
List<Offer> theOffers = account.result.offers;
if (theOffers.size() == 0) {
result.data = new Offer(true);
result.success = true;
return;
} else {
for (Offer offer : theOffers) {
if (offer.seq == orderId) {
result.data = offer;
result.success = true;
return;
}
}
}
result.data = -1.0;
result.success = false;
}
}
} else {
result.data = -1.0;
result.success = false;
}
if (listener != null) {
listener.update(result);
}
}
});
return result;
}
public MarketDepthBidsResponse getBids(String takerAddress,
final Take pays, final Take gets, final int limit,
final Updateable update) {
final MarketDepthBidsResponse bids = new MarketDepthBidsResponse();
RPClient client = RPClient.ripple();
if (client != null) {
Request req = client.newRequest(Command.book_offers);
if (takerAddress != null) {
req.json("taker", takerAddress);
}
req.json("taker_pays", pays.getJSON());
req.json("taker_gets", gets.getJSON());
if (limit > 0) {
req.json("limit", limit);
} else {
req.json("limit", 15);
}
req.once(Request.OnSuccess.class, new Request.OnSuccess() {
@Override
public void called(Response response) {
JSONObject result = response.message;
if (result != null) {
bids.from(result);
}
if (update != null) {
update.action(bids);
}
}
});
req.once(Request.OnError.class, new Request.OnError() {
@Override
public void called(Response response) {
if (update != null) {
update.action(response.error_message);
}
}
});
req.request();
}
return bids;
}
public MarketDepthAsksResponse getAsks(String takerAddress,
final Take pays, final Take gets, final int limit,
final Updateable update) {
final MarketDepthAsksResponse asks = new MarketDepthAsksResponse();
RPClient client = RPClient.ripple();
if (client != null) {
Request req = client.newRequest(Command.book_offers);
if (takerAddress != null) {
req.json("taker", takerAddress);
}
req.json("taker_pays", gets.getJSON());
req.json("taker_gets", pays.getJSON());
if (limit > 0) {
req.json("limit", limit);
} else {
req.json("limit", 15);
}
req.once(Request.OnSuccess.class, new Request.OnSuccess() {
@Override
public void called(Response response) {
JSONObject result = response.message;
if (result != null) {
asks.from(result);
}
if (update != null) {
update.action(asks);
}
}
});
req.once(Request.OnError.class, new Request.OnError() {
@Override
public void called(Response response) {
if (update != null) {
update.action(response.error_message);
}
}
});
req.request();
}
return asks;
}
public Market getSynXRPMarketDepth(String takerAddress, final Take gets,
final int limit) {
return getSynMarketDepth(takerAddress, RippleDefault.BASE,
gets, limit);
}
public Market getSynMarketDepth(String takerAddress, final Take pays,
final Take gets, final int limit) {
Market market = getMarketDepth(takerAddress, pays, gets, limit, null);
for (; market.count < 2;) {
}
return market;
}
public Market getMarketDepth(String takerAddress, final Take pays,
final Take gets, final int limit) {
return getMarketDepth(takerAddress, pays, gets, limit, null);
}
public Market getMarketDepth(String takerAddress, final Take pays,
final Take gets, final int limit, final OfferListener listener) {
final Market market = new Market();
// rippled
switch (model) {
case Rippled:
getBids(takerAddress, pays, gets, limit, new Updateable() {
@Override
public void action(Object o) {
if (o instanceof MarketDepthBidsResponse) {
market.Bids = ((MarketDepthBidsResponse) o).result.offers;
if (listener != null) {
listener.bids(market.Bids);
}
}
market.count++;
}
});
getAsks(takerAddress, pays, gets, limit, new Updateable() {
@Override
public void action(Object o) {
if (o instanceof MarketDepthAsksResponse) {
market.Asks = ((MarketDepthAsksResponse) o).result.offers;
if (listener != null) {
listener.asks(market.Asks);
}
}
market.count++;
}
});
default:
break;
}
return market;
}
public RippleResult placeOrder(final RippleSeedAddress seed,
IssuedCurrency pays, IssuedCurrency gets, long flags,
final RippleResultListener listener) {
final RippleResult result = new RippleResult();
if (_testing) {
NewOrderResponse newOrder = new NewOrderResponse();
result.data = newOrder;
result.success = true;
return result;
}
OfferCreate.set(seed, pays, gets, LSystem.getFee(), -1, 1.0001f, flags,
new Rollback() {
@Override
public void success(JSONObject res) {
NewOrderResponse newOrder = new NewOrderResponse();
newOrder.from(res);
result.data = newOrder;
result.success = true;
if (listener != null) {
listener.update(result);
}
}
@Override
public void error(JSONObject res) {
result.data = -1;
result.success = false;
if (listener != null) {
listener.update(result);
}
}
});
return result;
}
public long placeSynXRPBuyOrder(double price, double amount,
Take dst) {
return placeSynXRPBuyOrder(price, amount, dst.currency,
dst.issuer);
}
public long placeSynXRPBuyOrder(double price, double amount,
String curreny, String issuer) {
if (_seed != null) {
return placeSynXRPBuyOrder(_seed, price, amount, curreny, issuer);
}
return -1;
}
public long placeSynXRPBuyOrder(final RippleSeedAddress seed, double price,
double amount, String curreny, String issuer) {
RippleResult result = placeXRPBuyOrder(seed, price, amount, curreny,
issuer, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof NewOrderResponse) {
return ((NewOrderResponse) result.data).result.tx_json.Sequence;
}
}
return -1;
}
public long placeSynXRPSellOrder(double price, double amount,
Take dst) {
return placeSynXRPSellOrder(price, amount, dst.currency,
dst.issuer);
}
public long placeSynXRPSellOrder(double price, double amount,
String curreny, String issuer) {
if (_seed != null) {
return placeSynXRPSellOrder(_seed, price, amount, curreny, issuer);
}
return -1;
}
public long placeSynXRPSellOrder(final RippleSeedAddress seed,
double price, double amountXrp, String curreny, String issuer) {
RippleResult result = placeXRPSellOrder(seed, price, amountXrp,
curreny, issuer, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof NewOrderResponse) {
return ((NewOrderResponse) result.data).result.tx_json.Sequence;
}
}
return -1;
}
public RippleResult placeXRPBuyOrder(final RippleSeedAddress seed,
double price, double amount, String curreny, String issuer,
RippleResultListener listener) {
long amountXrpDrops = (long) Math.round(amount * Const.DROPS_IN_XRP);
double amountFiat = price * amount;
IssuedCurrency pays = new IssuedCurrency(String.valueOf(amountXrpDrops));
IssuedCurrency gets = new IssuedCurrency(String.valueOf(xrp_num_format
.format(amountFiat)), issuer, curreny);
return placeOrder(seed, pays, gets, 0, listener);
}
public RippleResult placeXRPSellOrder(final RippleSeedAddress seed,
double price, double amountXrp, String curreny, String issuer,
RippleResultListener listener) {
double amountFiat = price * amountXrp;
long amountXrpDrops = (long) Math.round(amountXrp * Const.DROPS_IN_XRP);
IssuedCurrency pays = new IssuedCurrency(String.valueOf(xrp_num_format
.format(amountFiat)), issuer, curreny);
IssuedCurrency gets = new IssuedCurrency(String.valueOf(amountXrpDrops));
// flags == 2147483648(sell)
return placeOrder(seed, pays, gets, 2147483648l, listener);
}
public long updateSynXRPSellOrder(long orderId, double price,
double amount, Take dst) {
if (_seed != null) {
return updateSynXRPSellOrder(_seed, orderId, price, amount, dst);
}
return -1;
}
public long updateSynXRPSellOrder(final RippleSeedAddress seed,
long orderId, double price, double amount, Take dst) {
return updateSynXRPSellOrder(orderId, price, amount, dst.currency,
dst.issuer);
}
public long updateSynXRPSellOrder(long orderId, double price,
double amount, String curreny, String issuer) {
if (_seed != null) {
return updateSynXRPSellOrder(_seed, orderId, price, amount,
curreny, issuer);
}
return -1;
}
public long updateSynXRPSellOrder(final RippleSeedAddress seed,
long orderId, double price, double amount, String curreny,
String issuer) {
if (cancelSynOrder(seed, orderId)) {
long id = placeSynXRPSellOrder(seed, price, amount, curreny, issuer);
if (id == -1) {
return orderId;
}
return id;
}
return orderId;
}
public long updateSynXRPBuyOrder(long orderId, double price, double amount,
Take dst) {
if (_seed != null) {
return updateSynXRPBuyOrder(_seed, orderId, price, amount, dst);
}
return -1;
}
public long updateSynXRPBuyOrder(final RippleSeedAddress seed,
long orderId, double price, double amount, Take dst) {
return updateSynXRPBuyOrder(orderId, price, amount, dst.currency,
dst.issuer.toString());
}
public long updateSynXRPBuyOrder(long orderId, double price, double amount,
String curreny, String issuer) {
if (_seed != null) {
return updateSynXRPSellOrder(_seed, orderId, price, amount,
curreny, issuer);
}
return -1;
}
public long updateSynXRPBuyOrder(final RippleSeedAddress seed,
long orderId, double price, double amount, String curreny,
String issuer) {
if (cancelSynOrder(orderId)) {
long id = placeSynXRPBuyOrder(seed, price, amount, curreny, issuer);
if (-1 == id) {
return orderId;
}
return id;
}
return orderId;
}
public boolean cancelSynOrder(long orderId) {
if (_seed != null) {
return cancelSynOrder(_seed, orderId);
}
return false;
}
public boolean cancelSynOrder(final RippleSeedAddress seed, long orderId) {
RippleResult result = cancelOrder(seed, orderId, null);
for (; result.data == null;) {
}
if (result.success) {
if (result.data instanceof CancelOrderResponse) {
return ((CancelOrderResponse) result.data).result.getResultOK();
}
}
return false;
}
public RippleResult cancelOrder(final RippleSeedAddress seed, long orderId,
final RippleResultListener listener) {
final RippleResult result = new RippleResult();
if (_testing) {
CancelOrderResponse cancelOrder = new CancelOrderResponse();
result.data = cancelOrder;
result.success = true;
return result;
}
OfferCancel.set(seed, orderId, LSystem.getFee(), new Rollback() {
@Override
public void success(JSONObject res) {
CancelOrderResponse cancelOrder = new CancelOrderResponse();
cancelOrder.from(res);
result.data = cancelOrder;
result.success = true;
if (listener != null) {
listener.update(result);
}
}
@Override
public void error(JSONObject res) {
result.data = -1;
result.success = false;
if (listener != null) {
listener.update(result);
}
}
});
return result;
}
public CandlesResponse getTradeStatistics(long time, String curreny,
String issuer) {
return RippleChartsAPI.getTradeStatistics(curreny, issuer, time);
}
public CandlesResponse getTradeStatistics(long time,
Take basecur, Take counter) {
return RippleChartsAPI.getTradeStatistics(basecur, counter, time);
}
public CandlesResponse getTradeStatistics(long time, Take counter) {
return RippleChartsAPI.getTradeStatistics(RippleDefault.BASE, counter,
time);
}
public boolean isTesting() {
return _testing;
}
public RippleSeedAddress getAccountSeed() {
return _seed;
}
}