Skip to content

Commit

Permalink
Merge branch 'feat/next' into update-cookbook-v1
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Dec 2, 2024
2 parents f8724ac + b021c55 commit ab62322
Show file tree
Hide file tree
Showing 24 changed files with 135 additions and 60 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
project = 'multiversx-sdk'
copyright = '2024, MultiversX'
author = 'MultiversX'
release = '0.11.0'
release = '0.19.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
41 changes: 41 additions & 0 deletions examples/Cookbook.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,47 @@
"print(\"Is contract address:\", address.is_smart_contract())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Changing the default hrp\n",
"\n",
"We have a configuration class, called `LibraryConfig`, that only stores (for the moment) the **default hrp** of the addresses. The default value is `erd`. The hrp can be changed when instantiating an address, or it can be changed in the `LibraryConfig` class, and all the addresses created will have the newly set hrp. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"erd\n",
"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\n",
"test1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ss5hqhtr\n"
]
}
],
"source": [
"from multiversx_sdk import Address\n",
"from multiversx_sdk import LibraryConfig\n",
"\n",
"\n",
"print(LibraryConfig.default_address_hrp)\n",
"address = Address.new_from_hex(\"0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1\")\n",
"print(address.to_bech32())\n",
"\n",
"LibraryConfig.default_address_hrp = \"test\"\n",
"address = Address.new_from_hex(\"0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1\")\n",
"print(address.to_bech32())\n",
"\n",
"# setting back the default value\n",
"LibraryConfig.default_address_hrp = \"erd\""
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
16 changes: 9 additions & 7 deletions multiversx_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
AccountTransactionsFactory)
from multiversx_sdk.accounts import Account
from multiversx_sdk.core import (Address, AddressComputer, AddressFactory,
CodeMetadata, Message, MessageComputer,
SmartContractResult, Token, TokenComputer,
TokenIdentifierParts, TokenTransfer,
Transaction, TransactionComputer,
TransactionEvent, TransactionEventsParser,
TransactionLogs, TransactionOnNetwork,
CodeMetadata, LibraryConfig, Message,
MessageComputer, SmartContractResult, Token,
TokenComputer, TokenIdentifierParts,
TokenTransfer, Transaction,
TransactionComputer, TransactionEvent,
TransactionEventsParser, TransactionLogs,
TransactionOnNetwork,
TransactionsFactoryConfig, TransactionStatus,
find_events_by_first_topic,
find_events_by_identifier)
Expand Down Expand Up @@ -80,5 +81,6 @@
"BurnQuantityOutcome", "TransactionOnNetwork", "TransactionStatus", "ParsedSmartContractCallOutcome",
"AccountOnNetwork", "AccountStorage", "AccountStorageEntry", "AwaitingOptions", "BlockCoordinates",
"BlockOnNetwork", "FungibleTokenMetadata", "GetBlockArguments", "NetworkConfig", "NetworkStatus",
"TokenAmountOnNetwork", "TokensCollectionMetadata", "TransactionCostResponse", "AccountAwaiter"
"TokenAmountOnNetwork", "TokensCollectionMetadata", "TransactionCostResponse", "AccountAwaiter",
"LibraryConfig"
]
10 changes: 5 additions & 5 deletions multiversx_sdk/accounts/account.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
from pathlib import Path

from multiversx_sdk.core.constants import DEFAULT_HRP
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.wallet.mnemonic import Mnemonic
from multiversx_sdk.wallet.user_signer import UserSigner
from multiversx_sdk.wallet.user_wallet import UserWallet


class Account:
def __init__(self, signer: UserSigner, hrp: str = DEFAULT_HRP) -> None:
def __init__(self, signer: UserSigner, hrp: str = LibraryConfig.default_address_hrp) -> None:
self.signer = signer
self.address = signer.get_pubkey().to_address(hrp)
self.nonce = 0

@classmethod
def new_from_pem(cls, file_path: Path, index: int = 0, hrp: str = DEFAULT_HRP) -> "Account":
def new_from_pem(cls, file_path: Path, index: int = 0, hrp: str = LibraryConfig.default_address_hrp) -> "Account":
signer = UserSigner.from_pem_file(file_path, index)
return Account(signer, hrp)

