예제 #1
0
def restore(ctx):
    """ Restore a wallet from a mnemonic

    \b
    If you accidently deleted your wallet file or the file
    became corrupted, use this command to restore your wallet. You
    must have your 12 word phrase (mnemonic) that was displayed
    when you created your wallet.
    """
    # Stop daemon if it's running.
    d = None
    try:
        d = get_daemonizer()
    except OSError as e:
        pass

    if d:
        try:
            d.stop()
        except exceptions.DaemonizerError as e:
            click.echo("ERROR: Couldn't stop daemon: %s" % e)
            ctx.exit(code=4)

    # Check to see if the current wallet path exists
    if os.path.exists(ctx.obj['wallet_path']):
        if click.confirm("Wallet file already exists and may have a balance. Do you want to delete it?"):
            os.remove(ctx.obj['wallet_path'])
        else:
            click.echo("Not continuing.")
            ctx.exit(code=4)

    # Ask for mnemonic
    mnemonic = click.prompt("Please enter the wallet's 12 word mnemonic")

    # Sanity check the mnemonic
    m = Mnemonic(language='english')
    if not m.check(mnemonic):
        click.echo("ERROR: Invalid mnemonic.")
        ctx.exit(code=5)

    if click.confirm("Did the wallet have a passphrase?"):
        passphrase = get_passphrase()
    else:
        passphrase = ''

    # Try creating the wallet
    click.echo("\nRestoring...")
    wallet = Two1Wallet.import_from_mnemonic(
        data_provider=ctx.obj['data_provider'],
        mnemonic=mnemonic,
        passphrase=passphrase)

    wallet.to_file(ctx.obj['wallet_path'])
    if Two1Wallet.check_wallet_file(ctx.obj['wallet_path']):
        click.echo("Wallet successfully restored.")
    else:
        click.echo("Wallet not restored.")
        ctx.exit(code=6)
예제 #2
0
def create(ctx, account_type, testnet):
    """ Creates a new wallet
    """
    # txn_data_provider and related params come from the
    # global context.
    passphrase = ""
    if ctx.obj['passphrase']:
        # Let's prompt for a passphrase
        conf = "a"
        i = 0
        while passphrase != conf and i < 3:
            passphrase = getpass.getpass("Enter desired passphrase: ")
            conf = getpass.getpass("Confirm passphrase: ")
            i += 1

        if passphrase != conf:
            ctx.fail("Passphrases don't match. Quitting.")

    options = {"account_type": account_type,
               "passphrase": passphrase,
               "data_provider": ctx.obj['data_provider'],
               "testnet": testnet,
               "wallet_path": ctx.obj['wallet_path']}

    logger.info("Creating wallet with options: %r" % options)
    created = Two1Wallet.configure(options)

    if created:
        # Make sure it opens
        logger.info("Wallet created.")
        try:
            wallet = Two1Wallet(params_or_file=ctx.obj['wallet_path'],
                                data_provider=ctx.obj['data_provider'],
                                passphrase=passphrase)

            click.echo("Wallet successfully created!")

            adder = " (and your passphrase) " if passphrase else " "
            click.echo("Your wallet can be recovered using the following set of words (in that order).")
            click.echo("Please store them%ssafely." % adder)
            click.echo("\n%s\n" % wallet._orig_params['master_seed'])
        except Exception as e:
            logger.debug("Error opening created wallet: %s" % e)
            click.echo("Wallet was not created properly.")
            ctx.exit(code=3)
    else:
        ctx.fail("Wallet was not created.")
