Skip to content
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
63 changes: 18 additions & 45 deletions crypto/configuration/network.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,26 @@
from datetime import datetime
from typing import Type, TypedDict, Union
from crypto.networks.mainnet import Mainnet
from crypto.networks.abstract_network import AbstractNetwork
from crypto.networks.testnet import Testnet

class NetworkType(TypedDict):
epoch: datetime
wif: str
chain_id: int
class Network:
_network: AbstractNetwork

network: NetworkType = {
'epoch': Testnet.epoch,
'wif': Testnet.wif,
'chain_id': Testnet.chain_id,
}
@classmethod
def set_network(cls, network: AbstractNetwork) -> None:
"""Set what network you want to use in the crypto library

def set_network(network_object: Union[Type[Mainnet], Type[Testnet]]) -> None:
"""Set what network you want to use in the crypto library
Args:
network_object: Testnet, Devnet, Mainnet
"""

Args:
network_object: Testnet, Devnet, Mainnet
"""
global network
cls._network = network

network = {
'epoch': network_object.epoch,
'wif': network_object.wif,
'chain_id': network_object.chain_id,
}
@classmethod
def get_network(cls) -> AbstractNetwork:
"""Get settings for a selected network

def get_network() -> NetworkType:
"""Get settings for a selected network, default network is devnet
Returns:
AbstractNetwork: network settings (default network is testnet)
"""
return cls._network

Returns:
dict: network settings (default network is devnet)
"""
return network

def set_custom_network(epoch: datetime, wif: str, chain_id: int) -> None:
"""Set custom network

Args:
epoch (datetime): chains epoch time
wif (str): chains wif
chain_id (int): chain id
"""
global network

network = {
'epoch': epoch,
'wif': wif,
'chain_id': chain_id
}
Network.set_network(Testnet())
4 changes: 2 additions & 2 deletions crypto/identity/private_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from Cryptodome.Hash import keccak
from base58 import b58decode

from crypto.configuration.network import get_network
from crypto.configuration.network import Network
from crypto.enums.constants import Constants

class PrivateKey(object):
Expand Down Expand Up @@ -76,7 +76,7 @@ def from_wif(cls, wif: str):
wif = b58decode(wif).hex()

version = wif[0:2]
if version != get_network()['wif']:
if version != Network.get_network().wif():
raise ValueError(f"Invalid network version: {version}")

private_key = wif[2:66]
Expand Down
6 changes: 3 additions & 3 deletions crypto/identity/wif.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from binary.unsigned_integer.writer import write_bit8

from crypto.configuration.network import get_network
from crypto.configuration.network import Network

def wif_from_passphrase(passphrase: str, network_wif: Optional[str] = None):
"""Get wif from passphrase
Expand All @@ -18,9 +18,9 @@ def wif_from_passphrase(passphrase: str, network_wif: Optional[str] = None):
string: wif
"""
if not network_wif:
network = get_network()
network = Network.get_network()

network_wif = network['wif']
network_wif = network.wif()

private_key = hashlib.sha256(passphrase.encode())
seed = write_bit8(int(network_wif, 16)) + private_key.digest() + write_bit8(0x01)
Expand Down
14 changes: 14 additions & 0 deletions crypto/networks/abstract_network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from abc import ABC, abstractmethod

class AbstractNetwork(ABC):
@abstractmethod
def chain_id(self) -> int:
"""Return the chain ID of the network."""

@abstractmethod
def epoch(self) -> str:
"""Return the epoch time of the network."""

@abstractmethod
def wif(self) -> str:
"""Return the WIF (Wallet Import Format) of the network."""
15 changes: 10 additions & 5 deletions crypto/networks/mainnet.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from datetime import datetime
from crypto.networks.abstract_network import AbstractNetwork

class Mainnet(object):
epoch = datetime(2017, 3, 21, 13, 00, 00)
wif = 'ba'
chain_id = 10000
class Mainnet(AbstractNetwork):
def chain_id(self):
return 10000

def epoch(self):
return '2017-03-21T13:00:00.000Z'

def wif(self):
return 'ba'
15 changes: 10 additions & 5 deletions crypto/networks/testnet.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from datetime import datetime
from crypto.networks.abstract_network import AbstractNetwork

class Testnet(object):
epoch = datetime(2017, 3, 21, 13, 00, 00)
wif = 'ba'
chain_id = 10000
class Testnet(AbstractNetwork):
def chain_id(self):
return 10000

def epoch(self):
return '2017-03-21T13:00:00.000Z'