Expand All @@ -22,7 +22,7 @@ def new_from_keystore(cls,
file_path: Path,
password: str,
address_index: int = 0,
hrp: str = DEFAULT_HRP) -> "Account":
hrp: str = LibraryConfig.default_address_hrp) -> "Account":
secret_key = UserWallet.load_secret_key(file_path, password, address_index)
signer = UserSigner(secret_key)
return Account(signer, hrp)
Expand All @@ -31,7 +31,7 @@ def new_from_keystore(cls,
def new_from_mnemonic(cls,
mnemonic: str,
address_index: int = 0,
hrp: str = DEFAULT_HRP) -> "Account":
hrp: str = LibraryConfig.default_address_hrp) -> "Account":
mnemonic_handler = Mnemonic(mnemonic)
secret_key = mnemonic_handler.derive_key(address_index)
return Account(UserSigner(secret_key), hrp)
Expand Down
4 changes: 3 additions & 1 deletion multiversx_sdk/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from multiversx_sdk.core.address import (Address, AddressComputer,
AddressFactory)
from multiversx_sdk.core.code_metadata import CodeMetadata
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.message import Message, MessageComputer
from multiversx_sdk.core.tokens import (Token, TokenComputer,
TokenIdentifierParts, TokenTransfer)
Expand All @@ -22,5 +23,6 @@
"Token", "TokenComputer", "TokenTransfer", "TokenIdentifierParts",
"SmartContractResult", "TransactionEvent", "TransactionLogs",
"TransactionOnNetwork", "TransactionStatus", "TransactionsFactoryConfig",
"find_events_by_identifier", "find_events_by_first_topic", "TransactionEventsParser"
"find_events_by_identifier", "find_events_by_first_topic", "TransactionEventsParser",
"LibraryConfig"
]
16 changes: 9 additions & 7 deletions multiversx_sdk/core/address.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import logging
from typing import Optional

from Cryptodome.Hash import keccak

from multiversx_sdk.core import bech32
from multiversx_sdk.core.constants import DEFAULT_HRP, METACHAIN_ID
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.constants import METACHAIN_ID
from multiversx_sdk.core.errors import BadAddressError, BadPubkeyLengthError

SC_HEX_PUBKEY_PREFIX = "0" * 16
Expand All @@ -15,7 +17,7 @@
class Address:
"""An Address, as an immutable object."""

def __init__(self, pubkey: bytes, hrp: str) -> None:
def __init__(self, pubkey: bytes, hrp: Optional[str] = None) -> None:
"""Creates an address object, given a sequence of bytes and the human readable part(hrp).
Args:
Expand All @@ -25,14 +27,14 @@ def __init__(self, pubkey: bytes, hrp: str) -> None:
# used for creating an empty address
if not len(pubkey):
self.pubkey = bytes()
self.hrp = DEFAULT_HRP
self.hrp = LibraryConfig.default_address_hrp
return

if len(pubkey) != PUBKEY_LENGTH:
raise BadPubkeyLengthError(len(pubkey), PUBKEY_LENGTH)

self.pubkey = bytes(pubkey)
self.hrp = hrp
self.hrp = hrp if hrp else LibraryConfig.default_address_hrp

@classmethod
def empty(cls,) -> 'Address':
Expand All @@ -57,7 +59,7 @@ def from_bech32(cls, value: str) -> 'Address':
return Address.new_from_bech32(value)

@classmethod
def new_from_hex(cls, value: str, hrp: str) -> 'Address':
def new_from_hex(cls, value: str, hrp: Optional[str] = None) -> 'Address':
"""Creates an address object from the hexed sequence of bytes and the human readable part(hrp).
Args:
Expand Down Expand Up @@ -118,12 +120,12 @@ def __eq__(self, other: object) -> bool:
class AddressFactory:
"""A factory used to create address objects."""

def __init__(self, hrp: str = DEFAULT_HRP) -> None:
def __init__(self, hrp: Optional[str] = None) -> None:
"""All the addresses created with the factory have the same human readable part
Args:
hrp (str): the human readable part of the address (default: erd)"""
self.hrp = hrp
self.hrp = hrp if hrp else LibraryConfig.default_address_hrp

def create_from_bech32(self, value: str) -> Address:
"""Creates an address object from the bech32 representation of an address"""
Expand Down
11 changes: 11 additions & 0 deletions multiversx_sdk/core/address_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from multiversx_sdk.core.address import (Address, AddressComputer,
AddressFactory, is_valid_bech32)
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.errors import BadAddressError, BadPubkeyLengthError


Expand Down Expand Up @@ -78,3 +79,13 @@ def test_compute_contract_address():
contract_address = address_computer.compute_contract_address(deployer, deployment_nonce=1)
assert contract_address.to_hex() == "000000000000000005006e4f90488e27342f9a46e1809452c85ee7186566bd5e"
assert contract_address.to_bech32() == "erd1qqqqqqqqqqqqqpgqde8eqjywyu6zlxjxuxqfg5kgtmn3setxh40qen8egy"


