Skip to content

Commit

Permalink
refactor: Make Keypair.secret and Keypair.public_key property
Browse files Browse the repository at this point in the history
  • Loading branch information
overcat committed Aug 14, 2019
1 parent fa732ad commit 0fb216d
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 35 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ A Simple Example
bob_address = "GA7YNBW5CBTJZ3ZZOWX3ZNBKD6OE7A7IHUQVWMY62W2ZBG2SGZVOOPVH"
server = Server("https://horizon-testnet.stellar.org")
alice_account = server.load_account(alice_keypair.public_key())
alice_account = server.load_account(alice_keypair.public_key)
base_fee = server.fetch_base_fee()
transaction = (
TransactionBuilder(
Expand Down Expand Up @@ -98,7 +98,7 @@ A Simple Example
async with Server(
horizon_url="https://horizon-testnet.stellar.org", client=AiohttpClient()
) as server:
alice_account = await server.load_account(alice_keypair.public_key())
alice_account = await server.load_account(alice_keypair.public_key)
base_fee = await server.fetch_base_fee()
transaction = (
TransactionBuilder(
Expand Down
6 changes: 3 additions & 3 deletions docs/generate_keypair.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ creating new keypair is by passing the account's secret seed:
from stellar_sdk import Keypair
keypair = Keypair.from_secret("SBK2VIYYSVG76E7VC3QHYARNFLY2EAQXDHRC7BMXBBGIFG74ARPRMNQM")
public_key = keypair.public_key() # GDHMW6QZOL73SHKG2JA3YHXFDHM46SS5ZRWEYF5BCYHX2C5TVO6KZBYL
public_key = keypair.public_key # GDHMW6QZOL73SHKG2JA3YHXFDHM46SS5ZRWEYF5BCYHX2C5TVO6KZBYL
can_sign = keypair.can_sign() # True
Expand All @@ -41,5 +41,5 @@ You can also create a randomly generated keypair:
from stellar_sdk import Keypair
keypair = Keypair.random()
print("Public Key: " + keypair.public_key())
print("Secret Seed: " + keypair.secret())
print("Public Key: " + keypair.public_key)
print("Secret Seed: " + keypair.secret)
6 changes: 3 additions & 3 deletions examples/create_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
source = Keypair.from_secret("SBFZCHU5645DOKRWYBXVOXY2ELGJKFRX6VGGPRYUWHQ7PMXXJNDZFMKD")
destination = Keypair.random()

source_account = server.load_account(account_id=source.public_key())
source_account = server.load_account(account_id=source.public_key)
transaction = TransactionBuilder(
source_account=source_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=100) \
.append_create_account_op(destination=destination.public_key(), starting_balance="12.25") \
.append_create_account_op(destination=destination.public_key, starting_balance="12.25") \
.build()
transaction.sign(source)
response = server.submit_transaction(transaction)
print("Transaction hash: {}".format(response["hash"]))
print("New Keypair: \n\taccount id: {account_id}\n\tsecret seed: {secret_seed}".format(
account_id=destination.public_key(), secret_seed=destination.secret()))
account_id=destination.public_key, secret_seed=destination.secret))
6 changes: 3 additions & 3 deletions examples/create_account_friendbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

keypair = Keypair.random()

print("Public Key: " + keypair.public_key())
print("Secret Seed: " + keypair.secret())
print("Public Key: " + keypair.public_key)
print("Secret Seed: " + keypair.secret)

url = 'https://friendbot.stellar.org'
response = requests.get(url, params={'addr': keypair.public_key()})
response = requests.get(url, params={'addr': keypair.public_key})
print(response)
10 changes: 5 additions & 5 deletions examples/create_keypair.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
# create a random keypair
print("create a random keypair")
kp = Keypair.random()
print("Secret: {}".format(kp.secret()))
print("Public Key: {}".format(kp.public_key()))
print("Secret: {}".format(kp.secret))
print("Public Key: {}".format(kp.public_key))
print("")

# create a keypair from secret
print("create a keypair from secret")
secret = "SBRR6ZPBHHTDXYSFRZR2QZCGDZURNE5ON4M4F3HQA42G3Z62SFCR7EEJ"
kp = Keypair.from_secret(secret)
print("Secret: {}".format(kp.secret()))
print("Public Key: {}".format(kp.public_key()))
print("Secret: {}".format(kp.secret))
print("Public Key: {}".format(kp.public_key))
print("")

# create a keypair from public key
print("create a keypair from public key")
public_key = "GDCZ6JDZMWYORTIHEO2E4ZXKBQ2TLXNRQJPJH5RCFN7Q7I24G4RGLXP6"
kp = Keypair.from_public_key(public_key)
print("Public Key: {}".format(kp.public_key()))
print("Public Key: {}".format(kp.public_key))
2 changes: 1 addition & 1 deletion examples/path_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
server = Server(horizon_url="https://horizon-testnet.stellar.org")
source_keypair = Keypair.from_secret("SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")

source_account = server.load_account(account_id=source_keypair.public_key())
source_account = server.load_account(account_id=source_keypair.public_key)

path = [
Asset("USD", "GBBM6BKZPEHWYO3E3YKREDPQXMS4VK35YLNU7NFBRI26RAN7GI5POFBB"),
Expand Down
2 changes: 1 addition & 1 deletion examples/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# Derive Keypair object and public key (that starts with a G) from the secret
source_keypair = Keypair.from_secret(source_secret_key)
source_public_key = source_keypair.public_key()
source_public_key = source_keypair.public_key

receiver_public_key = "GA7YNBW5CBTJZ3ZZOWX3ZNBKD6OE7A7IHUQVWMY62W2ZBG2SGZVOOPVH"

Expand Down
4 changes: 2 additions & 2 deletions examples/set_up_multisig_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

server = Server(horizon_url="https://horizon-testnet.stellar.org")
root_keypair = Keypair.from_secret("SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")
root_account = server.load_account(account_id=root_keypair.public_key())
root_account = server.load_account(account_id=root_keypair.public_key)
secondary_keypair = Keypair.from_secret("SAMZUAAPLRUH62HH3XE7NVD6ZSMTWPWGM6DS4X47HLVRHEBKP4U2H5E7")

secondary_signer = Signer.ed25519_public_key(account_id=secondary_keypair.public_key(), weight=1)
secondary_signer = Signer.ed25519_public_key(account_id=secondary_keypair.public_key, weight=1)
transaction = TransactionBuilder(
source_account=root_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
Expand Down
2 changes: 1 addition & 1 deletion examples/transaction_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

root_keypair = Keypair.from_secret("SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")
# Create an Account object from an address and sequence number.
root_account = Account(account_id=root_keypair.public_key(), sequence=1)
root_account = Account(account_id=root_keypair.public_key, sequence=1)

transaction = TransactionBuilder(
source_account=root_account,
Expand Down
2 changes: 1 addition & 1 deletion examples/transaction_builder_with_memo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

root_keypair = Keypair.from_secret("SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")
# Create an Account object from an address and sequence number.
root_account = Account(account_id=root_keypair.public_key(), sequence=1)
root_account = Account(account_id=root_keypair.public_key, sequence=1)

transaction = TransactionBuilder(source_account=root_account, network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=100).add_text_memo("Happy birthday!").append_payment_op(
Expand Down
2 changes: 1 addition & 1 deletion stellar_sdk/asset.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from typing import Optional, Dict

from .exceptions import AssetCodeInvalidError, AssetIssuerInvalidError
from .exceptions import AssetCodeInvalidError, AssetIssuerInvalidError, AttributeError
from .keypair import Keypair
from .xdr import Xdr
from .strkey import StrKey
Expand Down
6 changes: 6 additions & 0 deletions stellar_sdk/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

BuildInValueError = ValueError
BuildInTypeError = TypeError
BuildInAttributeError = AttributeError

__all__ = [
"SdkError",
"ValueError",
"TypeError",
"AttributeError",
"BadSignatureError",
"Ed25519PublicKeyInvalidError",
"Ed25519SecretSeedInvalidError",
Expand Down Expand Up @@ -42,6 +44,10 @@ class TypeError(BuildInTypeError, SdkError):
"""


class AttributeError(BuildInAttributeError, SdkError):
""" Attribute not found. """


class BadSignatureError(ValueError):
"""Raised when the signature was forged or otherwise corrupt.
"""
Expand Down
22 changes: 20 additions & 2 deletions stellar_sdk/keypair.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
import nacl.signing as ed25519
from nacl.exceptions import BadSignatureError as NaclBadSignatureError

from .exceptions import BadSignatureError, MissingEd25519SecretSeedError, ValueError
from .exceptions import (
BadSignatureError,
MissingEd25519SecretSeedError,
ValueError,
AttributeError,
)
from .strkey import StrKey
from .xdr import Xdr

Expand Down Expand Up @@ -78,6 +83,7 @@ def from_raw_ed25519_seed(cls, raw_seed: bytes) -> "Keypair":
verify_key = signing_key.verify_key
return cls(verify_key, signing_key)

@property
def secret(self) -> str:
"""Returns secret key associated with this :class:`Keypair` instance
Expand All @@ -93,14 +99,26 @@ def secret(self) -> str:

return StrKey.encode_ed25519_secret_seed(self.raw_secret_key())

# @property
@secret.setter
def secret(self, secret: str) -> None:
raise AttributeError(
"Please use `Keypair.from_secret` to generate a new Keypair object."
)

@property
def public_key(self) -> str:
"""Returns public key associated with this :class:`Keypair` instance
:return: public key
"""
return StrKey.encode_ed25519_public_key(self.raw_public_key())

@public_key.setter
def public_key(self, public_key: str) -> None:
raise AttributeError(
"Please use `Keypair.from_public_key` to generate a new Keypair object."
)

def xdr_public_key(self) -> Xdr.types.PublicKey:
"""
Expand Down
31 changes: 22 additions & 9 deletions tests/test_keypair.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest
import nacl.signing as ed25519
from stellar_sdk.exceptions import ValueError
from stellar_sdk.exceptions import ValueError, AttributeError

from stellar_sdk.exceptions import (
Ed25519SecretSeedInvalidError,
Expand All @@ -17,8 +17,8 @@
class TestKeypair:
def test_create_random(self):
kp = Keypair.random()
public_key = kp.public_key()
secret = kp.secret()
public_key = kp.public_key
secret = kp.secret
assert StrKey.is_valid_ed25519_public_key(public_key)
assert StrKey.is_valid_ed25519_secret_seed(secret)

Expand All @@ -27,10 +27,9 @@ def test_create_from_secret(self):
kp = Keypair.from_secret(secret)
assert isinstance(kp, Keypair)
assert (
kp.public_key()
== "GDFQVQCYYB7GKCGSCUSIQYXTPLV5YJ3XWDMWGQMDNM4EAXAL7LITIBQ7"
kp.public_key == "GDFQVQCYYB7GKCGSCUSIQYXTPLV5YJ3XWDMWGQMDNM4EAXAL7LITIBQ7"
)
assert kp.secret() == secret
assert kp.secret == secret

@pytest.mark.parametrize(
"invalid_secret",
Expand All @@ -54,8 +53,7 @@ def test_create_from_public_key(self):
kp = Keypair.from_public_key(public_key)
assert isinstance(kp, Keypair)
assert (
kp.public_key()
== "GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH"
kp.public_key == "GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH"
)
assert (
kp.raw_public_key().hex()
Expand Down Expand Up @@ -155,4 +153,19 @@ def test_read_secret_without_secret_raise(self):
"GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH"
)
with pytest.raises(MissingEd25519SecretSeedError):
kp.secret()
secret = kp.secret

def test_set_keypair_raise(self):
secret = "SD7X7LEHBNMUIKQGKPARG5TDJNBHKC346OUARHGZL5ITC6IJPXHILY36"
kp = Keypair.from_secret(secret)
with pytest.raises(
AttributeError,
match="Please use `Keypair.from_secret` to generate a new Keypair object.",
):
kp.secret = "SAMWF63FZ5ZNHY75SNYNAFMWTL5FPBMIV7DLB3UDAVLL7DKPI5ZFS2S6"

with pytest.raises(
AttributeError,
match="Please use `Keypair.from_public_key` to generate a new Keypair object.",
):
kp.public_key = "GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH"
2 changes: 1 addition & 1 deletion tests/test_transaction.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from stellar_sdk import Keypair, IdMemo, Asset, NoneMemo
from stellar_sdk import Keypair, IdMemo, Asset, NoneMemo
from stellar_sdk.operation import Payment, ManageData
from stellar_sdk.exceptions import ValueError
from stellar_sdk.time_bounds import TimeBounds
Expand Down

0 comments on commit 0fb216d

Please sign in to comment.