Source code for terra_sdk.client.lcd.wallet

from __future__ import annotations

from terra_sdk.key.key import Key, SignOptions

from .api.tx import CreateTxOptions, SignerOptions

__all__ = ["Wallet", "AsyncWallet"]

from ...core.tx import SignMode, Tx


class AsyncWallet:
    def __init__(self, lcd, key: Key):
        self.lcd = lcd
        self.key = key

    async def account_number(self) -> int:
        res = await self.lcd.auth.account_info(self.key.acc_address)
        return res.account_number

    async def sequence(self) -> int:
        res = await self.lcd.auth.account_info(self.key.acc_address)
        return res.sequence

    async def account_number_and_sequence(self) -> dict:
        res = await self.lcd.auth.account_info(self.key.acc_address)
        return {"account_number": res.account_number, "sequence": res.sequence}

    async def create_tx(self, options: CreateTxOptions) -> Tx:
        sigOpt = [
            SignerOptions(
                address=self.key.acc_address,
                sequence=options.sequence,
                public_key=self.key.public_key,
            )
        ]
        return await self.lcd.tx.create(sigOpt, options)

    async def create_and_sign_tx(self, options: CreateTxOptions) -> Tx:
        account_number = options.account_number
        sequence = options.sequence
        if account_number is None or sequence is None:
            res = await self.account_number_and_sequence()
            if account_number is None:
                account_number = res.get("account_number")
            if sequence is None:
                sequence = res.get("sequence")
        options.sequence = sequence
        options.account_number = account_number
        return self.key.sign_tx(
            tx=(await self.create_tx(options)),
            options=SignOptions(
                account_number=account_number,
                sequence=sequence,
                chain_id=self.lcd.chain_id,
                sign_mode=options.sign_mode
                if options.sign_mode
                else SignMode.SIGN_MODE_DIRECT,
            ),
        )


[docs]class Wallet: """Wraps around a :class:`Key` implementation and provides transaction building and signing functionality. It is recommended to create this object through :meth:`LCDClient.wallet()<terra_sdk.client.lcd.LCDClient.wallet>`.""" def __init__(self, lcd, key: Key): self.lcd = lcd self.key = key
[docs] def account_number(self) -> int: """Fetches account number for the account associated with the Key.""" res = self.lcd.auth.account_info(self.key.acc_address) return res.account_number
[docs] def sequence(self) -> int: """Fetches the sequence number for the account associated with the Key.""" res = self.lcd.auth.account_info(self.key.acc_address) return res.sequence
[docs] def account_number_and_sequence(self) -> dict: """Fetches both account and sequence number associated with the Key.""" res = self.lcd.auth.account_info(self.key.acc_address) return {"account_number": res.account_number, "sequence": res.sequence}
[docs] def create_tx(self, options: CreateTxOptions) -> Tx: """Builds an unsigned transaction object. The ``Wallet`` will first query the blockchain to fetch the latest ``account`` and ``sequence`` values for the account corresponding to its Key, unless the they are both provided. If no ``fee`` parameter is set, automatic fee estimation will be used (see `fee_estimation`). Args: options (CreateTxOptions): Options to create a tx Returns: Tx: unsigned transaction """ sigOpt = [ SignerOptions( address=self.key.acc_address, sequence=options.sequence, public_key=self.key.public_key, ) ] return self.lcd.tx.create(sigOpt, options)
[docs] def create_and_sign_tx(self, options: CreateTxOptions) -> Tx: """Creates and signs a :class:`Tx` object in a single step. This is the recommended method for preparing transaction for immediate signing and broadcastring. The transaction is generated exactly as :meth:`create_tx`. Args: options (CreateTxOptions): Options to create a tx Returns: Tx: signed transaction """ account_number = options.account_number sequence = options.sequence if account_number is None or sequence is None: res = self.account_number_and_sequence() if account_number is None: account_number = res.get("account_number") if sequence is None: sequence = res.get("sequence") options.sequence = sequence options.account_number = account_number return self.key.sign_tx( tx=self.create_tx(options), options=SignOptions( account_number=account_number, sequence=sequence, chain_id=self.lcd.chain_id, sign_mode=options.sign_mode if options.sign_mode else SignMode.SIGN_MODE_DIRECT, ), )