def test_address_with_library_config_hrp():
address = Address(bytes.fromhex("0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"))
assert address.to_bech32() == "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"

LibraryConfig.default_address_hrp = "test"
address = Address(bytes.fromhex("0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"))
assert address.to_bech32() == "test1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ss5hqhtr"
LibraryConfig.default_address_hrp = "erd"
17 changes: 17 additions & 0 deletions multiversx_sdk/core/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from dataclasses import dataclass


@dataclass
class LibraryConfig:
"""
Global configuration of the library.
Generally speaking, this configuration should only be altered in exotic use cases.
It can be seen as a collection of constants or, more precisely, variables that are rarely changed and used throughout the library.
Never alter the configuration within a library!
Only alter the configuration, if needed, within a final application that uses this library.
"""

# The human-readable part of the bech32 addresses
default_address_hrp: str = "erd"
7 changes: 4 additions & 3 deletions multiversx_sdk/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
EGLD_TOKEN_IDENTIFIER = "EGLD"
EGLD_NUM_DECIMALS = 18

DELEGATION_MANAGER_SC_ADDRESS = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6"
DEFAULT_HRP = "erd"
CONTRACT_DEPLOY_ADDRESS = "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"
DELEGATION_MANAGER_SC_ADDRESS_HEX = "000000000000000000010000000000000000000000000000000000000004ffff"
CONTRACT_DEPLOY_ADDRESS_HEX = "0000000000000000000000000000000000000000000000000000000000000000"
ESDT_CONTRACT_ADDRESS_HEX = "000000000000000000010000000000000000000000000000000000000002ffff"

TRANSACTION_OPTIONS_TX_GUARDED = 0b0010
TRANSACTION_OPTIONS_TX_HASH_SIGN = 0b0001

Expand Down
8 changes: 4 additions & 4 deletions multiversx_sdk/core/transactions_factory_config.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from dataclasses import dataclass, field

from multiversx_sdk.core.address import Address
from multiversx_sdk.core.constants import DEFAULT_HRP
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.constants import ESDT_CONTRACT_ADDRESS_HEX


@dataclass
class TransactionsFactoryConfig:
# General-purpose configuration
chain_id: str
address_hrp: str = DEFAULT_HRP
address_hrp: str = LibraryConfig.default_address_hrp
min_gas_limit: int = 50_000
gas_limit_per_byte: int = 1_500

Expand Down Expand Up @@ -43,8 +44,7 @@ class TransactionsFactoryConfig:
gas_limit_stop_nft_create: int = 60_000_000
gas_limit_wipe_single_nft: int = 60_000_000
gas_limit_esdt_nft_add_uri: int = 10_000_000
esdt_contract_address: Address = field(default_factory=lambda: Address.new_from_bech32(
"erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"))
esdt_contract_address: Address = field(default_factory=lambda: Address.new_from_hex(value=ESDT_CONTRACT_ADDRESS_HEX))

