diff --git a/multiversx_sdk/abi/abi.py b/multiversx_sdk/abi/abi.py index c84a6fb8..f0baffde 100644 --- a/multiversx_sdk/abi/abi.py +++ b/multiversx_sdk/abi/abi.py @@ -88,7 +88,7 @@ def _create_custom_type_prototype(self, name: str) -> Any: definition = self.definition.types.structs[name] return self._create_struct_prototype(definition) - raise ValueError(f"cannot create prototype for custom type {name} not found") + raise ValueError(f"cannot create prototype for custom type {name}: definition not found") def _create_enum_prototype(self, enum_definition: EnumDefinition) -> Any: return EnumValue(fields_provider=lambda discriminant: self._provide_fields_for_enum_prototype(discriminant, enum_definition)) @@ -277,6 +277,8 @@ def _create_prototype(self, type_formula: TypeFormula) -> Any: return AddressValue() if name == "TokenIdentifier": return TokenIdentifierValue() + if name == "EgldOrEsdtTokenIdentifier": + return TokenIdentifierValue() if name == "CodeMetadata": return BytesValue() if name == "tuple": diff --git a/multiversx_sdk/core/transactions_factories/token_management_transactions_factory.py b/multiversx_sdk/core/transactions_factories/token_management_transactions_factory.py index 9519820a..062ca9c9 100644 --- a/multiversx_sdk/core/transactions_factories/token_management_transactions_factory.py +++ b/multiversx_sdk/core/transactions_factories/token_management_transactions_factory.py @@ -314,6 +314,34 @@ def create_transaction_for_setting_special_role_on_fungible_token( data_parts=parts ).build() + def create_transaction_for_unsetting_special_role_on_fungible_token( + self, + sender: IAddress, + user: IAddress, + token_identifier: str, + remove_role_local_mint: bool, + remove_role_local_burn: bool, + remove_role_esdt_transfer_role: bool + ) -> Transaction: + parts: List[str] = [ + "unSetSpecialRole", + arg_to_string(token_identifier), + user.to_hex(), + *([arg_to_string("ESDTRoleLocalMint")] if remove_role_local_mint else []), + *([arg_to_string("ESDTRoleLocalBurn")] if remove_role_local_burn else []), + *([arg_to_string("ESDTTransferRole")] if remove_role_esdt_transfer_role else []) + ] + + return TransactionBuilder( + config=self._config, + sender=sender, + receiver=self._config.esdt_contract_address, + amount=None, + gas_limit=self._config.gas_limit_set_special_role, + add_data_movement_gas=True, + data_parts=parts + ).build() + def create_transaction_for_setting_special_role_on_semi_fungible_token( self, sender: IAddress, @@ -354,6 +382,44 @@ def create_transaction_for_setting_special_role_on_semi_fungible_token( data_parts=parts ).build() + def create_transaction_for_unsetting_special_role_on_semi_fungible_token( + self, + sender: IAddress, + user: IAddress, + token_identifier: str, + remove_role_nft_burn: bool = False, + remove_role_nft_add_quantity: bool = False, + remove_role_esdt_transfer_role: bool = False, + remove_role_nft_update: bool = False, + remove_role_esdt_modify_royalties: bool = False, + remove_role_esdt_set_new_uri: bool = False, + remove_role_esdt_modify_creator: bool = False, + remove_role_nft_recreate: bool = False, + ) -> Transaction: + parts: List[str] = [ + "unSetSpecialRole", + arg_to_string(token_identifier), + user.to_hex(), + *([arg_to_string("ESDTRoleNFTBurn")] if remove_role_nft_burn else []), + *([arg_to_string("ESDTRoleNFTAddQuantity")] if remove_role_nft_add_quantity else []), + *([arg_to_string("ESDTTransferRole")] if remove_role_esdt_transfer_role else []), + *([arg_to_string("ESDTRoleNFTUpdate")] if remove_role_nft_update else []), + *([arg_to_string("ESDTRoleModifyRoyalties")] if remove_role_esdt_modify_royalties else []), + *([arg_to_string("ESDTRoleSetNewURI")] if remove_role_esdt_set_new_uri else []), + *([arg_to_string("ESDTRoleModifyCreator")] if remove_role_esdt_modify_creator else []), + *([arg_to_string("ESDTRoleNFTRecreate")] if remove_role_nft_recreate else []), + ] + + return TransactionBuilder( + config=self._config, + sender=sender, + receiver=self._config.esdt_contract_address, + amount=None, + gas_limit=self._config.gas_limit_set_special_role, + add_data_movement_gas=True, + data_parts=parts + ).build() + def create_transaction_for_setting_special_role_on_non_fungible_token( self, sender: IAddress, @@ -396,6 +462,46 @@ def create_transaction_for_setting_special_role_on_non_fungible_token( data_parts=parts, ).build() + def create_transaction_for_unsetting_special_role_on_non_fungible_token( + self, + sender: IAddress, + user: IAddress, + token_identifier: str, + remove_role_nft_burn: bool = False, + remove_role_nft_update_attributes: bool = False, + remove_role_nft_remove_uri: bool = False, + remove_role_esdt_transfer_role: bool = False, + remove_role_nft_update: bool = False, + remove_role_esdt_modify_royalties: bool = False, + remove_role_esdt_set_new_uri: bool = False, + remove_role_esdt_modify_creator: bool = False, + remove_role_nft_recreate: bool = False, + ) -> Transaction: + parts: List[str] = [ + "unSetSpecialRole", + arg_to_string(token_identifier), + user.to_hex(), + *([arg_to_string("ESDTRoleNFTBurn")] if remove_role_nft_burn else []), + *([arg_to_string("ESDTRoleNFTUpdateAttributes")] if remove_role_nft_update_attributes else []), + *([arg_to_string("ESDTRoleNFTAddURI")] if remove_role_nft_remove_uri else []), + *([arg_to_string("ESDTTransferRole")] if remove_role_esdt_transfer_role else []), + *([arg_to_string("ESDTRoleNFTUpdate")] if remove_role_nft_update else []), + *([arg_to_string("ESDTRoleModifyRoyalties")] if remove_role_esdt_modify_royalties else []), + *([arg_to_string("ESDTRoleSetNewURI")] if remove_role_esdt_set_new_uri else []), + *([arg_to_string("ESDTRoleModifyCreator")] if remove_role_esdt_modify_creator else []), + *([arg_to_string("ESDTRoleNFTRecreate")] if remove_role_nft_recreate else []), + ] + + return TransactionBuilder( + config=self._config, + sender=sender, + receiver=self._config.esdt_contract_address, + amount=None, + gas_limit=self._config.gas_limit_set_special_role, + add_data_movement_gas=True, + data_parts=parts, + ).build() + def create_transaction_for_creating_nft( self, sender: IAddress, diff --git a/multiversx_sdk/core/transactions_factories/token_management_transactions_factory_test.py b/multiversx_sdk/core/transactions_factories/token_management_transactions_factory_test.py index bae86609..d139e51d 100644 --- a/multiversx_sdk/core/transactions_factories/token_management_transactions_factory_test.py +++ b/multiversx_sdk/core/transactions_factories/token_management_transactions_factory_test.py @@ -134,6 +134,26 @@ def test_create_transaction_for_setting_special_role_on_non_fungible_token(): assert transaction.value == 0 +def test_create_transaction_for_unsetting_special_role_on_non_fungible_token(): + transaction = factory.create_transaction_for_unsetting_special_role_on_non_fungible_token( + sender=frank, + user=grace, + token_identifier="FRANK-11ce3e", + remove_role_nft_burn=False, + remove_role_nft_update_attributes=True, + remove_role_nft_remove_uri=True, + remove_role_esdt_transfer_role=False, + remove_role_esdt_modify_creator=True, + remove_role_nft_recreate=True + ) + + assert transaction.data + assert transaction.data.decode() == "unSetSpecialRole@4652414e4b2d313163653365@1e8a8b6b49de5b7be10aaa158a5a6a4abb4b56cc08f524bb5e6cd5f211ad3e13@45534454526f6c654e465455706461746541747472696275746573@45534454526f6c654e4654416464555249@45534454526f6c654d6f6469667943726561746f72@45534454526f6c654e46545265637265617465" + assert transaction.sender == frank.to_bech32() + assert transaction.receiver == "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u" + assert transaction.value == 0 + + def test_set_roles_on_nft(): transaction = factory.create_transaction_for_setting_special_role_on_non_fungible_token( sender=frank, @@ -203,6 +223,24 @@ def test_create_transaction_for_setting_special_role_on_fungible_token(): assert transaction.value == 0 +def test_create_transaction_for_unsetting_special_role_on_fungible_token(): + mint_role_as_hex = arg_to_string("ESDTRoleLocalMint") + + transaction = factory.create_transaction_for_unsetting_special_role_on_fungible_token( + sender=frank, + user=grace, + token_identifier="FRANK-11ce3e", + remove_role_local_mint=True, + remove_role_local_burn=False, + remove_role_esdt_transfer_role=False + ) + + assert transaction.data + assert transaction.data.decode() == f"unSetSpecialRole@4652414e4b2d313163653365@1e8a8b6b49de5b7be10aaa158a5a6a4abb4b56cc08f524bb5e6cd5f211ad3e13@{mint_role_as_hex}" + assert transaction.sender == frank.to_bech32() + assert transaction.value == 0 + + def test_set_all_roles_on_fungible_token(): mint_role_as_hex = arg_to_string("ESDTRoleLocalMint") burn_role_as_hex = arg_to_string("ESDTRoleLocalBurn") @@ -240,6 +278,22 @@ def test_create_transaction_for_setting_special_role_on_semi_fungible_token(): assert transaction.value == 0 +def test_create_transaction_for_unsetting_special_role_on_semi_fungible_token(): + transaction = factory.create_transaction_for_unsetting_special_role_on_semi_fungible_token( + sender=frank, + user=grace, + token_identifier="FRANK-11ce3e", + remove_role_nft_burn=True, + remove_role_nft_add_quantity=True, + remove_role_esdt_transfer_role=True, + ) + + assert transaction.data + assert transaction.data.decode() == "unSetSpecialRole@4652414e4b2d313163653365@1e8a8b6b49de5b7be10aaa158a5a6a4abb4b56cc08f524bb5e6cd5f211ad3e13@45534454526f6c654e46544275726e@45534454526f6c654e46544164645175616e74697479@455344545472616e73666572526f6c65" + assert transaction.sender == frank.to_bech32() + assert transaction.value == 0 + + def test_create_transaction_for_pausing(): transaction = factory.create_transaction_for_pausing( sender=frank, diff --git a/multiversx_sdk/core/transactions_outcome_parsers/transaction_events_parser_test.py b/multiversx_sdk/core/transactions_outcome_parsers/transaction_events_parser_test.py index e5efc63b..fa7a95c7 100644 --- a/multiversx_sdk/core/transactions_outcome_parsers/transaction_events_parser_test.py +++ b/multiversx_sdk/core/transactions_outcome_parsers/transaction_events_parser_test.py @@ -7,6 +7,7 @@ from multiversx_sdk.abi.abi_definition import AbiDefinition from multiversx_sdk.converters import TransactionsConverter from multiversx_sdk.core.address import Address +from multiversx_sdk.core.codec import encode_unsigned_number from multiversx_sdk.core.transactions_outcome_parsers.resources import ( SmartContractCallOutcome, SmartContractResult, TransactionEvent, TransactionLogs, TransactionOutcome, find_events_by_first_topic, @@ -156,14 +157,14 @@ def test_parse_event_with_multi_values(): identifier="foobar", topics=[ "doFoobar".encode(), - value.to_bytes(), + encode_unsigned_number(value), "test".encode(), - (value + 1).to_bytes(), + encode_unsigned_number(value + 1), "test".encode(), "test".encode(), - (value + 2).to_bytes() + encode_unsigned_number(value + 2), ], - data_items=[value.to_bytes()] + data_items=[encode_unsigned_number(value)] ) ) @@ -224,7 +225,7 @@ def test_multisig_start_perform_action(): api = ApiNetworkProvider("https://testnet-api.multiversx.com") converter = TransactionsConverter() - transaction_on_network = api.get_transaction("6f006c99e45525c94629db2442d9ca27ff088ad113a09f0a3a3e24bcc164945a") + transaction_on_network = api.get_transaction("69f63a246a65abad952fa052e105e2487fda98e765c318ed3a2af801efeb9818") transaction_outcome = converter.transaction_on_network_to_outcome(transaction_on_network) abi = Abi.load(testdata / "multisig-full.abi.json") @@ -238,9 +239,18 @@ def test_multisig_start_perform_action(): group_id=0, action_data=SimpleNamespace( **{ - "0": Address.new_from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th").get_public_key(), - '__discriminant__': 1 + "0": SimpleNamespace( + **{ + 'to': Address.new_from_bech32("erd1r69gk66fmedhhcg24g2c5kn2f2a5k4kvpr6jfw67dn2lyydd8cfswy6ede").get_public_key(), + 'egld_amount': 1000000000000000000, + 'opt_gas_limit': None, + 'endpoint_name': b'', + 'arguments': [] + } + ), + '__discriminant__': 5 }, ), - signers=[Address.new_from_bech32("erd18s6a06ktr2v6fgxv4ffhauxvptssnaqlds45qgsrucemlwc8rawq553rt2").get_public_key()] + signers=[Address.new_from_bech32("erd1kdl46yctawygtwg2k462307dmz2v55c605737dp3zkxh04sct7asqylhyv").get_public_key(), + Address.new_from_bech32("erd1r69gk66fmedhhcg24g2c5kn2f2a5k4kvpr6jfw67dn2lyydd8cfswy6ede").get_public_key()] ) diff --git a/multiversx_sdk/testutils/testdata/artificial.abi.json b/multiversx_sdk/testutils/testdata/artificial.abi.json index d8b0dbfe..af17c4d2 100644 --- a/multiversx_sdk/testutils/testdata/artificial.abi.json +++ b/multiversx_sdk/testutils/testdata/artificial.abi.json @@ -39,6 +39,17 @@ } ], "outputs": [] + }, + { + "name": "orange", + "mutability": "mutable", + "inputs": [ + { + "name": "value", + "type": "EgldOrEsdtTokenIdentifier" + } + ], + "outputs": [] } ], "types": {}, diff --git a/pyproject.toml b/pyproject.toml index 4b3b0e19..7bc5bc67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ allow-direct-references = true [project] name = "multiversx-sdk" -version = "0.11.0" +version = "0.11.1" authors = [ { name="MultiversX" }, ]