Пример #1
0
    async def create(self, seed: str) -> 'Wallet':
        """
        Create wallet as configured and store DID.

        Raise ExtantWallet if wallet already exists on current name.

        :param seed: seed
        :return: current object
        """

        LOGGER.debug('Wallet.create >>> seed: [SEED]')

        try:
            await wallet.create_wallet(
                config=json.dumps(self.config),
                credentials=json.dumps(self.access_creds
                                       or Wallet.DEFAULT_ACCESS_CREDS))
            LOGGER.info('Created wallet %s', self.name)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletAlreadyExistsError:
                LOGGER.info('Wallet %s already exists', self.name)
                raise ExtantWallet('Wallet {} already exists'.format(
                    self.name))
            else:
                LOGGER.debug(
                    'Wallet.create <!< indy error code %s on creation of wallet %s',
                    x_indy.error_code, self.name)
                raise

        self._handle = await wallet.open_wallet(
            json.dumps(self.config),
            json.dumps(self.access_creds or Wallet.DEFAULT_ACCESS_CREDS))
        LOGGER.info('Opened wallet %s on handle %s', self.name, self.handle)

        try:
            (self._did, self.verkey) = await did.create_and_store_my_did(
                self.handle, json.dumps({'seed': seed}))
            LOGGER.debug('Wallet %s stored new DID %s, verkey %s from seed',
                         self.name, self.did, self.verkey)
            await did.set_did_metadata(
                self.handle, self.did,
                json.dumps({
                    'anchor': True,
                    'since': int(time())
                }))
            LOGGER.info('Wallet %s set seed hash metadata for DID %s',
                        self.name, self.did)
        finally:
            await wallet.close_wallet(
                self.handle)  # bypass self.close() in case auto-remove set
            self._handle = None

        LOGGER.debug('Wallet.create <<<')
        return self
Пример #2
0
    async def create(self,
                     config: dict = None,
                     access: str = None,
                     replace: bool = False) -> Wallet:
        """
        Create wallet on input name with given configuration and access credential value.

        Raise ExtantWallet if wallet on input name exists already and replace parameter is False.
        Raise BadAccess on replacement for bad access credentials value.

        FAIR WARNING: specifying replace=True attempts to remove any matching wallet before proceeding; to
        succeed, the existing wallet must use the same access credentials that the input configuration has.

        :param config: configuration data for both indy-sdk and VON anchor wallet:

            - 'name' or 'id': wallet name
            - 'storage_type': storage type
            - 'freshness_time': freshness time
            - 'did': (optional) DID to use
            - 'seed': (optional) seed to use
            - 'auto_create': whether to create the wallet on first open (persists past close, can work with auto_remove)
            - 'auto_remove': whether to remove the wallet on next close
            - 'link_secret_label': (optional) link secret label to use to create link secret

        :param access: indy wallet access credential ('key') value, if different than default
        :param replace: whether to replace old wallet if it exists
        :return: wallet created
        """

        LOGGER.debug(
            'WalletManager.create >>> config %s, access %s, replace %s',
            config, access, replace)

        assert {'name', 'id'} & {k for k in config}
        wallet_name = config.get('name', config.get('id'))
        if replace:
            von_wallet = self.get(config, access)
            if not await von_wallet.remove():
                LOGGER.debug(
                    'WalletManager.create <!< Failed to remove wallet %s for replacement',
                    wallet_name)
                raise ExtantWallet(
                    'Failed to remove wallet {} for replacement'.format(
                        wallet_name))

        indy_config = self._config2indy(config)
        von_config = self._config2von(config, access)
        rv = Wallet(indy_config, von_config)
        await rv.create()
        LOGGER.debug('WalletManager.create <<< %s', rv)
        return rv
Пример #3
0
    async def create(self) -> None:
        """
        Persist the wallet. Raise ExtantWallet if it already exists.

        Actuators should prefer WalletManager.create() to calling this method directly - the wallet manager
        filters wallet configuration through preset defaults.
        """

        LOGGER.debug('Wallet.create >>>')

        try:
            await wallet.create_wallet(
                config=json.dumps(self.config),
                credentials=json.dumps(self.access_creds))
            LOGGER.info('Created wallet %s', self.name)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletAlreadyExistsError:
                LOGGER.debug('Wallet.create <!< Wallet %s already exists', self.name)
                raise ExtantWallet('Wallet {} already exists'.format(self.name))
            LOGGER.debug(
                'Wallet.create <!< indy error code %s on creation of wallet %s',
                x_indy.error_code,
                self.name)
            raise

        auto_remove = self.auto_remove
        self.auto_remove = False  # defer past this creation process
        async with self:
            did_info = await self.create_local_did(
                self._von_config.get('seed', None),
                self._von_config.get('did', None),
                {'anchor': True})
            self.did = did_info.did
            self.verkey = did_info.verkey
            if 'link_secret_label' in self._von_config:
                await self.create_link_secret(self._von_config['link_secret_label'])
        self.auto_remove = auto_remove

        LOGGER.debug('Wallet.create <<<')