# Configuration for delegation operations
gas_limit_stake: int = 5_000_000
Expand Down
4 changes: 2 additions & 2 deletions multiversx_sdk/delegation/delegation_transactions_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from multiversx_sdk.abi.string_value import StringValue
from multiversx_sdk.builders.transaction_builder import TransactionBuilder
from multiversx_sdk.core import Address, Transaction
from multiversx_sdk.core.constants import DELEGATION_MANAGER_SC_ADDRESS
from multiversx_sdk.core.constants import DELEGATION_MANAGER_SC_ADDRESS_HEX
from multiversx_sdk.core.interfaces import IValidatorPublicKey
from multiversx_sdk.core.transactions_factory_config import \
TransactionsFactoryConfig
Expand Down Expand Up @@ -34,7 +34,7 @@ def create_transaction_for_new_delegation_contract(self,
transaction = TransactionBuilder(
config=self.config,
sender=sender,
receiver=Address.new_from_bech32(DELEGATION_MANAGER_SC_ADDRESS),
receiver=Address.new_from_hex(DELEGATION_MANAGER_SC_ADDRESS_HEX),
data_parts=parts,
gas_limit=self.config.gas_limit_create_delegation_contract + self.config.additional_gas_for_delegation_operations,
add_data_movement_gas=True,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from multiversx_sdk.core import Address, TransactionsFactoryConfig
from multiversx_sdk.core.constants import DELEGATION_MANAGER_SC_ADDRESS
from multiversx_sdk.core.constants import DELEGATION_MANAGER_SC_ADDRESS_HEX
from multiversx_sdk.delegation import DelegationTransactionsFactory
from multiversx_sdk.wallet import ValidatorSecretKey, ValidatorSigner

Expand All @@ -17,7 +17,7 @@ def test_create_transaction_for_new_delegation_contract(self):
)

assert transaction.sender.to_bech32() == "erd18s6a06ktr2v6fgxv4ffhauxvptssnaqlds45qgsrucemlwc8rawq553rt2"
assert transaction.receiver.to_bech32() == DELEGATION_MANAGER_SC_ADDRESS
assert transaction.receiver.to_bech32() == Address.new_from_hex(DELEGATION_MANAGER_SC_ADDRESS_HEX).to_bech32()
assert transaction.data
assert transaction.data.decode() == "createNewDelegationContract@010f0cf064dd59200000@0a"
assert transaction.gas_limit == 60126500
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from multiversx_sdk.core import (Address, TransactionEvent,
TransactionOnNetwork,
find_events_by_identifier)
from multiversx_sdk.core.constants import DEFAULT_HRP
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.errors import ParseTransactionOnNetworkError
from multiversx_sdk.delegation.delegation_transactions_outcome_parser_types import \
CreateNewDelegationContractOutcome
Expand Down Expand Up @@ -29,4 +29,4 @@ def _ensure_no_error(self, transaction_events: list[TransactionEvent]) -> None:
def _extract_contract_address(self, event: TransactionEvent) -> Address:
if not event.topics[0]:
raise Exception("No topic found for contract address")
return Address(event.topics[0], DEFAULT_HRP)
return Address(event.topics[0], LibraryConfig.default_address_hrp)
5 changes: 3 additions & 2 deletions multiversx_sdk/network_providers/api_network_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from multiversx_sdk.core import (Address, Token, TokenComputer, Transaction,
TransactionOnNetwork)
from multiversx_sdk.core.constants import DEFAULT_HRP, METACHAIN_ID
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.constants import METACHAIN_ID
from multiversx_sdk.network_providers.account_awaiter import AccountAwaiter
from multiversx_sdk.network_providers.config import NetworkProviderConfig
from multiversx_sdk.network_providers.constants import (
Expand Down Expand Up @@ -44,7 +45,7 @@ def __init__(self,
address_hrp: Optional[str] = None,
config: Optional[NetworkProviderConfig] = None) -> None:
self.url = url
self.address_hrp = address_hrp or DEFAULT_HRP
self.address_hrp = address_hrp or LibraryConfig.default_address_hrp
self.backing_proxy = ProxyNetworkProvider(url, self.address_hrp)
self.config = config if config is not None else NetworkProviderConfig()

Expand Down
9 changes: 5 additions & 4 deletions multiversx_sdk/network_providers/proxy_network_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import requests

from multiversx_sdk.core.address import Address
from multiversx_sdk.core.constants import (DEFAULT_HRP, ESDT_CONTRACT_ADDRESS,
from multiversx_sdk.core.config import LibraryConfig
from multiversx_sdk.core.constants import (ESDT_CONTRACT_ADDRESS_HEX,
METACHAIN_ID)
from multiversx_sdk.core.tokens import Token
from multiversx_sdk.core.transaction import Transaction
Expand Down Expand Up @@ -51,7 +52,7 @@ def __init__(self,
address_hrp: Optional[str] = None,
config: Optional[NetworkProviderConfig] = None) -> None:
self.url = url
self.address_hrp = address_hrp or DEFAULT_HRP
self.address_hrp = address_hrp or LibraryConfig.default_address_hrp
self.config = config if config is not None else NetworkProviderConfig()

self.user_agent_prefix = f"{BASE_USER_AGENT}/proxy"
Expand Down Expand Up @@ -259,7 +260,7 @@ def get_definition_of_fungible_token(self, token_identifier: str) -> FungibleTok
"""Fetches the definition of a fungible token."""
encoded_identifier = token_identifier.encode()
query = SmartContractQuery(
contract=Address.new_from_bech32(ESDT_CONTRACT_ADDRESS),
contract=Address.new_from_hex(ESDT_CONTRACT_ADDRESS_HEX, self.address_hrp),
function="getTokenProperties",
arguments=[encoded_identifier],
)
Expand All @@ -273,7 +274,7 @@ def get_definition_of_tokens_collection(self, collection_name: str) -> TokensCol
"""Fetches the definition of a tokens collection."""
encoded_identifier = collection_name.encode()
query = SmartContractQuery(
contract=Address.new_from_bech32(ESDT_CONTRACT_ADDRESS),
contract=Address.new_from_hex(ESDT_CONTRACT_ADDRESS_HEX, self.address_hrp),
function="getTokenProperties",
arguments=[encoded_identifier],
)
Expand Down
Loading

0 comments on commit ab62322

Please sign in to comment.