merge
[electrum-nvc.git] / client / remote_wallet.py
1 #!/usr/bin/env python
2 #
3 # Electrum - lightweight Bitcoin client
4 # Copyright (C) 2011 thomasv@gitorious
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import time, thread, sys, socket
20
21 # see http://code.google.com/p/jsonrpclib/
22 import jsonrpclib
23 from wallet import Wallet
24
25 """
26 Simple wallet daemon for webservers.
27 - generates new addresses on request
28 - private keys are not needed in order to generate new addresses. A neutralized wallet can be used (seed removed)
29 - no gap limit: use 'getnum' to know how many addresses have been created.
30
31 todo:
32 - return the max gap
33 - add expiration date
34
35 """
36
37
38 host = 'ecdsa.org'
39 port = 8444
40 wallet_path = 'wallet_path'
41 username = 'foo'
42 password = 'bar'
43 wallet = Wallet()
44 stopping = False
45
46
47
48 from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCRequestHandler
49 import SimpleXMLRPCServer
50
51 class authHandler(SimpleJSONRPCRequestHandler):
52     def parse_request(self):
53         if SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.parse_request(self):
54             if self.authenticate(self.headers):
55                 return True
56             else:
57                 self.send_error(401, 'Authentication failed')
58             return False
59
60     def authenticate(self, headers):
61         from base64 import b64decode
62         basic, _, encoded = headers.get('Authorization').partition(' ')
63         assert basic == 'Basic', 'Only basic authentication supported'
64         x_username, _, x_password = b64decode(encoded).partition(':')
65         return username == x_username and password == x_password
66
67
68 def do_stop():
69     global stopping
70     stopping = True
71
72 def get_new_address():
73     a = wallet.create_new_address(False)
74     wallet.save()
75     return a
76
77 def get_num():
78     return len(wallet.addresses)
79
80 def get_mpk():
81     return wallet.master_public_key.encode('hex')
82
83
84
85 if __name__ == '__main__':
86
87     if len(sys.argv)>1:
88         import jsonrpclib
89         server = jsonrpclib.Server('http://%s:%s@%s:%d'%(username, password, host, port))
90         cmd = sys.argv[1]
91
92         try:
93             if cmd == 'getnum':
94                 out = server.getnum()
95             elif cmd == 'getkey':
96                 out = server.getkey()
97             elif cmd == 'getnewaddress':
98                 out = server.getnewaddress()
99             elif cmd == 'stop':
100                 out = server.stop()
101         except socket.error:
102             print "server not running"
103             sys.exit(1)
104         print out
105         sys.exit(0)
106
107     else:
108
109         wallet.set_path(wallet_path)
110         wallet.read()
111
112         def server_thread():
113             from SocketServer import ThreadingMixIn
114             from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer
115             server = SimpleJSONRPCServer(( host, port), requestHandler=authHandler)
116             server.register_function(get_new_address, 'getnewaddress')
117             server.register_function(get_num, 'getnum')
118             server.register_function(get_mpk, 'getkey')
119             server.register_function(do_stop, 'stop')
120             server.serve_forever()
121
122         thread.start_new_thread(server_thread, ())
123         while not stopping: time.sleep(0.1)
124
125
126
127