Skip to content

Account

The account class can be instantiated through a seed or a private key. If nothing is provided it will create a new keyring and the params to work with the cosmos chain

Note
  • You can't provide a seed_phrase and aprivate_key
  • A readble method behaves is the getter for a Attribute (Example: hrp = account.hrp)
  • A writable method is the setter for the Attribute (Example: account.hrp = "cosmos")
  • A method can be setter and getter at the same time. The Parameters description always refers to the setter while the Returns section belongs to the getter

Parameters:

Name Type Description Default
seed_phrase str

Seed phrase to derive private keys from

None
private_key str

Private key to instantiate the Account

None
next_sequence int

Sequence which will be used for transactions signed with this Account

None
account_number int

On-chain account number

None
slip44 int

Slip44 value

118
hrp str

Address Prefix

'cosmos'
address_index int

Address index to get sub accounts for seed phrases (doesn't work when using a private key)

0
protobuf str

Define which protobuf files to use. Cosmos, Evmos and Osmosis are built in and otherwise pass the raw package name (cosmospy-protobuf)

'cosmos'
eth bool

Etermint compatibility mpde. If set to true the addresses and signatures will match the ethereum standard. Defaults to false to match the Cosmos standard.

False
Source code in mospy/Account.py
 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
class Account:
    """
    The account class can be instantiated through a seed or a private key. If nothing is provided it will create a new keyring and the params to work with the cosmos chain

    Note:
        * You can't provide a ``seed_phrase`` and a``private_key``
        * A ``readble`` method behaves is the getter for a Attribute (Example: ``hrp = account.hrp``)
        * A ``writable`` method is the setter for the Attribute (Example: ``account.hrp = "cosmos"``)
        * A method can be setter and getter at the same time. The Parameters description always refers to the setter while the Returns section belongs to the getter


    Args:
        seed_phrase (str): Seed phrase to derive private keys from
        private_key (str): Private key to instantiate the Account
        next_sequence (int): Sequence which will be used for transactions signed with this Account
        account_number (int): On-chain account number
        slip44 (int): Slip44 value
        hrp (str): Address Prefix
        address_index (int): Address index to get sub accounts for seed phrases (doesn't work when using a private key)
        protobuf (str): Define which protobuf files to use. Cosmos, Evmos and Osmosis are built in and otherwise pass the raw package name (cosmospy-protobuf)
        eth (bool): Etermint compatibility mpde. If set to true the addresses and signatures will match the ethereum standard. Defaults to false to match the Cosmos standard.
    """

    address: str
    """the address of the account derived by using the slip44 param, the hrp and the address_index"""

    _RAW_DERIVATION_PATH = "m/44'/{slip44}'/0'/0/{address_index}"

    def __init__(
        self,
        seed_phrase: str = None,
        private_key: str = None,
        next_sequence: int = None,
        account_number: int = None,
        slip44: int = 118,
        hrp: str = "cosmos",
        address_index: int = 0,
        protobuf: str = "cosmos",
        eth: bool = False,
        public_key_type: str = None
    ):
        _protobuf_packages = {
            "cosmos": "cosmospy_protobuf",
            "osmosis": "osmosis_protobuf",
            "evmos": "evmos_protobuf",
            "sentinel": "sentinel_protobuf",
        }
        _protobuf_package = (_protobuf_packages[protobuf.lower()]
                             if protobuf.lower() in _protobuf_packages.keys()
                             else protobuf)


        try:
            self.keys_pb2 = importlib.import_module(
                _protobuf_package + ".cosmos.crypto.secp256k1.keys_pb2")
        except AttributeError:
            raise ImportError(
                "It seems that you are importing conflicting protobuf files. Have sou set the protobuf attribute to specify your coin? Check out the documentation for more information."
            )
        except:
            raise ImportError(
                f"Couldn't import from {_protobuf_package}. Is the package installed? "
            )

        self._eth = eth
        self._slip44 = slip44
        self._hrp = hrp
        self._address_index = address_index
        self._next_sequence = next_sequence
        self._account_number = account_number

        # Set the public key type
        if public_key_type:
            self._public_key_type = public_key_type
        else:
            if eth:
                # Add Injectiver as exception as they use ethermint but with their own definition
                # Otherwise default to ethermint
                if hrp == "inj":
                    self._public_key_type = "/injective.crypto.v1beta1.ethsecp256k1.PubKey"
                else:
                    self._public_key_type = "/ethermint.crypto.v1.ethsecp256k1.PubKey"
            else:
                self._public_key_type = "/cosmos.crypto.secp256k1.PubKey"

        if not seed_phrase and not private_key:
            self._seed_phrase = Mnemonic(language="english").generate(
                strength=256)
            self._private_key = seed_to_private_key(self._seed_phrase,
                                                    self._derivation_path())

        elif seed_phrase and not private_key:
            self._seed_phrase = seed_phrase
            self._private_key = seed_to_private_key(seed_phrase,
                                                    self._derivation_path())

        elif private_key and not seed_phrase:
            self._seed_phrase = None
            self._private_key = bytes.fromhex(private_key)

        else:
            raise AttributeError(
                "Please set only a private key or a seed phrase. Not both!")

    def _derivation_path(self, address_index: int = None):
        adr_id = self._address_index if not address_index else address_index
        params = {"slip44": self._slip44, "address_index": adr_id}
        return self._RAW_DERIVATION_PATH.format(**params)

    @property
    def address(self) -> str:
        """
        Current address which depends on the hrp and the private key.

        Returns:
            Address
        """
        if not self._seed_phrase:
            address = privkey_to_address(self._private_key, hrp=self._hrp) if not self._eth else privkey_to_eth_address(self._private_key, hrp=self._hrp)
        else:
            sub_private_key = seed_to_private_key(
                self._seed_phrase,
                self._derivation_path(address_index=self._address_index),
            )
            address = privkey_to_address(sub_private_key, hrp=self._hrp) if not self._eth else privkey_to_eth_address(sub_private_key, hrp=self._hrp)

        return address

    @property
    def eth_address(self) -> str:
        """
        Ethereum compatible address starting with 0x. Only available if Account is initialised with eth set to True.

        Returns:
            Address
        """
        if not self._eth:
            raise TypeError("Account hasn't been initialised with the eth mode set to true.")
        if not self._seed_phrase:
            address = privkey_to_eth_address(self._private_key)
        else:
            sub_private_key = seed_to_private_key(
                self._seed_phrase,
                self._derivation_path(address_index=self._address_index),
            )
            address = privkey_to_eth_address(sub_private_key)

        return address

    @property
    def seed_phrase(self) -> str:
        """
        Current Seed Phrase

        Returns:
            Seed Phrase
        """
        return self._seed_phrase

    @property
    def private_key(self) -> bytes:
        """
        Current private key which depends on the slip 44 param and the address index if the account is instantiated through a seed.

        Returns:
            Private Key
        """
        if self._seed_phrase:
            private_key = seed_to_private_key(
                self._seed_phrase,
                self._derivation_path(address_index=self._address_index),
            )
            return private_key
        else:
            return self._private_key

    @property
    def public_key(self) -> str:
        """
        Current public key which depends on the slip 44 param and the address index if the account is instantiated through a seed.

        Returns:
            Public Key
        """
        pubkey_bytes = privkey_to_pubkey(self.private_key)
        _pubkey = self.keys_pb2.PubKey()
        _pubkey.key = pubkey_bytes
        return _pubkey

    @property
    def account_number(self) -> int:
        """
        On-chain account number which will be assigned when the address receives coins for the first time.

        Returns:
            Account number
        """
        return self._account_number

    @account_number.setter
    def account_number(self, account_number: int):
        self._account_number = account_number

    @property
    def next_sequence(self) -> int:
        """
        Sequence which will be used for transactions signed with this Account.

        Returns:
            Next Sequence
        """
        return self._next_sequence

    @next_sequence.setter
    def next_sequence(self, next_sequence):
        self._next_sequence = next_sequence

    def increase_sequence(self, change: int = 1) -> None:
        """
        Increase the sequence by ``change``

        Args:
            change (int): Value to increase the sequence
        """
        self._next_sequence += change

    @property
    def address_index(self):
        """
        Change the address index to use a sub account. This works only if a seed has been used to instantiate the Account.


        Returns:
            Address Index
        """
        return self._address_index

    @address_index.setter
    def address_index(self, address_index: int) -> None:

        if self._seed_phrase:
            self._DEFAULT_ADDRESS_INDEX = address_index
        else:
            raise ValueError(
                "Can't the change the address index without provided seed")

    @property
    def hrp(self) -> str:
        """
        Current address prefix used by the Account.

        Returns:
            Address Prefix (hrp)
        """
        return self._hrp

    @hrp.setter
    def hrp(self, hrp: str) -> None:
        self._hrp = hrp

    @property
    def slip44(self) -> int:
        """
        Set the Slip44 value. Cosmos defaults to 118

        Returns:
            Slip44

        """
        return self._slip44

    @slip44.setter
    def slip44(self, slip44: int) -> None:
        self._slip44 = slip44

    @property
    def eth(self) -> bool:
        """
        Change the eth compatibility mode. If you want to use Evmos you will need to set eth to true. Otherwise it defaults to False

        Returns:
            eth
          """
        return self._eth

    @eth.setter
    def eth(self, eth: bool):

        self._eth = eth

    @property
    def public_key_type(self):
        """
        Get the current pyblic key type

        Returns:
            public_key_type
          """
        return self._public_key_type
    @public_key_type.setter
    def public_key_type(self, public_key_type):
        self._public_key_type = public_key_type

account_number: int writable property

On-chain account number which will be assigned when the address receives coins for the first time.

Returns:

Type Description
int

Account number

address: str property

Current address which depends on the hrp and the private key.

Returns:

Type Description
str

Address

address_index writable property

Change the address index to use a sub account. This works only if a seed has been used to instantiate the Account.

Returns:

Type Description

Address Index

eth: bool writable property

Change the eth compatibility mode. If you want to use Evmos you will need to set eth to true. Otherwise it defaults to False

Returns:

Type Description
bool

eth

eth_address: str property

Ethereum compatible address starting with 0x. Only available if Account is initialised with eth set to True.

Returns:

Type Description
str

Address

hrp: str writable property

Current address prefix used by the Account.

Returns:

Type Description
str

Address Prefix (hrp)

next_sequence: int writable property

Sequence which will be used for transactions signed with this Account.

Returns:

Type Description
int

Next Sequence

private_key: bytes property

Current private key which depends on the slip 44 param and the address index if the account is instantiated through a seed.

Returns:

Type Description
bytes

Private Key

public_key: str property

Current public key which depends on the slip 44 param and the address index if the account is instantiated through a seed.

Returns:

Type Description
str

Public Key

public_key_type writable property

Get the current pyblic key type

Returns:

Type Description

public_key_type

seed_phrase: str property

Current Seed Phrase

Returns:

Type Description
str

Seed Phrase

slip44: int writable property

Set the Slip44 value. Cosmos defaults to 118

Returns:

Type Description
int

Slip44

increase_sequence(change=1)

Increase the sequence by change

Parameters:

Name Type Description Default
change int

Value to increase the sequence

1
Source code in mospy/Account.py
227
228
229
230
231
232
233
234
def increase_sequence(self, change: int = 1) -> None:
    """
    Increase the sequence by ``change``

    Args:
        change (int): Value to increase the sequence
    """
    self._next_sequence += change