Advertisement
chrisrico

Instawallet Client

Oct 2nd, 2011
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.84 KB | None | 0 0
  1. import org.codehaus.jackson.annotate.JsonAutoDetect;
  2. import org.codehaus.jackson.annotate.JsonSetter;
  3. import org.codehaus.jackson.map.ObjectMapper;
  4.  
  5. import java.io.*;
  6. import java.net.HttpURLConnection;
  7. import java.net.URL;
  8. import java.net.URLEncoder;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. import java.util.Random;
  12.  
  13. public class InstawalletClient {
  14.  
  15.     public InstawalletClient() {
  16.         System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
  17.         java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
  18.     }
  19.  
  20.     public InstawalletProto.Instawallet buildWallet() throws IOException {
  21.         String wallet_id = getNewWallet();
  22.         return buildWallet(wallet_id);
  23.     }
  24.  
  25.     public InstawalletProto.Instawallet buildWallet(String wallet_id) throws IOException {
  26.         String address = getAddress(wallet_id);
  27.         long balance = getBalance(wallet_id);
  28.         return InstawalletProto.Instawallet.newBuilder()
  29.                 .setId(wallet_id)
  30.                 .setAddress(address)
  31.                 .setBalance(balance)
  32.                 .setStatus(balance == 0 ? InstawalletProto.Instawallet.Status.NEW : InstawalletProto.Instawallet.Status.FILLED)
  33.                 .setTimestamp(System.currentTimeMillis())
  34.                 .build();
  35.     }
  36.  
  37.     public String getNewWallet() throws IOException {
  38.         InstawalletRequest<NewWalletResponse> request = new InstawalletRequest<NewWalletResponse>(null, "new_wallet");
  39.         request.setRequestMethod("POST");
  40.  
  41.         return request.getResponseObject(NewWalletResponse.class).wallet_id;
  42.     }
  43.  
  44.     public String getAddress(String wallet_id) throws IOException {
  45.         InstawalletRequest<AddressResponse> request = new InstawalletRequest<AddressResponse>(wallet_id, "address");
  46.         request.setRequestMethod("GET");
  47.  
  48.         return request.getResponseObject(AddressResponse.class).getAddress();
  49.     }
  50.  
  51.     public long getBalance(String wallet_id) throws IOException {
  52.         InstawalletRequest<BalanceResponse> request = new InstawalletRequest<BalanceResponse>(wallet_id, "balance");
  53.         request.setRequestMethod("GET");
  54.  
  55.         return request.getResponseObject(BalanceResponse.class).getBalance();
  56.     }
  57.  
  58.     public long sendPayment(String wallet_id, String address, double amount) throws IOException {
  59.         return sendPayment(wallet_id, address, Math.round(amount * Math.pow(10, 8)));
  60.     }
  61.  
  62.     public long sendPayment(String wallet_id, String address, long amount) throws IOException {
  63.         InstawalletRequest<PaymentResponse> request = new InstawalletRequest<PaymentResponse>(wallet_id, "payment");
  64.         request.setRequestMethod("POST");
  65.         request.addArgument("amount", Long.toString(amount));
  66.         request.addArgument("address", address);
  67.  
  68.         return request.getResponseObject(PaymentResponse.class).getMessage_code() == 0 ? amount : 0;
  69.     }
  70.  
  71.     public byte[] getAddressQrCode(String wallet_id) throws IOException {
  72.         InstawalletRequest request = new InstawalletRequest(wallet_id, "qrcode:address");
  73.         request.setRequestMethod("GET");
  74.         return request.getResponseBytes();
  75.     }
  76.  
  77.     public byte[] getUrlQrCode(String wallet_id) throws IOException {
  78.         InstawalletRequest request = new InstawalletRequest(wallet_id, "qrcode:link");
  79.         request.setRequestMethod("GET");
  80.         return request.getResponseBytes();
  81.     }
  82.  
  83.     class InstawalletRequest<T extends InstwalletResponse> {
  84.         Random random = new Random(System.currentTimeMillis());
  85.         int backoff = 250;
  86.         int ceiling = 5000;
  87.         HttpURLConnection connection;
  88.         URL url;
  89.         String requestMethod;
  90.         Map<String, String> arguments = new HashMap<String, String>();
  91.  
  92.         InstawalletRequest(String wallet_id, String call) throws IOException {
  93.             String path;
  94.             if (call.equals("new_wallet")) {
  95.                 path = "https://www.instawallet.org/api/v1/new_wallet";
  96.             } else if (call.contains("qrcode:")) {
  97.                 path = String.format("https://www.instawallet.org/qrcode/%s/%s.png", call.replace("qrcode:", ""), wallet_id);
  98.             } else {
  99.                 path = String.format("https://www.instawallet.org/api/v1/w/%s/%s", wallet_id, call);
  100.             }
  101.             //path = path.replace("https://www.instawallet.org", "http://127.0.0.1:8080");
  102.             url = new URL(path);
  103.         }
  104.  
  105.         void setRequestMethod(String requestMethod) {
  106.             this.requestMethod = requestMethod;
  107.         }
  108.  
  109.         void addArgument(String key, String value) {
  110.             arguments.put(key, value);
  111.         }
  112.  
  113.         HttpURLConnection getConnection() throws IOException {
  114.             while (connection == null) {
  115.                 try {
  116.                     connection = (HttpURLConnection) url.openConnection();
  117.                 } catch (IOException e) {
  118.                     e.printStackTrace();
  119.                     backoff();
  120.                 }
  121.             }
  122.  
  123.             connection.setDoInput(true);
  124.             connection.setDoOutput(true);
  125.  
  126.             connection.setRequestMethod(requestMethod);
  127.  
  128.             OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
  129.             writer.write(getData());
  130.             writer.flush();
  131.             writer.close();
  132.  
  133.             return connection;
  134.         }
  135.  
  136.         String getData() throws UnsupportedEncodingException {
  137.             StringBuilder builder = new StringBuilder();
  138.             for(Map.Entry<String, String> argument : arguments.entrySet()) {
  139.                 if (builder.length() > 0) {
  140.                     builder.append("&");
  141.                 }
  142.  
  143.                 builder.append(String.format("%s=%s", URLEncoder.encode(argument.getKey(), "utf-8"), URLEncoder.encode(argument.getValue(), "utf-8")));
  144.             }
  145.             return builder.toString();
  146.         }
  147.  
  148.         InputStream getResponseStream() {
  149.             InputStream stream = null;
  150.             while (stream == null) {
  151.                 try {
  152.                     stream = getConnection().getInputStream();
  153.                 } catch (IOException e) {
  154.                     connection = null;
  155.                     e.printStackTrace();
  156.                     backoff();
  157.                 }
  158.             }
  159.             return stream;
  160.         }
  161.  
  162.         byte[] getResponseBytes() throws IOException {
  163.             InputStream inputStream = getResponseStream();
  164.             int len;
  165.             int size = 1024;
  166.             byte[] buffer;
  167.             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  168.             buffer = new byte[size];
  169.             while ((len = inputStream.read(buffer, 0, size)) != -1) {
  170.                 outputStream.write(buffer, 0, len);
  171.             }
  172.             return outputStream.toByteArray();
  173.         }
  174.  
  175.         T getResponseObject(Class<T> targetClass) throws IOException {
  176.             ObjectMapper mapper = new ObjectMapper();
  177.             mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
  178.  
  179.             T response = mapper.readValue(getResponseStream(), targetClass);
  180.             if (response.isSuccessful()) {
  181.                 return response;
  182.             } else {
  183.                 throw new InstawalletAPIException(response);
  184.             }
  185.         }
  186.  
  187.         private void backoff() {
  188.             try {
  189.                 Thread.sleep(random.nextInt(backoff));
  190.             } catch (InterruptedException ignore) {
  191.             }
  192.             if (backoff < ceiling) {
  193.                 backoff *= 2;
  194.             } else {
  195.                 backoff = ceiling;
  196.             }
  197.         }
  198.     }
  199.  
  200.     // inner classes for json response objects
  201.     static class InstwalletResponse {
  202.         private boolean successful;
  203.  
  204.         public boolean isSuccessful() {
  205.             return successful;
  206.         }
  207.  
  208.         @JsonSetter
  209.         public void setSuccessful(boolean successful) {
  210.             this.successful = successful;
  211.         }
  212.  
  213.         @Override
  214.         public String toString() {
  215.             return successful ? "successful" : "unsuccessful";
  216.         }
  217.     }
  218.  
  219.     static class NewWalletResponse extends InstwalletResponse {
  220.         private String wallet_id;
  221.  
  222.         public String getWallet_id() {
  223.             return wallet_id;
  224.         }
  225.  
  226.         @JsonSetter
  227.         public void setWallet_id(String wallet_id) {
  228.             this.wallet_id = wallet_id;
  229.         }
  230.  
  231.         @Override
  232.         public String toString() {
  233.             return String.format("%s (%s)", super.toString(), wallet_id);
  234.         }
  235.     }
  236.  
  237.     static class AddressResponse extends InstwalletResponse {
  238.         private String address;
  239.  
  240.         public String getAddress() {
  241.             return address;
  242.         }
  243.  
  244.         @JsonSetter
  245.         public void setAddress(String address) {
  246.             this.address = address;
  247.         }
  248.  
  249.         @Override
  250.         public String toString() {
  251.             return String.format("%s (%s)", super.toString(), address);
  252.         }
  253.     }
  254.  
  255.     static class BalanceResponse extends InstwalletResponse {
  256.         private long balance;
  257.  
  258.         public long getBalance() {
  259.             return balance;
  260.         }
  261.  
  262.         @JsonSetter
  263.         public void setBalance(long balance) {
  264.             this.balance = balance;
  265.         }
  266.  
  267.         @Override
  268.         public String toString() {
  269.             return String.format("%s (%s)", super.toString(), balance);
  270.         }
  271.     }
  272.  
  273.     static class PaymentResponse extends InstwalletResponse {
  274.         private String message;
  275.         private int message_code;
  276.  
  277.         public String getMessage() {
  278.             return message;
  279.         }
  280.  
  281.         @JsonSetter
  282.         public void setMessage(String message) {
  283.             this.message = message;
  284.         }
  285.  
  286.         public int getMessage_code() {
  287.             return message_code;
  288.         }
  289.  
  290.         @JsonSetter
  291.         public void setMessage_code(int message_code) {
  292.             this.message_code = message_code;
  293.         }
  294.  
  295.         @Override
  296.         public String toString() {
  297.             return String.format("%s (%d:%s)", super.toString(), message_code, message);
  298.         }
  299.     }
  300.  
  301.     private class InstawalletAPIException extends IOException {
  302.         private final InstwalletResponse response;
  303.  
  304.         public InstawalletAPIException(InstwalletResponse response) {
  305.             this.response = response;
  306.         }
  307.  
  308.         @Override
  309.         public String getMessage() {
  310.             return response.toString();
  311.         }
  312.  
  313.         @Override
  314.         public String toString() {
  315.             StringBuilder builder = new StringBuilder();
  316.             builder.append(String.format("Response type: %s\n", response.getClass().getName()));
  317.             builder.append(String.format("Response message: %s", response.toString()));
  318.             return builder.toString();
  319.         }
  320.     }
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement