Beispiel #1
0
    async def _sign_submit(self, req_json: str) -> str:
        """
        Sign and submit (json) request to ledger; return (json) result.

        Raise ClosedPool if pool is not yet open, CorruptWallet if existing wallet's
        pool is no longer extant, or BadLedgerTxn on any other failure.

        :param req_json: json of request to sign and submit
        :return: json response
        """

        LOGGER.debug('_BaseAgent._sign_submit >>> json: %s', req_json)

        if not self.pool.handle:
            LOGGER.debug('_BaseAgent._submit <!< closed pool %s',
                         self.pool.name)
            raise ClosedPool('Cannot submit request to closed pool {}'.format(
                self.pool.name))

        try:
            rv_json = await ledger.sign_and_submit_request(
                self.pool.handle, self.wallet.handle, self.did, req_json)
            await asyncio.sleep(0)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletIncompatiblePoolError:
                LOGGER.debug(
                    '_BaseAgent._sign_submit: <!< Corrupt wallet %s is not compatible with pool %s',
                    self.wallet.name, self.pool.name)
                raise CorruptWallet(
                    'Corrupt wallet {} is not compatible with pool {}'.format(
                        self.wallet.name, self.pool.name))
            else:
                LOGGER.debug(
                    '_BaseAgent._sign_submit: <!<  cannot sign/submit request for ledger: indy error code %s',
                    self.wallet.name)
                raise BadLedgerTxn(
                    'Cannot sign/submit request for ledger: indy error code {}'
                    .format(x_indy.error_code))

        resp = json.loads(rv_json)
        if ('op' in resp) and (resp['op'] in ('REQNACK', 'REJECT')):
            LOGGER.debug(
                '_BaseAgent._sign_submit: ledger rejected request: %s',
                resp['reason'])
            raise BadLedgerTxn(
                'Ledger rejected transaction request: {}'.format(
                    resp['reason']))

        if 'reason' in resp and 'result' in resp and resp['result'].get(
                'seqNo', None) is None:
            LOGGER.debug(
                '_BaseAgent._sign_submit: <!< response indicates no transaction: %s',
                resp['reason'])
            raise BadLedgerTxn('Response indicates no transaction: {}'.format(
                resp['reason']))

        LOGGER.debug('_BaseAgent._sign_submit <<< %s', rv_json)
        return rv_json
Beispiel #2
0
    async def open(self) -> 'Wallet':
        """
        Explicit entry. Open wallet as configured, for later closure via close().
        For use when keeping wallet open across multiple calls.

        Raise ClosedPool if pool is closed, or any IndyError causing failure to open
        wallet (create, open, store DID, close).

        :return: current object
        """

        logger = logging.getLogger(__name__)
        logger.debug('Wallet.open: >>>')

        if not self.pool.handle:
            logger.debug(
                'Wallet.open: <!< closed pool {} on opening wallet {}'.format(
                    self.pool.name, self.name))
            raise ClosedPool('Open pool {} before opening wallet {}'.format(
                self.pool.name, self.name))

        if not self.created:
            logger.debug('Wallet.open: <!< absent wallet {}'.format(self.name))
            raise AbsentWallet('Cannot open wallet {}: not created'.format(
                self.name))

        try:
            self._handle = await wallet.open_wallet(
                self.name,
                json.dumps(self.cfg) if self.cfg else None,
                json.dumps(self.creds) if self.creds else None)
            logger.info('Opened wallet {} on handle {}'.format(
                self.name, self.handle))
        except IndyError as e:
            if e.error_code == ErrorCode.WalletAlreadyOpenedError:
                logger.info('Wallet already opened: {}'.format(self.name))
            else:
                logger.debug('Wallet.open: <!< indy error code {}'.format(
                    self.e.error_code))
                raise

        self._did = await self._seed2did()
        self._verkey = await did.key_for_did(self.pool.handle, self.handle,
                                             self.did)
        logger.info('Wallet {} got verkey {} for existing DID {}'.format(
            self.name, self.verkey, self.did))

        logger.debug('Wallet.open: <<<')
        return self