Пример #4
0
async def setnym(ini_path: str) -> int:
    """
    Set configuration. Open pool, trustee anchor, and wallet of anchor whose nym to send.
    Register exit hooks to close pool and trustee anchor.

    Engage trustee anchor to send nym for VON anchor, if it differs on the ledger from configuration.

    :param ini_path: path to configuration file
    :return: 0 for OK, 1 for failure
    """

    config = inis2dict(ini_path)
    if config['Trustee Anchor']['name'] == config['VON Anchor']['name']:
        raise ExtantWallet(
            'Wallet names must differ between VON Anchor and Trustee Anchor')

    cfg_van_role = config['VON Anchor'].get(
        'role', None) or None  # nudge empty value from '' to None
    if not ok_role(cfg_van_role):
        raise BadRole('Configured role {} is not valid'.format(cfg_van_role))

    pool_data = NodePoolData(
        config['Node Pool']['name'],
        config['Node Pool'].get('genesis.txn.path', None) or None)

    an_data = {
        'tan':
        AnchorData(
            Role.TRUSTEE, config['Trustee Anchor']['name'],
            config['Trustee Anchor'].get('seed', None) or None,
            config['Trustee Anchor'].get('did', None) or None,
            config['Trustee Anchor'].get('wallet.create',
                                         '0').lower() in ['1', 'true', 'yes'],
            config['Trustee Anchor'].get('wallet.type', None) or None,
            config['Trustee Anchor'].get('wallet.access', None) or None),
        'van':
        AnchorData(
            Role.get(cfg_van_role), config['VON Anchor']['name'],
            config['VON Anchor'].get('seed', None) or None,
            config['VON Anchor'].get('did', None) or None,
            config['VON Anchor'].get('wallet.create',
                                     '0').lower() in ['1', 'true', 'yes'],
            config['VON Anchor'].get('wallet.type', None) or None,
            config['VON Anchor'].get('wallet.access', None) or None)
    }

    an_wallet = await _set_wallets(an_data)

    p_mgr = NodePoolManager()
    if pool_data.name not in await p_mgr.list():
        if pool_data.genesis_txn_path:
            await p_mgr.add_config(pool_data.name, pool_data.genesis_txn_path)
        else:
            raise AbsentPool(
                'Node pool {} has no ledger configuration, but {} specifies no genesis txn path'
                .format(pool_data.name, ini_path))

    async with an_wallet['tan'] as w_tan, (an_wallet['van']) as w_van, (
            p_mgr.get(pool_data.name)) as pool, (TrusteeAnchor(
                w_tan, pool)) as tan, (NominalAnchor(w_van, pool)) as van:

        send_verkey = van.verkey
        try:
            nym_role = await tan.get_nym_role(van.did)
            if an_data['van'].role == nym_role:
                return 0  # ledger is as per configuration
            send_verkey = None  # only owner can touch verkey
            if nym_role != Role.USER:  # only remove role when it is not already None on the ledger
                await tan.send_nym(van.did, send_verkey, van.wallet.name,
                                   Role.ROLE_REMOVE)
        except AbsentNym:
            pass  # cryptonym not there yet, fall through

        await tan.send_nym(van.did, send_verkey, van.wallet.name,
                           an_data['van'].role)

    return 0
Пример #5
0
async def setnym(ini_path: str) -> int:
    """
    Set configuration. Open pool, trustee anchor, and wallet of anchor whose nym to send.
    Register exit hooks to close pool and trustee anchor.

    Engage trustee anchor to send nym for VON anchor, if it differs on the ledger from configuration.

    :param ini_path: path to configuration file
    :return: 0 for OK, 1 for failure
    """

    config = inis2dict(ini_path)
    cfg_van_role = config['VON Anchor'].get(
        'role', None) or None  # nudge empty value from '' to None
    if not ok_role(cfg_van_role):
        raise BadRole('Configured role {} is not valid'.format(cfg_van_role))

    if config['Trustee Anchor']['wallet.name'] == config['VON Anchor'][
            'wallet.name']:
        raise ExtantWallet(
            'Wallet names must differ between VON Anchor and Trustee Anchor')

    pool_data = NodePoolData(
        config['Node Pool']['name'],
        config['Node Pool'].get('genesis.txn.path', None) or None)
    an_data = {
        'tan':
        AnchorData(Role.TRUSTEE, config['Trustee Anchor'].get('seed', None)
                   or None, config['Trustee Anchor']['wallet.name'],
                   config['Trustee Anchor'].get('wallet.type', None) or None,
                   config['Trustee Anchor'].get('wallet.key', None) or None),
        'van':
        AnchorData(Role.get(cfg_van_role),
                   config['VON Anchor'].get('seed', None) or None,
                   config['VON Anchor']['wallet.name'],
                   config['VON Anchor'].get('wallet.type', None) or None,
                   config['VON Anchor'].get('wallet.key', None) or None)
    }
    an_wallet = {
        an: Wallet(an_data[an].wallet_name, an_data[an].wallet_type, None,
                   {'key': an_data[an].wallet_key}
                   if an_data[an].wallet_key else None)
        for an in an_data
    }

    for anchor in an_data:  # create wallet if seed configured, silently continue if extant
        if an_data[anchor].seed:
            try:
                await an_wallet[anchor].create(an_data[anchor].seed)
            except ExtantWallet:
                pass

    manager = NodePoolManager()
    if pool_data.name not in await manager.list():
        if pool_data.genesis_txn_path:
            await manager.add_config(pool_data.name,
                                     pool_data.genesis_txn_path)
        else:
            raise AbsentPool(
                'Node pool {} has no ledger configuration, but {} specifies no genesis txn path'
                .format(pool_data.name, ini_path))

    async with an_wallet['tan'] as w_tan, (an_wallet['van']) as w_van, (
            manager.get(pool_data.name)) as pool, (TrusteeAnchor(
                w_tan, pool)) as tan, (NominalAnchor(w_van, pool)) as van:

        send_verkey = van.verkey
        try:
            nym_role = await tan.get_nym_role(van.did)
            if an_data['van'].role == nym_role:
                return 0  # ledger is as per configuration
            send_verkey = None  # only owner can touch verkey
            await tan.send_nym(van.did, send_verkey, van.wallet.name,
                               Role.ROLE_REMOVE)
        except AbsentNym:
            pass  # cryptonym not there yet, fall through

        await tan.send_nym(van.did, send_verkey, van.wallet.name,
                           an_data['van'].role)

    return 0