예제 #3
0
파일: cli.py 프로젝트: masonicGIT/two1
def startdaemon(ctx):
    """ Starts the daemon
    """
    # Check to sere if we're in a venv and don't do anything if we are
    if os.environ.get("VIRTUAL_ENV"):
        click.echo("Not starting daemon while inside a virtualenv. It can be manually started by doing 'walletd' and backgrounding the process.")
        return

    # Check if the wallet path exists
    if not Two1Wallet.check_wallet_file(ctx.obj['wallet_path']):
        click.echo("ERROR: Wallet does not exist! Not starting daemon.")
        ctx.exit(code=7)

    try:
        d = get_daemonizer()
    except OSError as e:
        logger.debug(str(e))
        click.echo("Error: %s" % e)
        return

    if d.started():
        click.echo("walletd already running.")
        return

    if not d.installed():
        if isinstance(ctx.obj['data_provider'], TwentyOneProvider):
            dpo = dict(provider='twentyone')
        elif isinstance(ctx.obj['data_provider'], ChainProvider):
            dp_params = ctx.obj['data_provider_params']
            dpo = dict(provider='chain',
                       api_key_id=dp_params['chain_api_key_id'],
                       api_key_secret=dp_params['chain_api_key_secret'])

        try:
            d.install(dpo)
        except exceptions.DaemonizerError as e:
            logger.debug(str(e))
            click.echo("Error: %s" % e)
            return

    msg = ""
    try:
        if d.start():
            msg = "walletd successfully started."
        else:
            msg = "walletd not started."
    except exceptions.DaemonizerError as e:
        msg = "Error: %s" % e

    logger.debug(msg)
    click.echo(msg)
예제 #4
0
def startdaemon(ctx):
    """ Starts the daemon
    """
    # Check to sere if we're in a venv and don't do anything if we are
    if os.environ.get("VIRTUAL_ENV"):
        click.echo("Not starting daemon while inside a virtualenv. It can be manually started by doing 'walletd' and backgrounding the process.")
        return

    # Check if the wallet path exists
    if not Two1Wallet.check_wallet_file(ctx.obj['wallet_path']):
        click.echo("ERROR: Wallet does not exist! Not starting daemon.")
        ctx.exit(code=7)

    try:
        d = get_daemonizer()
    except OSError as e:
        logger.debug(str(e))
        click.echo("Error: %s" % e)
        return

    if d.started():
        click.echo("walletd already running.")
        return

    if not d.installed():
        if isinstance(ctx.obj['data_provider'], TwentyOneProvider):
            dpo = dict(provider='twentyone')

        try:
            d.install(dpo)
        except exceptions.DaemonizerError as e:
            logger.debug(str(e))
            click.echo("Error: %s" % e)
            return

    msg = ""
    try:
        if d.start():
            msg = "walletd successfully started."
        else:
            msg = "walletd not started."
    except exceptions.DaemonizerError as e:
        msg = "Error: %s" % e

    logger.debug(msg)
    click.echo(msg)
예제 #5
0
def load_wallet(wallet_path, data_provider, passphrase):
    """ Loads a wallet.

    Args:
        wallet_path (str): The path to the wallet to be loaded.
        data_provider (BaseProvider): A blockchain data provider object.
        passphrase (str): Passphrase to use to unlock the wallet if the
            wallet requires unlocking.
    """
    global wallet

    try:
        logger.debug("In load_wallet...")
        logger.debug("\twallet_path = %s" % wallet_path)
        logger.debug("\tdata_provider = %r" % data_provider)
        logger.debug("\tpassphrase = %r" % bool(passphrase))
        wallet['obj'] = Two1Wallet(params_or_file=wallet_path,
                                   data_provider=data_provider,
                                   passphrase=passphrase)
        wallet['locked'] = False
    except Exception as e:
        raise WalletNotLoadedError("Wallet loading failed: %s" % e)
