├── .gitattributes
├── .gitignore
├── README.md
├── nbactions-release-profile.xml
├── nbactions-sonatype-oss-release.xml
├── nbactions.xml
├── pom.xml
├── pom.xml.releaseBackup
└── src
├── main
├── java
│ └── com
│ │ └── nitinsurana
│ │ └── bitcoinlitecoin
│ │ └── rpcconnector
│ │ ├── APICalls.java
│ │ ├── CryptoCurrencyRPC.java
│ │ ├── JSONRequestBody.java
│ │ ├── events
│ │ ├── AlertListener.java
│ │ ├── BitcoinDListener.java
│ │ └── WalletListener.java
│ │ ├── exception
│ │ ├── AuthenticationException.java
│ │ ├── CallApiCryptoCurrencyRpcException.java
│ │ ├── CryptoCurrencyRpcException.java
│ │ ├── CryptoCurrencyRpcExceptionHandler.java
│ │ ├── InsufficientFundsException.java
│ │ └── RpcInvalidResponseException.java
│ │ └── pojo
│ │ └── Transaction.java
└── resources
│ └── log4j.properties
└── test
└── java
└── com
└── nitinsurana
└── litecoinrpcconnector
└── AppTest.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Intellij Idea
3 | #################
4 | *.iml
5 |
6 | #################
7 | ## Eclipse
8 | #################
9 |
10 | *.pydevproject
11 | .project
12 | .metadata
13 | bin/
14 | tmp/
15 | *.tmp
16 | *.bak
17 | *.swp
18 | *~.nib
19 | local.properties
20 | .classpath
21 | .settings/
22 | .loadpath
23 |
24 | # External tool builders
25 | .externalToolBuilders/
26 |
27 | # Locally stored "Eclipse launch configurations"
28 | *.launch
29 |
30 | # CDT-specific
31 | .cproject
32 |
33 | # PDT-specific
34 | .buildpath
35 |
36 |
37 | #################
38 | ## Visual Studio
39 | #################
40 |
41 | ## Ignore Visual Studio temporary files, build results, and
42 | ## files generated by popular Visual Studio add-ons.
43 |
44 | # User-specific files
45 | *.suo
46 | *.user
47 | *.sln.docstates
48 |
49 | # Build results
50 |
51 | [Dd]ebug/
52 | [Rr]elease/
53 | x64/
54 | build/
55 | [Bb]in/
56 | [Oo]bj/
57 |
58 | # MSTest test Results
59 | [Tt]est[Rr]esult*/
60 | [Bb]uild[Ll]og.*
61 |
62 | *_i.c
63 | *_p.c
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.pch
68 | *.pdb
69 | *.pgc
70 | *.pgd
71 | *.rsp
72 | *.sbr
73 | *.tlb
74 | *.tli
75 | *.tlh
76 | *.tmp
77 | *.tmp_proj
78 | *.log
79 | *.vspscc
80 | *.vssscc
81 | .builds
82 | *.pidb
83 | *.log
84 | *.scc
85 |
86 | # Visual C++ cache files
87 | ipch/
88 | *.aps
89 | *.ncb
90 | *.opensdf
91 | *.sdf
92 | *.cachefile
93 |
94 | # Visual Studio profiler
95 | *.psess
96 | *.vsp
97 | *.vspx
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | *.ncrunch*
114 | .*crunch*.local.xml
115 |
116 | # Installshield output folder
117 | [Ee]xpress/
118 |
119 | # DocProject is a documentation generator add-in
120 | DocProject/buildhelp/
121 | DocProject/Help/*.HxT
122 | DocProject/Help/*.HxC
123 | DocProject/Help/*.hhc
124 | DocProject/Help/*.hhk
125 | DocProject/Help/*.hhp
126 | DocProject/Help/Html2
127 | DocProject/Help/html
128 |
129 | # Click-Once directory
130 | publish/
131 |
132 | # Publish Web Output
133 | *.Publish.xml
134 | *.pubxml
135 |
136 | # NuGet Packages Directory
137 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
138 | #packages/
139 |
140 | # Windows Azure Build Output
141 | csx
142 | *.build.csdef
143 |
144 | # Windows Store app package directory
145 | AppPackages/
146 |
147 | # Others
148 | sql/
149 | *.Cache
150 | ClientBin/
151 | [Ss]tyle[Cc]op.*
152 | ~$*
153 | *~
154 | *.dbmdl
155 | *.[Pp]ublish.xml
156 | *.pfx
157 | *.publishsettings
158 |
159 | # RIA/Silverlight projects
160 | Generated_Code/
161 |
162 | # Backup & report files from converting an old project file to a newer
163 | # Visual Studio version. Backup files are not needed, because we have git ;-)
164 | _UpgradeReport_Files/
165 | Backup*/
166 | UpgradeLog*.XML
167 | UpgradeLog*.htm
168 |
169 | # SQL Server files
170 | App_Data/*.mdf
171 | App_Data/*.ldf
172 |
173 | #############
174 | ## Windows detritus
175 | #############
176 |
177 | # Windows image file caches
178 | Thumbs.db
179 | ehthumbs.db
180 |
181 | # Folder config file
182 | Desktop.ini
183 |
184 | # Recycle Bin used on file shares
185 | $RECYCLE.BIN/
186 |
187 | # Mac crap
188 | .DS_Store
189 |
190 |
191 | #############
192 | ## Python
193 | #############
194 |
195 | *.py[co]
196 |
197 | # Packages
198 | *.egg
199 | *.egg-info
200 | dist/
201 | build/
202 | eggs/
203 | parts/
204 | var/
205 | sdist/
206 | develop-eggs/
207 | .installed.cfg
208 |
209 | # Installer logs
210 | pip-log.txt
211 |
212 | # Unit test / coverage reports
213 | .coverage
214 | .tox
215 |
216 | #Translations
217 | *.mo
218 |
219 | #Mr Developer
220 | .mr.developer.cfg
221 | /target
222 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Introduction
2 | ============
3 |
4 | This project is a java library that is intended to provide a wrapper around JSON-RPC provided by Bitcoin/Litecoin.
5 |
6 | It has been tested on Litecoin. I wrote it for one of my projects.
7 |
8 | The main dependencies of this project are
9 |
10 | * **Htmlunit**
11 | * **Google Gson**
12 |
13 | Since this was intended for use in a proprietary project, I've tried to write as much javadoc as possible as to what the method does.
14 |
15 | JSON-RPC calls for Litecoin & Bitcoin are same as you can see below, so this work shall work with both. If it doesn't please let me know by filing an issue.
16 |
17 | [Litecoin RPC API Calls](https://litecoin.info/Litecoin_API)
18 |
19 | [Bitcoin RPC API Calls](https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29)
20 |
21 | This project assumes that the one who uses it has a preliminary knowledge about Bitcoin/Litecoin and how to start the RPC server.
22 |
23 | [Running Litecoin](https://litecoin.info/Litecoin.conf)
24 |
25 | [Running Bitcoin](https://en.bitcoin.it/wiki/Running_Bitcoin)
26 |
27 |
28 |
29 | Sample Usage
30 | ===========
31 |
32 | public static void main(String[] args) throws Exception {
33 | final String rpcUser = "rpcuser";
34 | final String rpcPassword = "password";
35 | final String rpcHost = "localhost";
36 | final String rpcPort = "9332";
37 | CryptoCurrencyRPC cryptoCurrencyRPC = new CryptoCurrencyRPC(rpcUser, rpcPassword, rpcHost, rpcPort);
38 |
39 | cryptoCurrencyRPC.setAccount("account","LCYEnDaddressENBYCEYD235NSD");
40 |
41 | //Similarly, all the API methods can be called.
42 | }
43 |
44 | ### Blockchain Events
45 | (part of the code was taken from https://github.com/johannbarbie/BitcoindClient4J)
46 |
47 | The library also captures notifications from Bitcoind using the startup configuration. Launch your deamon with those parameters:
48 | ```bash
49 | ./bitcoind -walletnotify="echo '%s' | nc 127.0.0.1 4002"
50 | -alertnotify="echo '%s' | nc 127.0.0.1 4003"
51 | -daemon
52 | ```
53 |
54 | You can register observers to capture events of wallets, and alerts:
55 | ```java
56 | WalletListener walletListener = new WalletListener(cryptoCurrencyRPC, 4002);
57 | walletListener.addObserver(new Observer() {
58 | @Override
59 | public void update(Observable o, Object arg) {
60 | System.out.println("Amount of transaction: " + ((Transaction)arg).getAmount());
61 | }
62 | });
63 |
64 | ```
65 |
66 | Make sure to close sockets later:
67 | ```java
68 | walletListener.stop();
69 | ```
70 |
71 | License
72 | =======
73 | Copyright (c) 2014-2015 Nitin Surana | Licensed under the MIT license.
74 |
75 |
76 | > Written with [StackEdit](https://stackedit.io/).
77 |
--------------------------------------------------------------------------------
/nbactions-release-profile.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | jar
7 |
8 |
9 | process-classes
10 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
11 |
12 |
13 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
14 | java
15 |
16 |
17 |
18 | debug
19 |
20 | jar
21 |
22 |
23 | process-classes
24 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
25 |
26 |
27 | -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath
28 | com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
29 | java
30 | true
31 |
32 |
33 |
34 | profile
35 |
36 | jar
37 |
38 |
39 | process-classes
40 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
41 |
42 |
43 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
44 | java
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/nbactions-sonatype-oss-release.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | jar
7 |
8 |
9 | process-classes
10 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
11 |
12 |
13 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
14 | java
15 |
16 |
17 |
18 | debug
19 |
20 | jar
21 |
22 |
23 | process-classes
24 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
25 |
26 |
27 | -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath
28 | com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
29 | java
30 | true
31 |
32 |
33 |
34 | profile
35 |
36 | jar
37 |
38 |
39 | process-classes
40 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
41 |
42 |
43 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
44 | java
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | jar
7 |
8 |
9 | process-classes
10 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
11 |
12 |
13 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
14 | java
15 |
16 |
17 |
18 | debug
19 |
20 | jar
21 |
22 |
23 | process-classes
24 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
25 |
26 |
27 | -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath
28 | com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
29 | java
30 | true
31 |
32 |
33 |
34 | profile
35 |
36 | jar
37 |
38 |
39 | process-classes
40 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
41 |
42 |
43 | -classpath %classpath com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
44 | java
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.nitinsurana
5 | Litecoin-Bitcoin-RPC-Java-Connector
6 | 2.0.0
7 | jar
8 |
9 | Litecoin-Bitcoin-RPC-Java-Connector
10 | Java Wrapper around the JSON-RPC provided by Bitcoin/Litecoin
11 | http://nitinsurana.com
12 |
13 |
14 |
15 | org.sonatype.oss
16 | oss-parent
17 | 7
18 |
19 |
20 |
21 |
22 | MIT License
23 | http://www.opensource.org/licenses/mit-license.php
24 | repo
25 |
26 |
27 |
28 |
29 |
30 | https://github.com/coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector
31 |
32 | scm:git:git@github.com:coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector.git
33 | scm:git:git@github.com:coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector.git
34 |
35 |
36 |
37 |
38 | nitin.cool4urchat@gmail.com
39 | Nitin Surana
40 | https://nitinsurana.com
41 | coding_idiot
42 |
43 |
44 |
45 |
46 | UTF-8
47 |
48 |
49 |
50 |
51 |
52 | org.apache.maven.plugins
53 | maven-jar-plugin
54 | 2.6
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.apache.maven.plugins
62 | maven-shade-plugin
63 | 1.6
64 |
65 |
66 | package
67 |
68 | shade
69 |
70 |
71 |
72 |
73 |
74 | org.apache.maven.plugins
75 | maven-compiler-plugin
76 | 2.0.2
77 |
78 | 1.6
79 | 1.6
80 |
81 |
82 |
83 | maven-dependency-plugin
84 | 2.10
85 |
86 |
87 | install
88 |
89 | copy-dependencies
90 |
91 |
92 | ${project.build.directory}/lib
93 |
94 |
95 |
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-jar-plugin
100 | 2.6
101 |
102 |
103 |
104 | true
105 | lib/
106 | com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC
107 |
108 |
109 |
110 |
111 |
112 | org.apache.maven.plugins
113 | maven-javadoc-plugin
114 |
115 |
116 |
117 | jar
118 |
119 |
120 | -Xdoclint:none
121 |
122 |
123 |
124 |
125 |
126 | org.apache.maven.plugins
127 | maven-source-plugin
128 | 2.4
129 |
130 |
131 |
132 | jar
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | org.apache.commons
143 | commons-lang3
144 | 3.4
145 |
146 |
147 | com.google.code.gson
148 | gson
149 | 2.3.1
150 |
151 |
152 | log4j
153 | log4j
154 | 1.2.17
155 |
156 |
157 | net.sourceforge.htmlunit
158 | htmlunit
159 | 2.15
160 | compile
161 |
162 |
163 | junit
164 | junit
165 | 4.12
166 | test
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/pom.xml.releaseBackup:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.nitinsurana
5 | Litecoin-Bitcoin-RPC-Java-Connector
6 | 2.0.0-SNAPSHOT
7 | jar
8 |
9 | Litecoin-Bitcoin-RPC-Java-Connector
10 | Java Wrapper around the JSON-RPC provided by Bitcoin/Litecoin
11 | http://nitinsurana.com
12 |
13 |
14 | org.sonatype.oss
15 | oss-parent
16 | 7
17 |
18 |
19 |
20 |
21 | MIT License
22 | http://www.opensource.org/licenses/mit-license.php
23 | repo
24 |
25 |
26 |
27 |
28 |
29 | https://github.com/coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector
30 |
31 | scm:git:git@github.com:coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector.git
32 | scm:git:git@github.com:coding-idiot/Litecoin-Bitcoin-RPC-Java-Connector.git
33 |
34 |
35 |
36 |
37 | nitin.cool4urchat@gmail.com
38 | Nitin Surana
39 | https://nitinsurana.com
40 | coding_idiot
41 |
42 |
43 |
44 |
45 | UTF-8
46 |
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-compiler-plugin
52 | 2.0.2
53 |
54 | 1.6
55 | 1.6
56 |
57 |
58 |
59 | maven-dependency-plugin
60 |
61 |
62 | install
63 |
64 | copy-dependencies
65 |
66 |
67 | ${project.build.directory}/lib
68 |
69 |
70 |
71 |
72 |
73 | org.apache.maven.plugins
74 | maven-jar-plugin
75 |
76 |
77 |
78 | true
79 | lib/
80 | com.nitinsurana.bitcoinlitecoin.rpcconnector.App
81 |
82 |
83 |
84 |
85 |
86 | org.apache.maven.plugins
87 | maven-javadoc-plugin
88 |
89 |
90 |
91 | jar
92 |
93 |
94 |
95 |
96 |
97 | org.apache.maven.plugins
98 | maven-source-plugin
99 |
100 |
101 |
102 | jar
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | org.apache.commons
113 | commons-lang3
114 | 3.2.1
115 |
116 |
117 | com.google.code.gson
118 | gson
119 | 2.2.4
120 |
121 |
122 | log4j
123 | log4j
124 | 1.2.17
125 |
126 |
127 | net.sourceforge.htmlunit
128 | htmlunit
129 | 2.12
130 | compile
131 |
132 |
133 | junit
134 | junit
135 | 4.11
136 | test
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/APICalls.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package com.nitinsurana.bitcoinlitecoin.rpcconnector;
7 |
8 | /**
9 | *
10 | * @author hp
11 | */
12 | public enum APICalls {
13 |
14 | GET_NEW_ADDRESS("getnewaddress"),
15 | DUMP_PRIVATE_KEY("dumpprivkey"),
16 | GET_ACCOUNT("getaccount"),
17 | GET_ACCOUNT_ADDRESS("getaccountaddress"),
18 | LIST_ACCOUNTS("listaccounts"),
19 | LIST_ADDRESS_GROUPINGS("listaddressgroupings"),
20 | LIST_RECEIVED_BY_ACCOUNT("listreceivedbyaccount"),
21 | LIST_RECEIVED_BY_ADDRESS("listreceivedbyaddress"),
22 | SEND_FROM("sendfrom"),
23 | SEND_RAW_TRANSACTION("sendrawtransaction"),
24 | SET_ACCOUNT("setaccount"),
25 | SEND_TO_ADDRESS("sendtoaddress"),
26 | GET_ADDRESSES_BY_ACCOUNT("getaddressesbyaccount"),
27 | GET_RECEIVED_BY_ACCOUNT("getreceivedbyaccount"),
28 | GET_RECEIVED_BY_ADDRESS("getreceivedbyaddress"),
29 | GET_BALANCE("getbalance"),
30 | GET_TRANSACTION("gettransaction"),
31 | GET_CONNECTION_COUNT("getconnectioncount"),
32 | BACKUP_WALLET("backupwallet"),
33 | DECODE_RAW_TRANSACTION("decoderawtransaction"),
34 | GET_RAW_TRANSACTION("getrawtransaction"),
35 | LIST_TRANSACTIONS("listtransactions"),
36 | LIST_UNSPENT("listunspent"),
37 | CREATE_RAW_TRANSACTION("createrawtransaction"),
38 | SIGN_RAW_TRANSACTION("signrawtransaction"),
39 | VALIDATE_ADDRESS("validateaddress"),
40 | ENCRYPT_WALLET("encryptwallet");
41 |
42 | private String value;
43 |
44 | private APICalls(String value) {
45 | this.value = value;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | //Using in BitcoinRPC#callAPIMethod(..)
51 | return value;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/CryptoCurrencyRPC.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector;
2 |
3 | import com.gargoylesoftware.htmlunit.*;
4 | import com.google.gson.Gson;
5 | import com.google.gson.JsonArray;
6 | import com.google.gson.JsonObject;
7 | import com.google.gson.JsonParser;
8 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.AuthenticationException;
9 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException;
10 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcExceptionHandler;
11 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CallApiCryptoCurrencyRpcException;
12 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.pojo.Transaction;
13 | import org.apache.log4j.Logger;
14 |
15 | import java.math.BigDecimal;
16 | import java.net.URL;
17 | import java.util.Arrays;
18 | import java.util.List;
19 |
20 | public class CryptoCurrencyRPC {
21 |
22 | public static final Logger LOG = Logger.getLogger("rpcLogger");
23 |
24 | private WebClient client;
25 | private String baseUrl;
26 | private CryptoCurrencyRpcExceptionHandler cryptoCurrencyRpcExceptionHandler = new CryptoCurrencyRpcExceptionHandler();
27 | private Gson gson = new Gson();
28 |
29 | public CryptoCurrencyRPC(String rpcUser, String rpcPassword, String rpcHost, String rpcPort) throws AuthenticationException {
30 | client = new WebClient(BrowserVersion.CHROME);
31 | client.getOptions().setThrowExceptionOnFailingStatusCode(false);
32 | client.getOptions().setThrowExceptionOnScriptError(false);
33 | client.getOptions().setPrintContentOnFailingStatusCode(false);
34 | client.getOptions().setJavaScriptEnabled(false);
35 | client.getOptions().setCssEnabled(false);
36 | baseUrl = new String("http://" + rpcUser + ":" + rpcPassword + "@" + rpcHost + ":" + rpcPort + "/");
37 |
38 | try {
39 | if (client.getPage(baseUrl).getWebResponse().getStatusCode() == 401) { //401 is Http Unauthorized
40 | throw new AuthenticationException();
41 | }
42 | } catch (Exception ex) {
43 | LOG.error(ex.getMessage(), ex);
44 | }
45 | }
46 |
47 | /**
48 | * Safely copies wallet.dat to destination, which can be a directory or a
49 | * path with filename.
50 | *
51 | * @param destination
52 | * @return
53 | * @throws Exception
54 | */
55 | public boolean backupWallet(String destination) throws CryptoCurrencyRpcException {
56 | JsonObject jsonObj = callAPIMethod(APICalls.BACKUP_WALLET, destination);
57 | if (jsonObj.get("error") == null) {
58 | return true;
59 | }
60 | return false;
61 | }
62 |
63 | /**
64 | * Produces a human-readable JSON object for a raw transaction.
65 | *
66 | * @param hex
67 | * @return
68 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
69 | */
70 | public JsonObject decodeRawTransaction(String hex) throws CryptoCurrencyRpcException {
71 | JsonObject jsonObj = callAPIMethod(APICalls.DECODE_RAW_TRANSACTION, hex);
72 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
73 | return jsonObj.get("result").getAsJsonObject();
74 | }
75 |
76 | /**
77 | * Reveals the private key corresponding to
78 | *
79 | * @param address
80 | * @return
81 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
82 | */
83 | public String dumpPrivateKey(String address) throws CryptoCurrencyRpcException {
84 | JsonObject jsonObj = callAPIMethod(APICalls.DUMP_PRIVATE_KEY, address);
85 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
86 | return jsonObj.get("result").getAsString();
87 | }
88 |
89 | /**
90 | * Returns raw transaction representation for given transaction id.
91 | *
92 | * @param txid
93 | * @return returns the hex string for the given transaction id
94 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
95 | */
96 | public String getRawTransaction(String txid) throws CryptoCurrencyRpcException {
97 | JsonObject jsonObj = callAPIMethod(APICalls.GET_RAW_TRANSACTION, txid);
98 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
99 | return jsonObj.get("result").getAsString();
100 | }
101 |
102 | /**
103 | * Returns the account associated with the given address.
104 | *
105 | * @param address
106 | * @return
107 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
108 | */
109 | public String getAccount(String address) throws CryptoCurrencyRpcException {
110 | JsonObject jsonObj = callAPIMethod(APICalls.GET_ACCOUNT, address);
111 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
112 | return jsonObj.get("result").getAsString();
113 | }
114 |
115 | /**
116 | * Returns the current Litecoin address for receiving payments to this
117 | * account.
118 | *
119 | * @param account
120 | * @return
121 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
122 | */
123 | public String getAccountAddress(String account) throws CryptoCurrencyRpcException {
124 | JsonObject jsonObj = callAPIMethod(APICalls.GET_ACCOUNT_ADDRESS, account);
125 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
126 | return jsonObj.get("result").getAsString();
127 | }
128 |
129 | /**
130 | * Returns the list of addresses for the given account.
131 | *
132 | * @param account
133 | * @return
134 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
135 | */
136 | public JsonArray getAddressesByAccount(String account) throws CryptoCurrencyRpcException {
137 | JsonObject jsonObj = callAPIMethod(APICalls.GET_ADDRESSES_BY_ACCOUNT, account);
138 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
139 | return jsonObj.get("result").getAsJsonArray();
140 | }
141 |
142 | /**
143 | * Returns the balance in the account.
144 | *
145 | * @param account
146 | * @return
147 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
148 | */
149 | public BigDecimal getBalance(String account) throws CryptoCurrencyRpcException {
150 | JsonObject jsonObj = callAPIMethod(APICalls.GET_BALANCE, account);
151 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
152 | return jsonObj.get("result").getAsBigDecimal();
153 | }
154 |
155 | /**
156 | * Returns the wallet's total available balance.
157 | *
158 | * @return
159 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
160 | */
161 | public BigDecimal getBalance() throws CryptoCurrencyRpcException {
162 | JsonObject jsonObj = callAPIMethod(APICalls.GET_BALANCE);
163 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
164 | return jsonObj.get("result").getAsBigDecimal();
165 | }
166 |
167 | /**
168 | * Returns the total amount received by addresses with [account] in
169 | * transactions
170 | *
171 | * @param account
172 | * @return
173 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
174 | */
175 | public BigDecimal getReceivedByAccount(String account) throws CryptoCurrencyRpcException {
176 | JsonObject jsonObj = callAPIMethod(APICalls.GET_RECEIVED_BY_ACCOUNT, account);
177 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
178 | return jsonObj.get("result").getAsBigDecimal();
179 | }
180 |
181 | /**
182 | * Returns a new address for receiving payments.
183 | *
184 | * @return
185 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
186 | */
187 | public String getNewAddress() throws CryptoCurrencyRpcException {
188 | JsonObject jsonObj = callAPIMethod(APICalls.GET_NEW_ADDRESS);
189 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
190 | return jsonObj.get("result").getAsString();
191 | }
192 |
193 | /**
194 | * Returns a new address for receiving payments.
195 | *
196 | * @param account
197 | * @return
198 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
199 | */
200 | public String getNewAddress(String account) throws CryptoCurrencyRpcException {
201 | JsonObject jsonObj = callAPIMethod(APICalls.GET_NEW_ADDRESS, account);
202 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
203 | return jsonObj.get("result").getAsString();
204 | }
205 |
206 | /**
207 | * Returns the total amount received by in transactions
208 | *
209 | * @param address
210 | * @return
211 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
212 | */
213 | public BigDecimal getReceivedByAddress(String address) throws CryptoCurrencyRpcException {
214 | JsonObject jsonObj = callAPIMethod(APICalls.GET_RECEIVED_BY_ADDRESS, address);
215 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
216 | return jsonObj.get("result").getAsBigDecimal();
217 | }
218 |
219 | /**
220 | * Returns an object about the given transaction containing: amount,
221 | * confirmations, txid, time[1], details (an array of objects containing:
222 | * account, address, category, amount, fee)
223 | *
224 | * @param txid
225 | * @return
226 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
227 | */
228 | public Transaction getTransaction(String txid) throws CryptoCurrencyRpcException {
229 | JsonObject jsonObj = callAPIMethod(APICalls.GET_TRANSACTION, txid);
230 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
231 | return gson.fromJson(jsonObj.get("result").getAsJsonObject(), Transaction.class);
232 | }
233 |
234 | /**
235 | * Returns Object that has account names as keys, account balances as
236 | * values.
237 | *
238 | * @return
239 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
240 | */
241 | public JsonObject listAccounts() throws CryptoCurrencyRpcException {
242 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_ACCOUNTS);
243 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
244 | return jsonObj.get("result").getAsJsonObject();
245 | }
246 |
247 | /**
248 | * Returns an array of objects containing: account, amount, confirmations
249 | *
250 | * @return
251 | */
252 | public JsonArray listReceivedByAccount() throws CryptoCurrencyRpcException {
253 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_RECEIVED_BY_ACCOUNT);
254 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
255 | return jsonObj.get("result").getAsJsonArray();
256 | }
257 |
258 | /**
259 | * Returns an array of objects containing: address, account, amount,
260 | * confirmations
261 | *
262 | * @return
263 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
264 | */
265 | public JsonArray listReceivedByAddress() throws CryptoCurrencyRpcException {
266 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_RECEIVED_BY_ADDRESS);
267 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
268 | return jsonObj.get("result").getAsJsonArray();
269 | }
270 |
271 | /**
272 | * is a real and is rounded to 8 decimal places. Will send the
273 | * given amount to the given address, ensuring the account has a valid
274 | * balance using [minconf] confirmations. Returns the transaction ID if
275 | * successful
276 | *
277 | * @param fromAccount
278 | * @param toAddress
279 | * @param amount
280 | * @return
281 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
282 | */
283 | public String sendFrom(String fromAccount, String toAddress, BigDecimal amount) throws CryptoCurrencyRpcException {
284 | JsonObject response = callAPIMethod(APICalls.SEND_FROM, fromAccount, toAddress, amount);
285 | cryptoCurrencyRpcExceptionHandler.checkException(response);
286 | return response.get("result").getAsString();
287 | }
288 |
289 | /**
290 | * < amount > is a real and is rounded to the nearest 0.00000001
291 | *
292 | * @param toAddress
293 | * @param amount
294 | * @return TransactionID
295 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
296 | */
297 | public String sendToAddress(String toAddress, BigDecimal amount) throws CryptoCurrencyRpcException {
298 | JsonObject jsonObj = callAPIMethod(APICalls.SEND_TO_ADDRESS, toAddress, amount);
299 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
300 | return jsonObj.get("result").getAsString();
301 | }
302 |
303 | public boolean validateAddress(String address) throws CryptoCurrencyRpcException {
304 | JsonObject jsonObj = callAPIMethod(APICalls.VALIDATE_ADDRESS, address);
305 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
306 | return jsonObj.get("result").getAsJsonObject().get("isvalid").getAsBoolean();
307 | }
308 |
309 | /**
310 | * Sets the account associated with the given address. Assigning address
311 | * that is already assigned to the same account will create a new address
312 | * associated with that account.
313 | *
314 | * @param address
315 | * @param account
316 | *
317 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
318 | */
319 | public void setAccount(String address, String account) throws CryptoCurrencyRpcException {
320 | JsonObject jsonObj = callAPIMethod(APICalls.SET_ACCOUNT, address, account);
321 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
322 | }
323 |
324 | /**
325 | * Returns up to [count] most recent transactions skipping the first [from]
326 | * transactions for account [account].
327 | *
328 | * @param account
329 | * @param count
330 | * @param from
331 | * @return
332 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
333 | */
334 | public List listTransactions(String account, int count, int from) throws CryptoCurrencyRpcException {
335 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_TRANSACTIONS, account, count, from);
336 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
337 |
338 | return Arrays.asList(gson.fromJson(jsonObj.get("result").getAsJsonArray(), Transaction[].class));
339 | }
340 |
341 | /**
342 | * Returns all unspent outputs with at least [minconf] and at most [maxconf]
343 | * confirmations.
344 | *
345 | * @param minconf
346 | * @param maxconf
347 | * @return
348 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
349 | */
350 | public JsonArray listUnspent(int minconf, int maxconf) throws CryptoCurrencyRpcException {
351 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_UNSPENT, minconf, maxconf);
352 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
353 |
354 | return jsonObj.get("result").getAsJsonArray();
355 | }
356 |
357 | /**
358 | * Returns all unspent outputs with at least [minconf] and at most 9999999
359 | * confirmations; Further limited to outputs that pay at least one of the
360 | * given addresses in the [address] array.
361 | *
362 | * @param minconf
363 | * @param address
364 | * @return
365 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
366 | */
367 | public JsonArray listUnspent(int minconf, String[] address) throws CryptoCurrencyRpcException {
368 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_UNSPENT, minconf, address);
369 |
370 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
371 | return jsonObj.get("result").getAsJsonArray();
372 | }
373 |
374 |
375 | /**
376 | * Returns all unspent outputs with at least [minconf] and at most 9999999
377 | * confirmations.
378 | *
379 | * @param minconf
380 | * @return
381 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
382 | */
383 | public JsonArray listUnspent(int minconf) throws CryptoCurrencyRpcException {
384 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_UNSPENT, minconf);
385 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
386 | return jsonObj.get("result").getAsJsonArray();
387 | }
388 |
389 | /**
390 | * Returns all unspent outputs with at least [minconf] and at most [maxconf]
391 | * confirmations; Further limited to outputs that pay at least one of the
392 | * given addresses in the [address] array.
393 | *
394 | * @param minconf
395 | * @param maxconf
396 | * @param address
397 | * @return
398 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
399 | */
400 | public JsonArray listUnspent(int minconf, int maxconf, String[] address) throws CryptoCurrencyRpcException {
401 | JsonObject jsonObj = callAPIMethod(APICalls.LIST_UNSPENT, minconf, maxconf, address);
402 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
403 |
404 | return jsonObj.get("result").getAsJsonArray();
405 | }
406 |
407 | /**
408 | * Returns an unsigned transaction that spends the outputs [prevOut] to new
409 | * outputs [Out] and encodes it as hex format.
410 | *
411 | * @param prevOut is an array of JsonObjects, each with the properties
412 | * "txid" and "vout".
413 | * @param out is an JsonObject with the receiving addresses as properties
414 | * and the receiving amount as value of each property(=address)
415 | * @return
416 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
417 | */
418 | public Transaction createRawTransaction(JsonObject[] prevOut, JsonObject out) throws CryptoCurrencyRpcException {
419 | JsonObject jsonObj = callAPIMethod(APICalls.CREATE_RAW_TRANSACTION, prevOut, out);
420 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
421 |
422 | return gson.fromJson(jsonObj.get("result").getAsJsonObject(), Transaction.class);
423 | }
424 |
425 | /**
426 | * Returns a signed transaction in hex format using private keys stored in
427 | * the wallet and the output from createRawTransaction()
428 | *
429 | * @param hexString
430 | * @return
431 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
432 | */
433 | public Transaction signRawTransaction(String hexString) throws CryptoCurrencyRpcException {
434 | JsonObject jsonObj = callAPIMethod(APICalls.SIGN_RAW_TRANSACTION,hexString);
435 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
436 |
437 | return gson.fromJson(jsonObj.get("result").getAsJsonObject(), Transaction.class);
438 | }
439 |
440 | /**
441 | * Validates a signed transaction in hex format and broadcasts it to the
442 | * network.
443 | *
444 | * @param hexString
445 | * @return
446 | * @throws com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException
447 | */
448 | public String sendRawTransaction(String hexString) throws CryptoCurrencyRpcException {
449 | JsonObject jsonObj = callAPIMethod(APICalls.SEND_RAW_TRANSACTION,hexString);
450 | cryptoCurrencyRpcExceptionHandler.checkException(jsonObj);
451 |
452 | return jsonObj.get("result").getAsString();
453 | }
454 |
455 | private JsonObject callAPIMethod(APICalls callMethod, Object... params) throws CallApiCryptoCurrencyRpcException {
456 | try {
457 | JsonObject jsonObj = null;
458 | WebRequest req = new WebRequest(new URL(baseUrl));
459 | req.setAdditionalHeader("Content-type", "application/json");
460 | req.setHttpMethod(HttpMethod.POST);
461 | JSONRequestBody body = new JSONRequestBody();
462 | body.setMethod(callMethod.toString());
463 | if (params != null && params.length > 0) {
464 | body.setParams(params);
465 | }
466 | req.setRequestBody(new Gson().toJson(body, JSONRequestBody.class));
467 | WebResponse resp = client.getPage(req).getWebResponse();
468 | jsonObj = new JsonParser().parse(resp.getContentAsString()).getAsJsonObject();
469 |
470 | StringBuffer buffer = new StringBuffer("");
471 | for (Object item : params) {
472 | buffer.append(item.toString() + " | ");
473 | }
474 | LOG.info("Bitcoin RPC Request: Method: " + callMethod + " Params: " + buffer.toString() +
475 | "\nBitcoin RPC Response : " + jsonObj);
476 |
477 | return jsonObj;
478 | } catch (Exception e) {
479 | throw new CallApiCryptoCurrencyRpcException(e.getMessage());
480 | }
481 | }
482 | }
483 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/JSONRequestBody.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package com.nitinsurana.bitcoinlitecoin.rpcconnector;
7 |
8 | /**
9 | *
10 | * @author hp
11 | */
12 | public class JSONRequestBody {
13 |
14 | private String method, id;
15 | private Object[] params = new Object[]{};
16 |
17 | public String getMethod() {
18 | return method;
19 | }
20 |
21 | public void setMethod(String method) {
22 | this.method = method;
23 | }
24 |
25 | public String getId() {
26 | return id;
27 | }
28 |
29 | public void setId(String id) {
30 | this.id = id;
31 | }
32 |
33 | public Object[] getParams() {
34 | return params;
35 | }
36 |
37 | public void setParams(Object[] params) {
38 | this.params = params;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/events/AlertListener.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.events;
2 |
3 | import java.io.IOException;
4 | import java.util.Observable;
5 | import java.util.Observer;
6 |
7 | /**
8 | * The class, which allows to subscribe to notifications of events related to Bitcoin network.
9 | * Bitcoind must be configured with -alertnotify parameter.
10 | */
11 | public class AlertListener extends Observable implements Observer {
12 |
13 | final private Observable alertListener;
14 | public Thread listener = null;
15 |
16 | public AlertListener(int port) throws IOException {
17 | alertListener = new BitcoinDListener(port);
18 | }
19 |
20 | @Override
21 | public synchronized void addObserver(Observer o) {
22 | if (null == listener) {
23 | alertListener.addObserver(this);
24 | listener = new Thread((Runnable) alertListener, "alertListener");
25 | listener.start();
26 | }
27 | super.addObserver(o);
28 | }
29 |
30 | @Override
31 | public void update(Observable o, Object arg) {
32 | final String value = ((String) arg).trim();
33 | setChanged();
34 | notifyObservers(value);
35 | }
36 |
37 | public void stop(){
38 | listener.interrupt();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/events/BitcoinDListener.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.events;
2 |
3 | import org.apache.log4j.Logger;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.net.ServerSocket;
9 | import java.net.Socket;
10 | import java.util.Observable;
11 |
12 | /**
13 | * Basic class for implementation CryptoCurrencyListener's. Contains work with ports and streams.
14 | */
15 | public class BitcoinDListener extends Observable implements Runnable {
16 | public static final Logger LOG = Logger.getLogger("rpcLogger");
17 | private final ServerSocket server;
18 | private int port;
19 |
20 | public BitcoinDListener(int port) throws IOException {
21 | server = new ServerSocket(port);
22 | this.port = port;
23 | }
24 |
25 | public BitcoinDListener(ServerSocket server) throws IOException {
26 | this.server = server;
27 | this.port = server.getLocalPort();
28 | }
29 |
30 | @Override
31 | public void run() {
32 | LOG.info("Thread " + Thread.currentThread().getName()
33 | + " started listening on " + port);
34 | while (!Thread.currentThread().isInterrupted()) {
35 | Socket connection = null;
36 | try {
37 | connection = server.accept();
38 | } catch (IOException e1) {
39 | e1.printStackTrace();
40 | break;
41 | }
42 | try {
43 | BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
44 | String line;
45 | if ((line = reader.readLine()) != null) {
46 | setChanged();
47 | notifyObservers(line);
48 | connection.close();
49 | }
50 | } catch (IOException e) {
51 | e.printStackTrace();
52 | } finally {
53 | // sockets are closed when complete.
54 | try {
55 | if (connection != null)
56 | connection.close();
57 | } catch (IOException e) {
58 | }
59 | }
60 | }
61 | LOG.warn("Thread " + Thread.currentThread().getName() + " exited");
62 | }
63 |
64 | @Override
65 | protected void finalize() throws Throwable {
66 | server.close();
67 | LOG.info("Thread " + Thread.currentThread().getName() + " shutting down.");
68 | super.finalize();
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/events/WalletListener.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.events;
2 |
3 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.CryptoCurrencyRPC;
4 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.exception.CryptoCurrencyRpcException;
5 | import com.nitinsurana.bitcoinlitecoin.rpcconnector.pojo.Transaction;
6 | import org.apache.log4j.Logger;
7 |
8 | import java.io.IOException;
9 | import java.util.Observable;
10 | import java.util.Observer;
11 |
12 | /**
13 | * The class allows you to subscribe to the events associated with purses.
14 | * Bitcoind must be configured with -walletnotify parameter.
15 | */
16 | public class WalletListener extends Observable implements Observer {
17 | public static final Logger LOG = Logger.getLogger("rpcLogger");
18 |
19 | final private Observable walletListener;
20 | final private CryptoCurrencyRPC client;
21 | public Thread listener = null;
22 |
23 | public WalletListener(final CryptoCurrencyRPC client, int port) throws IOException {
24 | walletListener = new BitcoinDListener(port);
25 | this.client = client;
26 | }
27 |
28 | @Override
29 | public synchronized void addObserver(Observer o) {
30 | if (listener == null) {
31 | walletListener.addObserver(this);
32 | listener = new Thread((Runnable) walletListener, "walletListener");
33 | listener.start();
34 | }
35 | super.addObserver(o);
36 | }
37 |
38 | @Override
39 | public void update(Observable o, Object arg) {
40 | final String value = ((String) arg).trim();
41 | new Thread() {
42 | public void run() {
43 | try {
44 | Transaction tx = client.getTransaction(value);
45 | LOG.info("WalletEvent. TxId: " + tx.getTxid() + " Amount: " + tx.getAmount());
46 | setChanged();
47 | notifyObservers(tx);
48 | } catch (CryptoCurrencyRpcException e) {
49 | e.printStackTrace();
50 | }
51 |
52 | }
53 | }.start();
54 | }
55 |
56 | public void stop(){
57 | listener.interrupt();
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/AuthenticationException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
7 |
8 | /**
9 | *
10 | * @author hp
11 | */
12 | public class AuthenticationException extends CryptoCurrencyRpcException {
13 |
14 | public AuthenticationException() {
15 | super("Invalid RPC Credentials");
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/CallApiCryptoCurrencyRpcException.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
2 |
3 | /**
4 | * Created by d.romantsov on 26.05.2015.
5 | */
6 | public class CallApiCryptoCurrencyRpcException extends CryptoCurrencyRpcException {
7 | public CallApiCryptoCurrencyRpcException(String message) {
8 | super(message);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/CryptoCurrencyRpcException.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
2 |
3 | /**
4 | * Created by d.romantsov on 22.05.2015.
5 | */
6 | public class CryptoCurrencyRpcException extends RuntimeException {
7 |
8 | public CryptoCurrencyRpcException(String message) {
9 | super(message);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/CryptoCurrencyRpcExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
2 |
3 | import com.google.gson.JsonObject;
4 |
5 | /**
6 | * Created by d.romantsov on 22.05.2015.
7 | */
8 | public class CryptoCurrencyRpcExceptionHandler {
9 |
10 | public void checkException(JsonObject response) throws CryptoCurrencyRpcException {
11 | if (response.get("error") != null && response.get("error").isJsonObject() == true) {
12 | JsonObject errorJson = response.get("error").getAsJsonObject();
13 | String message = errorJson.get("message").getAsString();
14 |
15 | int code = errorJson.get("code").getAsInt();
16 | switch (code) {
17 | case -6:
18 | throw new InsufficientFundsException(message);
19 | default:
20 | throw new CryptoCurrencyRpcException(message);
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/InsufficientFundsException.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
2 |
3 | /**
4 | * Created by d.romantsov on 22.05.2015.
5 | */
6 | public class InsufficientFundsException extends CryptoCurrencyRpcException {
7 | public InsufficientFundsException(String message) {
8 | super(message);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/exception/RpcInvalidResponseException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.exception;
7 |
8 | /**
9 | *
10 | * @author hp
11 | */
12 | public class RpcInvalidResponseException extends CryptoCurrencyRpcException {
13 |
14 | public RpcInvalidResponseException(String message) {
15 | super(message);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/nitinsurana/bitcoinlitecoin/rpcconnector/pojo/Transaction.java:
--------------------------------------------------------------------------------
1 | package com.nitinsurana.bitcoinlitecoin.rpcconnector.pojo;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import java.math.BigDecimal;
6 | import java.util.Date;
7 | import java.util.List;
8 |
9 | public class Transaction {
10 |
11 | public enum Category {
12 | @SerializedName("receive")
13 | RECEIVE,
14 | @SerializedName("send")
15 | SEND,
16 | @SerializedName("conflicted")
17 | CONFLICTED,
18 | @SerializedName("move")
19 | MOVE;
20 |
21 | /*private String text;
22 |
23 | Category(String text) {
24 | this.text = text;
25 | }
26 |
27 | final String value() {
28 | return this.text;
29 | }
30 |
31 | public String getText() {
32 | return this.text;
33 | }
34 |
35 | public static Category fromString(String text) {
36 | if (text != null) {
37 | for (Category b : Category.values()) {
38 | if (text.equalsIgnoreCase(b.text)) {
39 | return b;
40 | }
41 | }
42 | }
43 | return null;
44 | }*/
45 | }
46 |
47 |
48 | private BigDecimal fee;
49 | private BigDecimal amount;
50 | private long blockindex;
51 | private Category category;
52 | private long confirmations;
53 | private long time;
54 | private long timereceived;
55 | private long blocktime;
56 | private List walletconflicts;
57 | private List details;
58 | private String address;
59 | private String txid;
60 | private long block;
61 | private String hex;
62 | private String blockhash;
63 | private String account;
64 | private String otheraccount;
65 | private String comment;
66 | private String to;
67 |
68 |
69 | public String getOtheraccount() {
70 | return otheraccount;
71 | }
72 | public Transaction setOtheraccount(String otheraccount) {
73 | this.otheraccount = otheraccount;
74 | return this;
75 | }
76 | public String getComment() {
77 | return comment;
78 | }
79 | public Transaction setComment(String comment) {
80 | this.comment = comment;
81 | return this;
82 | }
83 | public BigDecimal getFee() {
84 | return fee;
85 | }
86 | public Transaction setFee(BigDecimal fee) {
87 | this.fee = fee;
88 | return this;
89 | }
90 | public BigDecimal getAmount() {
91 | return amount;
92 | }
93 | public Transaction setAmount(BigDecimal amount) {
94 | this.amount = amount;
95 | return this;
96 | }
97 | public long getBlockindex() {
98 | return blockindex;
99 | }
100 | public List getWalletconflicts() {
101 | return walletconflicts;
102 | }
103 | public Transaction setWalletconflicts(List walletconflicts) {
104 | this.walletconflicts = walletconflicts;
105 | return this;
106 | }
107 | public Transaction setBlockindex(long blockindex) {
108 | this.blockindex = blockindex;
109 | return this;
110 | }
111 | public Category getCategory() {
112 | return category;
113 | }
114 | public Transaction setCategory(Category category) {
115 | this.category = category;
116 | return this;
117 | }
118 | public long getConfirmations() {
119 | return confirmations;
120 | }
121 | public Transaction setConfirmations(long confirmations) {
122 | this.confirmations = confirmations;
123 | return this;
124 | }
125 | public String getAddress() {
126 | return address;
127 | }
128 | public Transaction setAddress(String address) {
129 | this.address = address;
130 | return this;
131 | }
132 | public String getTxid() {
133 | return txid;
134 | }
135 | public Transaction setTxid(String txid) {
136 | this.txid = txid;
137 | return this;
138 | }
139 | public long getBlock() {
140 | return block;
141 | }
142 | public Transaction setBlock(long block) {
143 | this.block = block;
144 | return this;
145 | }
146 |
147 | public String getHex() {
148 | return hex;
149 | }
150 | public Transaction setHex(String hex) {
151 | this.hex = hex;
152 | return this;
153 | }
154 | public String getBlockhash() {
155 | return blockhash;
156 | }
157 | public Transaction setBlockhash(String blockhash) {
158 | this.blockhash = blockhash;
159 | return this;
160 | }
161 | public List getDetails() {
162 | return details;
163 | }
164 | public Transaction setDetails(List details) {
165 | this.details = details;
166 | return this;
167 | }
168 | public String getAccount() {
169 | return account;
170 | }
171 | public Transaction setAccount(String account) {
172 | this.account = account;
173 | return this;
174 | }
175 | public long getTime() {
176 | return time;
177 | }
178 | public Transaction setTime(long time) {
179 | this.time = time;
180 | return this;
181 | }
182 | public Date getDateTime() {
183 | return new Date(getTime()*1000);
184 | }
185 |
186 | public long getTimereceived() {
187 | return timereceived;
188 | }
189 | public Transaction setTimereceived(long timereceived) {
190 | this.timereceived = timereceived;
191 | return this;
192 | }
193 | public long getBlocktime() {
194 | return blocktime;
195 | }
196 | public Transaction setBlocktime(long blocktime) {
197 | this.blocktime = blocktime;
198 | return this;
199 | }
200 | public String getTo() {
201 | return to;
202 | }
203 | public Transaction setTo(String to) {
204 | this.to = to;
205 | return this;
206 | }
207 |
208 |
209 | }
210 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Loggers configuration
2 | log4j.logger.rpcLogger = stdout, file, applog
3 |
4 | # Console output
5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6 | log4j.appender.stdout.Target=System.out
7 | log4j.appender.stdout.Threshold=WARN
8 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.stdout.layout.ConversionPattern=%d - %m%n
10 |
11 | #Log to a separate file
12 | log4j.appender.file=org.apache.log4j.RollingFileAppender
13 | log4j.appender.file.File=/var/log/bitcoin-rpc/coin.log
14 | log4j.appender.file.MaxFileSize=50000KB
15 | log4j.appender.file.MaxBackupIndex=50
16 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
17 | log4j.appender.file.layout.ConversionPattern=%d - %m%n
18 |
19 | #Logging to another separate file
20 | log4j.appender.applog=org.apache.log4j.DailyRollingFileAppender
21 | log4j.appender.applog.encoding=UTF-8
22 | log4j.appender.applog.layout=org.apache.log4j.PatternLayout
23 | log4j.appender.applog.layout.ConversionPattern=%d{yyyy:MM:dd_HH:mm} %m%n
24 | log4j.appender.applog.File=/var/log/bitcoin-rpc/daily/day.log
25 | log4j.appender.applog.DatePattern='.'yyyyMM:dd_HH:mm'.log'
--------------------------------------------------------------------------------
/src/test/java/com/nitinsurana/litecoinrpcconnector/AppTest.java:
--------------------------------------------------------------------------------
1 | //package com.nitinsurana.litecoinrpcconnector;
2 | //
3 | //import com.google.gson.JsonObject;
4 | //import junit.framework.Test;
5 | //import junit.framework.TestCase;
6 | //import junit.framework.TestSuite;
7 | //import org.junit.Before;
8 | //import org.junit.BeforeClass;
9 | //
10 | ///**
11 | // * Unit test for simple App.
12 | // */
13 | //public class AppTest
14 | // extends TestCase {
15 | //
16 | // String txnId = "1a89f40ffc8695867827316fe99dbca1c9cc28bc295085b6a5587b4320acd185";
17 | //
18 | // /**
19 | // * Create the test case
20 | // *
21 | // * @param testName name of the test case
22 | // */
23 | // public AppTest(String testName) {
24 | // super(testName);
25 | // }
26 | //
27 | // /**
28 | // * @return the suite of tests being tested
29 | // */
30 | // public static Test suite() {
31 | // return new TestSuite(AppTest.class);
32 | // }
33 | // App app;
34 | //
35 | // @Before
36 | // public void init() throws AuthenticationException {
37 | // final String rpcUser = "Nitin";
38 | // final String rpcPassword = "magicmaker07";
39 | // final String rpcHost = "localhost";
40 | // final String rpcPort = "9332";
41 | // app = new App(rpcUser, rpcPassword, rpcHost, rpcPort);
42 | //// app=new App(null, null, null, null)
43 | // }
44 | //
45 | // @org.junit.Test
46 | // public void testBackupWallet() throws Exception {
47 | // assertTrue(app.backupWallet("c:/nitin.xzy"));
48 | // assertFalse(app.backupWallet(null));
49 | // assertFalse(app.backupWallet(""));
50 | // }
51 | //
52 | // @org.junit.Test
53 | // public void testGetRawTransaction() throws Exception {
54 | // assertNotNull(app.getRawTransaction(txnId));
55 | // }
56 | //
57 | // @org.junit.Test
58 | // public void testDecodeRawTransaction() throws Exception {
59 | //// String txnId = "1a89f40ffc8695867827316fe99dbca1c9cc28bc295085b6a5587b4320acd185";
60 | // String hex = app.getRawTransaction(txnId);
61 | // assertTrue(app.decodeRawTransaction(txnId) instanceof JsonObject);
62 | // }
63 | //
64 | // @org.junit.Test(expected = RpcInvalidResponseException.class)
65 | // public void testDumpPrivateKey() throws Exception {
66 | // String s = app.dumpPrivateKey("LMNtL3ta9Ff69frtecAuZ1LrW63R7fJ2TBD1");
67 | // assertNotNull(s);
68 | // //Below should throw Exception
69 | // app.dumpPrivateKey("LMNtL3ta9Fasdff69frtecAuZ1LrW63R7fJ2TBD1");
70 | // }
71 | //
72 | // /**
73 | // * Rigourous Test :-)
74 | // */
75 | // public void testApp() {
76 | // assertTrue(true);
77 | // }
78 | //}
79 |
--------------------------------------------------------------------------------