package co.gem.round;
import co.gem.round.coinop.MultiWallet;
import co.gem.round.coinop.TransactionWrapper;
import co.gem.round.patchboard.Client;
import co.gem.round.patchboard.Resource;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* Transaction associated with an account. Contains hash, type, status and the bitcoin transaction json.
*
* @author Julian Vergel de Dios (julian@gem.co) on 12/18/14.
*/
public class Transaction extends Base {
public enum Status {
UNCONFIRMED("unconfirmed"),
CONFIRMED("confirmed"),
REJECTED("rejected"),
CANCELED("canceled"),
UNSIGNED("unsigned");
private String status;
Status (String status) {
this.status = status;
}
public String toString() {
return this.status;
}
}
public enum Type {
INCOMING("incoming"),
OUTGOING("outgoing"),
TRANSFER_IN("transfer_in"),
TRANSFER_OUT("transfer_out"),
CHANGE("change");
private String type;
Type (String type) {
this.type = type;
}
public String toString() {
return this.type;
}
}
public static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
public Transaction(Resource resource, Round round) {
super(resource, round);
}
/**
* Sign a Gem API unsigned payment to send back to Gem for rules verification, co-signing and publishing to the
* blockchain
* @param wallet coinop.MultiWallet
* @return Payment signed
* @throws IOException
* @throws Client.UnexpectedStatusCodeException
* @see co.gem.round.coinop.MultiWallet
*/
public Transaction sign(MultiWallet wallet)
throws IOException, Client.UnexpectedStatusCodeException {
List<String> signatures = wallet.signaturesFromUnparsedTransaction(resource.attributes());
JsonArray signaturesJson = new JsonArray();
for (String signature : signatures) {
JsonObject signatureJson = new JsonObject();
signatureJson.addProperty("primary", signature);
signaturesJson.add(signatureJson);
}
JsonObject transactionSignatures = new JsonObject();
transactionSignatures.addProperty("transaction_hash", resource.attributes().get("hash").getAsString());
transactionSignatures.add("inputs", signaturesJson);
JsonObject body = new JsonObject();
body.add("signatures", transactionSignatures);
Resource signedPayment = resource.action("update", body);
resource = signedPayment;
return this;
}
public String getMfaUri() {
JsonElement possible = getAttribute("mfa_uri");
if (possible != null && !possible.isJsonNull()) {
return possible.getAsString();
}
return null;
}
public void setRedirectUri(String redirectUri) {
resource.attributes().addProperty("redirect_uri", redirectUri);
}
public Transaction approve()
throws IOException, Client.UnexpectedStatusCodeException {
resource = this.resource().action("approve", new JsonObject());
return this;
}
/**
* Cancels an unsigned transaction
* @throws IOException
* @throws Client.UnexpectedStatusCodeException
*/
public void cancel()
throws IOException, Client.UnexpectedStatusCodeException {
this.resource.action("cancel");
}
/**
* Getter for the transaction type. "incoming" and "outgoing" are the two types of values to be returned
* @return String type either "incoming" or "outgoing"
*/
public String getType() {
return this.resource().attributes().get("type").getAsString();
}
/**
* Getter for the bitcoin transaction hash
* @return String bitcoin transaction hash
*/
public String getTransactionHash() {
return this.resource().attributes().get("hash").getAsString();
}
/**
* Getter for the value in the bitcoin transaction.
* @return Long value
*/
public long getValue() {
return this.resource().attributes().get("value").getAsLong();
}
/**
* Getter for the status of a bitcoin transaction. Will return confirmed, unconfirmed, canceled, unsigned
* @return String status: confirmed, unconfirmed, canceled, unsigned
*/
public String getStatus() {
return this.resource().attributes().get("status").getAsString();
}
/**
* Getter for the number of confirmations of a transaction
* @return int number of confirmations
*/
public int getConfirmations() {
return this.resource().attributes().get("confirmations").getAsInt();
}
/**
* Getter for the fee in the transaction. Value - Fee = amount sent
* @return
*/
public long getFee() {
return this.resource().attributes().get("fee").getAsLong();
}
/**
* Getter for the date created for a bitcoin transaction yyyy-MM-dd HH:mm:ss Z
* @return Date created at
*/
public Date getCreatedAt() {
String dateString = this.resource().attributes().get("created_at").getAsString();
Date createdAt = null;
try {
createdAt = DATE_FORMATTER.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return createdAt;
}
}