예제 #6
0
파일: daemon.py 프로젝트: SamvitJ/21BC-lib
def main(ctx, wallet_path, blockchain_data_provider,
         insight_url, insight_api_path,
         data_update_interval, debug):
    """ Two1 Wallet daemon
    """
    global DEF_WALLET_UPDATE_INTERVAL

    wp = Path(wallet_path)
    # Initialize some logging handlers
    ch = logging.handlers.TimedRotatingFileHandler(wp.dirname().joinpath("walletd.log"),
                                                   when='midnight',
                                                   backupCount=5)
    ch_formatter = logging.Formatter(
        '%(asctime)s %(levelname)s %(name)-8s: %(message)s')
    ch.setFormatter(ch_formatter)
    ch.setLevel(logging.DEBUG if debug else logging.INFO)
    logging.getLogger().addHandler(ch)

    console = logging.StreamHandler()
    console.setLevel(logging.CRITICAL)
    logging.getLogger().addHandler(console)

    logging.getLogger().setLevel(logging.DEBUG)

    global wallet

    wallet['path'] = wallet_path
    if not Two1Wallet.check_wallet_file(wallet['path']):
        logger.critical("Wallet file does not exist or have the right parameters.")
        sys.exit(-1)

    wallet['data_provider'] = ctx.obj['data_provider']
    if data_update_interval is not None:
        DEF_WALLET_UPDATE_INTERVAL = data_update_interval
        wallet['update_info']['interval'] = data_update_interval

    logger.info("Starting daemon for wallet %s" % wallet_path)
    logger.info("Blockchain data provider: %s" %
                ctx.obj['data_provider'].__class__.__name__)
    logger.info("Update interval: %ds" % data_update_interval)

    # Check whether the wallet is locked
    if Two1Wallet.is_locked(wallet_path):
        wallet['locked'] = True
        logger.info("Wallet is locked.")
    else:
        logger.info("Wallet unlocked. Loading ...")
        try:
            load_wallet(wallet_path=wallet_path,
                        data_provider=ctx.obj['data_provider'],
                        passphrase="")
            logger.info("... loading complete.")
        except WalletNotLoadedError as e:
            logger.error(str(e))
            logger.info("Terminating.")
            sys.exit(-1)

    create_daemon_methods()

    # Setup a signal handler
    signal.signal(signal.SIGINT, sig_handler)
    signal.signal(signal.SIGTERM, sig_handler)
    server_thread = threading.Thread(target=rpc_server.serve_forever,
                                     daemon=True)
    update_thread = threading.Thread(target=data_updater,
                                     daemon=True)
    server_thread.start()
    update_thread.start()
    logger.info("Daemon started.")
    server_thread.join()

    rpc_server.server_close()

    try:
        _check_wallet_loaded()
        wallet['obj'].sync_wallet_file(force_cache_write=True)
    except:
        pass

    sys.exit(0)
예제 #7
0
파일: config.py 프로젝트: SamvitJ/21BC-lib
    def __init__(self, config_file=TWO1_CONFIG_FILE, config=None, create_wallet=True):
        if not os.path.exists(TWO1_USER_FOLDER):
            os.makedirs(TWO1_USER_FOLDER)
        self.file = path(config_file).expand().abspath()
        self.dir = self.file.parent
        self.defaults = {}  # TODO: Rename this var. Those are not the defaults but the actual values.
        self.json_output = False # output in json
        #  actual config.
        self.load()
        # override config variables
        if config:
            if self.verbose:
                self.vlog("Applied manual config.")

            for k, v in config:
                self.defaults[k] = v
                if self.verbose:
                    self.vlog("\t{}={}".format(k, v))

        # add wallet object
        if self.defaults.get('testwallet', None) == 'y':
            self.wallet = test_wallet.TestWallet()
        elif create_wallet:
            dp = TwentyOneProvider(TWO1_PROVIDER_HOST)

            wallet_path = self.defaults.get('wallet_path')

            if not Two1Wallet.check_wallet_file(wallet_path):
                # configure wallet with default options
                click.pause(UxString.create_wallet)

                wallet_options = {
                    'data_provider': dp,
                    'wallet_path': wallet_path
                }

                if not Two1Wallet.configure(wallet_options):
                    raise click.ClickException(UxString.Error.create_wallet_failed)

                # Display the wallet mnemonic and tell user to back it up.
                # Read the wallet JSON file and extract it.
                with open(wallet_path, 'r') as f:
                    wallet_config = json.load(f)
                    mnemonic = wallet_config['master_seed']

                click.pause(UxString.create_wallet_done % (mnemonic))

            # Start the daemon, if:
            # 1. It's not already started
            # 2. It's using the default wallet path
            # 3. We're not in a virtualenv
            try:
                d = daemonizer.get_daemonizer()

                if Two1Wallet.is_configured() and \
                   wallet_path == Two1Wallet.DEFAULT_WALLET_PATH and \
                   not os.environ.get("VIRTUAL_ENV") and \
                   not d.started():
                    d.start()
                    if d.started():
                        click.echo(UxString.wallet_daemon_started)
            except (OSError, DaemonizerError):
                pass

            self.wallet = Wallet(wallet_path=wallet_path,
                                 data_provider=dp)
            self.machine_auth = MachineAuthWallet(self.wallet)
            self.channel_client = PaymentChannelClient(self.wallet)
        else:
            # This branch is hit when '21 help' or '21 update' is invoked
            pass
