forked from Coldcard/ckbunker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
116 lines (87 loc) · 3.29 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
#
# Copyright 2020 by Coinkite Inc. This file is covered by license found in COPYING-CC.
#
# Main entry-point for project.
#
# To use this, install with:
#
# pip install --editable .
#
# That will create the command "ckbunker" in your path. Use it!
#
import os, sys, click, hid, asyncio, logging
from pprint import pformat, pprint
global force_serial
force_serial = None
from ckcc.protocol import CCProtocolPacker
from ckcc.protocol import CCProtoError, CCUserRefused, CCBusyError
from ckcc.client import ColdcardDevice, COINKITE_VID, CKCC_PID
# Options we want for all commands
@click.group()
@click.option('--serial', '-s', default=None, metavar="HEX",
help="Operate on specific unit (default: first found)")
def main(serial):
global force_serial
force_serial = serial
@main.command('list')
def _list():
"List all attached Coldcard devices"
count = 0
for info in hid.enumerate(COINKITE_VID, CKCC_PID):
#click.echo("\nColdcard {serial_number}:\n{nice}".format(
# nice=pformat(info, indent=4)[1:-1], **info))
click.echo(info['serial_number'])
count += 1
if not count:
click.echo("(none found)")
@main.command('example')
def example_config():
"Show an example config file, using the default values"
from persist import Settings
click.echo(Settings.make_sample())
@main.command('run')
@click.option('--local', '-l', default=False, is_flag=True,
help="Don't enable Tor (onion) access: just be on localhost")
@click.option('--psbt', '-f', metavar="filename.psbt",
help="Preload first PSBT to be signed", default=None,
type=click.File('rb'))
@click.option('--config-file', '-c', type=click.File('rt'), required=False)
def start_service(local=False, config_file=None, psbt=None):
"Start the CKBunker for normal operation"
if psbt:
psbt = psbt.read()
asyncio.run(startup(False, local, config_file, psbt), debug=True)
@main.command('setup')
@click.option('--local', '-l', default=False, is_flag=True,
help="Don't enable Tor (onion) access: just be on localhost")
@click.option('--config-file', '-c', type=click.File('rt'), required=False)
def setup_hsm(local=False, config_file=None):
"Configure your transaction signing policy, install it and then operate."
asyncio.run(startup(True, local, config_file, None), debug=True)
async def startup(setup_mode, force_local_mode, config_file, first_psbt):
# All startup/operation code
loop = asyncio.get_running_loop()
if loop.get_debug():
# quiet noise about slow stuff
loop.slow_callback_duration = 10
from utils import setup_logging
setup_logging()
from persist import Settings
Settings.startup(config_file)
aws = []
# copy some args into status area
from status import STATUS
STATUS.force_local_mode = force_local_mode
STATUS.setup_mode = setup_mode
# preload the contents of a PSBT
if first_psbt:
STATUS.import_psbt(first_psbt)
from torsion import TOR
aws.append(TOR.startup())
from conn import Connection
aws.append(Connection(force_serial).run())
import webapp
aws.append(webapp.startup(setup_mode))
await asyncio.gather(*aws)
# EOF