def wif(self):
return 'ba'
5 changes: 2 additions & 3 deletions crypto/transactions/builder/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from typing import Optional
from crypto.configuration.network import get_network
from crypto.configuration.network import Network
from crypto.identity.private_key import PrivateKey
from crypto.transactions.types.abstract_transaction import AbstractTransaction

Expand All @@ -11,7 +10,7 @@ def __init__(self, data: dict):
'senderPublicKey': '',
'gasPrice': '5',
'nonce': '1',
'network': get_network()['chain_id'],
'network': Network.get_network().chain_id(),
'gasLimit': 1_000_000,
'data': '',

Expand Down
2 changes: 0 additions & 2 deletions crypto/transactions/types/abstract_transaction.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import json
from typing import Optional

from crypto.configuration.network import get_network
from crypto.enums.constants import Constants
from crypto.enums.contract_abi_type import ContractAbiType
from crypto.identity.address import address_from_public_key
from crypto.identity.private_key import PrivateKey
from crypto.utils.transaction_utils import TransactionUtils
from coincurve import PublicKey
from crypto.utils.abi_decoder import AbiDecoder

class AbstractTransaction:
def __init__(self, data: dict):
Expand Down
20 changes: 12 additions & 8 deletions crypto/utils/slot.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
from datetime import datetime
from datetime import datetime, timezone

from crypto.configuration.network import get_network
from crypto.configuration.network import Network


def get_time():
def get_time() -> int:
"""Get the time difference between now and network start.

Returns:
int: difference in seconds
"""
now = datetime.utcnow()
network = get_network()
seconds = int((now - network['epoch']).total_seconds())
now = datetime.now(timezone.utc)

seconds = int((now - get_epoch()).total_seconds())

return seconds


def get_epoch():
network = get_network()
return network['epoch']
epoch_str = Network.get_network().epoch()
if epoch_str.endswith("Z"):
epoch_str = epoch_str[:-1] + "+00:00"

return datetime.fromisoformat(epoch_str)
49 changes: 29 additions & 20 deletions tests/configuration/test_network.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
from datetime import datetime

from crypto.configuration.network import get_network, set_custom_network, set_network
from crypto.configuration.network import Network
from crypto.networks.abstract_network import AbstractNetwork
from crypto.networks.testnet import Testnet
from crypto.networks.mainnet import Mainnet

class CustomNetwork(AbstractNetwork):
def epoch(self):
return "2024-01-01T13:00:00.000Z"

def wif(self):
return "82"

def chain_id(self):
return 20000

def test_get_network():
result = get_network()
assert result['chain_id'] == 10000
result = Network.get_network()
assert result.chain_id() == 10000

def test_set_network():
# mainnet
set_network(Mainnet)
result = get_network()
assert result['wif'] == 'ba'
assert result['chain_id'] == 10000
Network.set_network(Mainnet())
result = Network.get_network()
assert result.wif() == 'ba'
assert result.chain_id() == 10000

# testnet
set_network(Testnet)
result = get_network()
assert result['wif'] == 'ba'
assert result['chain_id'] == 10000
Network.set_network(Testnet())
result = Network.get_network()
assert result.wif() == 'ba'
assert result.chain_id() == 10000

set_network(Testnet) # set back to Testnet so other tests don't fail
Network.set_network(Testnet()) # set back to Testnet so other tests don't fail

def test_set_custom_network():
epoch_time = datetime(2017, 1, 1, 13, 00, 00)
set_custom_network(epoch_time, '82', 10000)
result = get_network()
assert result['wif'] == '82'
assert result['epoch'] == epoch_time
assert result['chain_id'] == 10000

set_network(Testnet) # set back to Testnet so other tests don't fail
Network.set_network(CustomNetwork())
result = Network.get_network()
assert result.wif() == '82'
assert result.epoch() == "2024-01-01T13:00:00.000Z"
assert result.chain_id() == 20000

Network.set_network(Testnet()) # set back to Testnet so other tests don't fail
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
import json
import os
from crypto.configuration.network import set_network
from crypto.configuration.network import Network
from crypto.networks.testnet import Testnet


Expand All @@ -11,7 +11,7 @@ def configure_network():
Configures the network to Testnet before running any tests.
This fixture runs automatically once per test session.
"""
set_network(Testnet)
Network.set_network(Testnet())

@pytest.fixture
def load_transaction_fixture():
Expand Down
4 changes: 2 additions & 2 deletions tests/identity/test_wif.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from crypto.configuration.network import set_network
from crypto.configuration.network import Network
from crypto.identity.wif import wif_from_passphrase
from crypto.networks.testnet import Testnet


def test_wif_from_passphrase(identity):
set_network(Testnet)
Network.set_network(Testnet())

result = wif_from_passphrase(identity['passphrase'])
assert result == identity['data']['wif']