예제 #8
0
    def __init__(self,
                 config_file=TWO1_CONFIG_FILE,
                 config=None,
                 create_wallet=True):
        if not os.path.exists(TWO1_USER_FOLDER):
            os.makedirs(TWO1_USER_FOLDER)
        self.file = path(config_file).expand().abspath()
        self.dir = self.file.parent
        self.defaults = {
        }  # TODO: Rename this var. Those are not the defaults but the actual values.
        self.json_output = False  # output in json
        #  actual config.
        self.load()
        # override config variables
        if config:
            if self.verbose:
                self.vlog("Applied manual config.")

            for k, v in config:
                self.defaults[k] = v
                if self.verbose:
                    self.vlog("\t{}={}".format(k, v))

        # add wallet object
        if self.defaults.get('testwallet', None) == 'y':
            self.wallet = test_wallet.TestWallet()
        elif create_wallet:
            dp = TwentyOneProvider(TWO1_PROVIDER_HOST)

            wallet_path = self.defaults.get('wallet_path')

            if not Two1Wallet.check_wallet_file(wallet_path):
                # configure wallet with default options
                click.pause(UxString.create_wallet)

                wallet_options = {
                    'data_provider': dp,
                    'wallet_path': wallet_path
                }

                if not Two1Wallet.configure(wallet_options):
                    raise click.ClickException(
                        UxString.Error.create_wallet_failed)

                # Display the wallet mnemonic and tell user to back it up.
                # Read the wallet JSON file and extract it.
                with open(wallet_path, 'r') as f:
                    wallet_config = json.load(f)
                    mnemonic = wallet_config['master_seed']

                click.pause(UxString.create_wallet_done % (mnemonic))

            # Start the daemon, if:
            # 1. It's not already started
            # 2. It's using the default wallet path
            # 3. We're not in a virtualenv
            try:
                d = daemonizer.get_daemonizer()

                if Two1Wallet.is_configured() and \
                   wallet_path == Two1Wallet.DEFAULT_WALLET_PATH and \
                   not os.environ.get("VIRTUAL_ENV") and \
                   not d.started():
                    d.start()
                    if d.started():
                        click.echo(UxString.wallet_daemon_started)
            except (OSError, DaemonizerError):
                pass

            self.wallet = Wallet(wallet_path=wallet_path, data_provider=dp)
            self.machine_auth = MachineAuthWallet(self.wallet)
            self.channel_client = PaymentChannelClient(self.wallet)
        else:
            # This branch is hit when '21 help' or '21 update' is invoked
            pass
