Skip to content
This repository was archived by the owner on Aug 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions aeternity/identifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
TRANSACTION
])

# Account address encoding formats
ACCOUNT_API_FORMAT = 'api'
ACCOUNT_SOFIA_FORMAT = 'sofia'
ACCOUNT_RAW_FORMAT = 'raw'

# RLP Identifiers

Expand Down
45 changes: 35 additions & 10 deletions aeternity/signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
from nacl.exceptions import CryptoError
from nacl.pwhash import argon2id
from nacl import secret, utils as nacl_utils
from aeternity.identifiers import ACCOUNT_ID


from aeternity.identifiers import ACCOUNT_ID, ACCOUNT_API_FORMAT, ACCOUNT_SOFIA_FORMAT, ACCOUNT_RAW_FORMAT
from aeternity import hashing, utils

from deprecated import deprecated


class Account:
"""Implement private/public key functionalities"""
Expand All @@ -25,15 +25,40 @@ def __init__(self, signing_key, verifying_key):
self.address = hashing.encode(ACCOUNT_ID, pub_key)
self.nonce = 0

def get_address(self):
"""get the keypair public_key base58 encoded and prefixed (ak_...)"""
return self.address
def get_address(self, format=ACCOUNT_API_FORMAT):
"""
Get the account address
:param format: the format of the address, possible values are 'api', 'sofia', 'raw', default is 'api'

when the format is:
- api the address is base58 encoded with ak_ as prefix
- sofia the addres is hex encoded with 0x as prefix
- raw the address is returned as a byte array

raise ValueError when the format is not recognized
"""
if format == ACCOUNT_API_FORMAT or format is None:
return self.address
elif format == ACCOUNT_RAW_FORMAT:
return self.verifying_key.encode()
elif format == ACCOUNT_SOFIA_FORMAT:
return f'0x{self.verifying_key.encode(encoder=HexEncoder).decode("utf-8")}'
raise ValueError(f'Unrecognized format {format} for address encoding')

@deprecated(version='2.0.0', reason="Use get_secret_key instead")
def get_private_key(self):
"""get the private key hex encoded"""
pk = self.signing_key.encode(encoder=HexEncoder).decode('utf-8')
pb = self.verifying_key.encode(encoder=HexEncoder).decode('utf-8')
return f"{pk}{pb}"
"""
Get the private key hex encoded
"""
return self.get_secret_key()

def get_secret_key(self) -> str:
"""
Get the secret key as a hex encoded string
"""
sk = self.signing_key.encode(encoder=HexEncoder).decode('utf-8')
pk = self.verifying_key.encode(encoder=HexEncoder).decode('utf-8')
return f"{sk}{pk}"

def sign(self, data):
"""
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ websocket_client==0.48.0
validators==0.12.1
semver==2.8.1
namedtupled==0.3.3
Deprecated==1.2.5
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def get_version():
'websocket_client == 0.48.0',
'validators == 0.12.1',
'semver==2.8.1',
'namedtupled==0.3.3'
'namedtupled==0.3.3',
'Deprecated==1.2.5'
],
classifiers=[
'Programming Language :: Python',
Expand Down
14 changes: 13 additions & 1 deletion tests/test_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from tests import TEST_TTL
from aeternity.signing import Account, is_signature_valid
from aeternity.utils import is_valid_hash
from aeternity import hashing
from aeternity import hashing, identifiers
import os


Expand Down Expand Up @@ -96,3 +96,15 @@ def test_signing_is_signature_valid():
hashing._base64_decode(account_b64),
hashing._base64_decode(sg_b64),
msg)


def test_signing_get_address():
a = Account.from_private_key_string(
'3960180c89e27fcc1559f631d664a4b56b569aa5768ba827ddc9ba9616fecd9d8134464ef14b1433790e259d40b6ad8ca39f397a2bbc5261eeba1018a67ce35a')
assert(a.get_address() == 'ak_yuMB5S3yiTwRVJC1NcNEGppcGAbq26qFWNJTCJWnLqoihCpCG')
assert(a.get_address(format=identifiers.ACCOUNT_API_FORMAT) == 'ak_yuMB5S3yiTwRVJC1NcNEGppcGAbq26qFWNJTCJWnLqoihCpCG')
assert(a.get_address(format=identifiers.ACCOUNT_API_FORMAT) != 'ak_xuMB5S3yiTwRVJC1NcNEGppcGAbq26qFWNJTCJWnLqoihCpCG')
assert(a.get_address(format=identifiers.ACCOUNT_SOFIA_FORMAT) == '0x8134464ef14b1433790e259d40b6ad8ca39f397a2bbc5261eeba1018a67ce35a')
assert(a.get_address(format=identifiers.ACCOUNT_SOFIA_FORMAT) != '8134464ef14b1433790e259d40b6ad8ca39f397a2bbc5261eeba1018a67ce35a')
assert(a.get_address(format=identifiers.ACCOUNT_RAW_FORMAT) == b'\x814FN\xf1K\x143y\x0e%\x9d@\xb6\xad\x8c\xa3\x9f9z+\xbcRa\xee\xba\x10\x18\xa6|\xe3Z')
assert(a.get_address(format=identifiers.ACCOUNT_RAW_FORMAT) != b'\x814FN\xf1K\x143y\x0e%\x9d@\xb6\x00\x8c\xa3\x9f9z+\xbcRa\xee\xba\x10\x18\xa6|\xe3Z')