Beispiel #3
0
    async def _submit(self, req_json: str) -> str:
        """
        Submit (json) request to ledger; return (json) result.

        Raise ClosedPool if pool is not yet open, or BadLedgerTxn on failure.

        :param req_json: json of request to sign and submit
        :return: json response
        """

        LOGGER.debug('_BaseAgent._submit >>> json: %s', req_json)

        if not self.pool.handle:
            LOGGER.debug('_BaseAgent._submit <!< closed pool %s',
                         self.pool.name)
            raise ClosedPool('Cannot submit request to closed pool {}'.format(
                self.pool.name))

        rv_json = await ledger.submit_request(self.pool.handle, req_json)
        await asyncio.sleep(0)

        resp = json.loads(rv_json)
        if ('op' in resp) and (resp['op'] in ('REQNACK', 'REJECT')):
            LOGGER.debug('_BaseAgent._submit: <!< ledger rejected request: %s',
                         resp['reason'])
            raise BadLedgerTxn(
                'Ledger rejected transaction request: {}'.format(
                    resp['reason']))

        if 'reason' in resp and 'result' in resp and resp['result'].get(
                'seqNo', None) is None:
            LOGGER.debug(
                '_BaseAgent._submit: <!< response indicates no transaction: %s',
                resp['reason'])
            raise BadLedgerTxn('Response indicates no transaction: {}'.format(
                resp['reason']))

        LOGGER.debug('_BaseAgent._submit <<< %s', rv_json)
        return rv_json
Beispiel #4
0
    async def create(self) -> 'Wallet':
        """
        Create wallet as configured and store DID, or else re-use any existing configuration.
        Operation sequence create/store-DID/close does not auto-remove the wallet on close,
        even if so configured.

        Raise ClosedPool if pool is closed, or any IndyError causing failure to operate on
        wallet (create, open, store DID, close).

        :return: current object
        """

        logger = logging.getLogger(__name__)
        logger.debug('Wallet.create: >>>')

        if not self.pool.handle:
            logger.debug(
                'Wallet.create: <!< closed pool {} on creating wallet {}'.
                format(self.pool.name, self.name))
            raise ClosedPool('Open pool {} before creating wallet {}'.format(
                self.pool.name, self.name))

        try:
            await wallet.create_wallet(
                pool_name=self.pool.name,
                name=self.name,
                xtype=self.xtype,
                config=json.dumps(self.cfg) if self.cfg else None,
                credentials=json.dumps(self.creds) if self.creds else None)
            self._created = True
            logger.info('Created wallet {} on pool {}:{}'.format(
                self.name, self.pool.handle, self.pool.name))
        except IndyError as e:
            if e.error_code == ErrorCode.WalletAlreadyExistsError:
                logger.info('Wallet already exists: {}'.format(self.name))
            else:
                logger.debug('Wallet.create: <!< indy error code {}'.format(
                    self.e.error_code))
                raise

        try:
            self._handle = await wallet.open_wallet(
                self.name,
                json.dumps(self.cfg) if self.cfg else None,
                json.dumps(self.creds) if self.creds else None)
            logger.info('Opened wallet {} on handle {}'.format(
                self.name, self.handle))
        except IndyError as e:
            if e.error_code == ErrorCode.WalletAlreadyOpenedError:
                logger.info('Wallet already opened: {}'.format(self.name))
            else:
                logger.debug('Wallet.open: <!< indy error code {}'.format(
                    self.e.error_code))
                raise

        if self._created:
            (self._did, self._verkey) = await did.create_and_store_my_did(
                self.handle, json.dumps({'seed': self._seed}))
            logger.debug(
                'Wallet {} stored new DID {}, verkey {} from seed'.format(
                    self.name, self.did, self.verkey))
        else:
            self._created = True
            self._did = await self._seed2did()
            self._verkey = await did.key_for_did(self.pool.handle, self.handle,
                                                 self.did)
            logger.info('Wallet {} got verkey {} for existing DID {}'.format(
                self.name, self.verkey, self.did))

        await wallet.close_wallet(self.handle)

        logger.debug('Wallet.create: <<<')
        return self