예제 #9
0
def main(ctx, wallet_path, passphrase,
         blockchain_data_provider,
         insight_url, insight_api_path,
         debug):
    """ Command-line Interface for the Two1 Wallet
    """
    wp = Path(wallet_path)

    # Initialize some logging handlers
    ch = logging.StreamHandler()
    ch_formatter = logging.Formatter(
        '%(levelname)s: %(message)s')
    ch.setFormatter(ch_formatter)

    if not os.path.exists(wp.dirname()):
        os.makedirs(wp.dirname())
    fh = logging.handlers.TimedRotatingFileHandler(wp.dirname().joinpath("wallet_cli.log"),
                                                   when='midnight',
                                                   backupCount=5)
    fh_formatter = logging.Formatter(
        '%(asctime)s %(levelname)s: %(message)s')
    fh.setFormatter(fh_formatter)

    logger.addHandler(ch)
    logger.addHandler(fh)

    fh.setLevel(logging.DEBUG if debug else logging.INFO)
    ch.setLevel(logging.DEBUG if debug else logging.WARNING)
    logger.setLevel(logging.DEBUG if debug else logging.INFO)

    logger.info("Wallet client started.")

    if ctx.obj is None:
        ctx.obj = {}

    ctx.obj['wallet_path'] = wallet_path
    ctx.obj['passphrase'] = passphrase

    if ctx.invoked_subcommand not in ['create', 'restore',
                                      'startdaemon', 'stopdaemon',
                                      'uninstalldaemon']:
        # Check that the wallet path exists
        if not Two1Wallet.check_wallet_file(ctx.obj['wallet_path']):
            click.echo("ERROR: Wallet file does not exist or is corrupt.")
            ctx.exit(code=7)

        p = get_passphrase() if passphrase else ''

        try:
            logger.info("Loading wallet %s ..." % (wp))
            ctx.obj['wallet'] = Wallet(wallet_path=wallet_path,
                                       data_provider=ctx.obj['data_provider'],
                                       passphrase=p)
            logger.info("... loading complete.")
        except exceptions.PassphraseError as e:
            click.echo(str(e))
            ctx.exit(code=1)
        except (TypeError, ValueError) as e:
            logger.error("Internal wallet error. Please report this as a bug.")
            logger.debug("".join(traceback.format_tb(e.__traceback__)))
            ctx.exit(code=2)

        def _on_close():
            try:
                ctx.obj['wallet'].sync_wallet_file()
            except:
                pass

        ctx.call_on_close(_on_close)
예제 #10
0
def main(ctx, wallet_path, blockchain_data_provider, insight_url,
         insight_api_path, data_update_interval, debug):
    """ Two1 Wallet daemon
    """
    global DEF_WALLET_UPDATE_INTERVAL

    wp = Path(wallet_path)
    # Initialize some logging handlers
    ch = logging.handlers.TimedRotatingFileHandler(
        wp.dirname().joinpath("walletd.log"), when='midnight', backupCount=5)
    ch_formatter = logging.Formatter(
        '%(asctime)s %(levelname)s %(name)-8s: %(message)s')
    ch.setFormatter(ch_formatter)
    ch.setLevel(logging.DEBUG if debug else logging.INFO)
    logging.getLogger().addHandler(ch)

    console = logging.StreamHandler()
    console.setLevel(logging.CRITICAL)
    logging.getLogger().addHandler(console)

    logging.getLogger().setLevel(logging.DEBUG)

    global wallet

    wallet['path'] = wallet_path
    if not Two1Wallet.check_wallet_file(wallet['path']):
        logger.critical(
            "Wallet file does not exist or have the right parameters.")
        sys.exit(-1)

    wallet['data_provider'] = ctx.obj['data_provider']
    if data_update_interval is not None:
        DEF_WALLET_UPDATE_INTERVAL = data_update_interval
        wallet['update_info']['interval'] = data_update_interval

    logger.info("Starting daemon for wallet %s" % wallet_path)
    logger.info("Blockchain data provider: %s" %
                ctx.obj['data_provider'].__class__.__name__)
    logger.info("Update interval: %ds" % data_update_interval)

    # Check whether the wallet is locked
    if Two1Wallet.is_locked(wallet_path):
        wallet['locked'] = True
        logger.info("Wallet is locked.")
    else:
        logger.info("Wallet unlocked. Loading ...")
        try:
            load_wallet(wallet_path=wallet_path,
                        data_provider=ctx.obj['data_provider'],
                        passphrase="")
            logger.info("... loading complete.")
        except WalletNotLoadedError as e:
            logger.error(str(e))
            logger.info("Terminating.")
            sys.exit(-1)

    create_daemon_methods()

    # Setup a signal handler
    signal.signal(signal.SIGINT, sig_handler)
    signal.signal(signal.SIGTERM, sig_handler)
    server_thread = threading.Thread(target=rpc_server.serve_forever,
                                     daemon=True)
    update_thread = threading.Thread(target=data_updater, daemon=True)
    server_thread.start()
    update_thread.start()
    logger.info("Daemon started.")
    server_thread.join()

    rpc_server.server_close()

    try:
        _check_wallet_loaded()
        wallet['obj'].sync_wallet_file(force_cache_write=True)
    except:
        pass

    sys.exit(0)