diff --git a/stellar_contract_bindings/java.py b/stellar_contract_bindings/java.py index c300e91..7609226 100644 --- a/stellar_contract_bindings/java.py +++ b/stellar_contract_bindings/java.py @@ -138,7 +138,7 @@ def to_java_type(td: xdr.SCSpecTypeDef, input_type: bool = False): return "byte[]" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return "String" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return "Address" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") @@ -200,7 +200,7 @@ def to_scval(td: xdr.SCSpecTypeDef, name: str): return f"Scv.toString({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return f"Scv.toSymbol({name})" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return f"Scv.toAddress({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") @@ -257,7 +257,7 @@ def from_scval(td: xdr.SCSpecTypeDef, name: str): return f"Scv.fromString({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return f"Scv.fromSymbol({name})" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return f"Scv.fromAddress({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") diff --git a/stellar_contract_bindings/python.py b/stellar_contract_bindings/python.py index 5452dcf..12a3978 100644 --- a/stellar_contract_bindings/python.py +++ b/stellar_contract_bindings/python.py @@ -63,7 +63,7 @@ def to_py_type(td: xdr.SCSpecTypeDef, input_type: bool = False): return "bytes" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return "str" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return "Union[Address, str]" if input_type else "Address" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") @@ -125,7 +125,7 @@ def to_scval(td: xdr.SCSpecTypeDef, name: str): return f"scval.to_string({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return f"scval.to_symbol({name})" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return f"scval.to_address({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") @@ -185,7 +185,7 @@ def from_scval(td: xdr.SCSpecTypeDef, name: str): return f"scval.from_string({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_SYMBOL: return f"scval.from_symbol({name})" - if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS: + if t == xdr.SCSpecType.SC_SPEC_TYPE_ADDRESS or t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: return f"scval.from_address({name})" if t == xdr.SCSpecType.SC_SPEC_TYPE_MUXED_ADDRESS: raise NotImplementedError("SC_SPEC_TYPE_MUXED_ADDRESS is not supported") @@ -686,7 +686,7 @@ def command(contract_id: str, rpc_url: str, output: str, client_type: str): if __name__ == "__main__": from stellar_contract_bindings.metadata import parse_contract_metadata - wasm_file = "/Users/overcat/repo/lightsail/stellar-contract-bindings/tests/contracts/target/wasm32-unknown-unknown/release/python.wasm" + wasm_file = "/Users/overcat/repo/lightsail/stellar-contract-bindings/tests/contracts/target/wasm32v1-none/release/python.wasm" with open(wasm_file, "rb") as f: wasm = f.read() diff --git a/tests/client.py b/tests/client.py index 4e29a27..9052c00 100644 --- a/tests/client.py +++ b/tests/client.py @@ -677,6 +677,30 @@ def address( restore=restore, ) + def muxed_address( + self, + address: Union[Address, str], + source: Union[str, MuxedAccount] = NULL_ACCOUNT, + signer: Optional[Keypair] = None, + base_fee: int = 100, + transaction_timeout: int = 300, + submit_timeout: int = 30, + simulate: bool = True, + restore: bool = True, + ) -> AssembledTransaction[Address]: + return self.invoke( + "muxed_address", + [scval.to_address(address)], + parse_result_xdr_fn=lambda v: scval.from_address(v), + source=source, + signer=signer, + base_fee=base_fee, + transaction_timeout=transaction_timeout, + submit_timeout=submit_timeout, + simulate=simulate, + restore=restore, + ) + def bytes_( self, bytes_: bytes, @@ -1527,6 +1551,30 @@ async def address( restore=restore, ) + async def muxed_address( + self, + address: Union[Address, str], + source: Union[str, MuxedAccount] = NULL_ACCOUNT, + signer: Optional[Keypair] = None, + base_fee: int = 100, + transaction_timeout: int = 300, + submit_timeout: int = 30, + simulate: bool = True, + restore: bool = True, + ) -> AssembledTransactionAsync[Address]: + return await self.invoke( + "muxed_address", + [scval.to_address(address)], + parse_result_xdr_fn=lambda v: scval.from_address(v), + source=source, + signer=signer, + base_fee=base_fee, + transaction_timeout=transaction_timeout, + submit_timeout=submit_timeout, + simulate=simulate, + restore=restore, + ) + async def bytes_( self, bytes_: bytes, @@ -2034,4 +2082,4 @@ async def duration( submit_timeout=submit_timeout, simulate=simulate, restore=restore, - ) + ) \ No newline at end of file diff --git a/tests/contracts/contracts/python/src/lib.rs b/tests/contracts/contracts/python/src/lib.rs index 6e5bd25..c5b6d0f 100644 --- a/tests/contracts/contracts/python/src/lib.rs +++ b/tests/contracts/contracts/python/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, vec, Address, Bytes, BytesN, - Duration, Env, Map, String, Symbol, Timepoint, Val, Vec, I256, U256, + Duration, Env, Map, MuxedAddress, String, Symbol, Timepoint, Val, Vec, I256, U256, }; #[contract] @@ -154,6 +154,10 @@ impl Contract { address } + pub fn muxed_address(_env: Env, address: MuxedAddress) -> MuxedAddress { + address + } + pub fn bytes_(_env: Env, bytes_: Bytes) -> Bytes { bytes_ } diff --git a/tests/contracts/deploy_python_contract.py b/tests/contracts/deploy_python_contract.py index 2e978a8..a002c8d 100644 --- a/tests/contracts/deploy_python_contract.py +++ b/tests/contracts/deploy_python_contract.py @@ -19,5 +19,5 @@ print(f"WASM Uploaded, ID: {wasm_id.hex()}") contract_id = ContractClient.create_contract(wasm_id, kp.public_key, kp, soroban_server, - network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, salt=b'\x00' * 32) + network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE) print(f"Contract Created, ID: {contract_id}") diff --git a/tests/test_client.py b/tests/test_client.py index 85edb6e..c327cd9 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -6,7 +6,7 @@ from .client import * -CONTRACT_ID = "CB6JMERZBVZC54KPRFTUNEEQXQI7PTTIQNDDUVHBN5YDQH33OWAHDWTW" +CONTRACT_ID = "CDX62OSVWH2M6RECZXUCLG2YF4YMX3HIYSXMDEYUDAQPUQCMONYV46RX" RPC_URL = "https://soroban-testnet.stellar.org/" NETWORK_PASSPHRASE = Network.PUBLIC_NETWORK_PASSPHRASE @@ -127,6 +127,11 @@ def test_address(self): result = self.client.address(address) assert result.result() == address + def test_muxed_address(self): + address = Address("MBXCJUTSISFIAS2UENBBO4NXVBJDL7MQHHWM2MSM6S7N4BNNUAO2CAAAAAAAAAAAAHJ22") + result = self.client.muxed_address(address) + assert result.result() == address + def test_bytes(self): result = self.client.bytes_(b"123") assert result.result() == b"123" @@ -225,23 +230,20 @@ def test_duration(self): result = self.client.duration(123456789) assert result.result() == 123456789 - +@pytest.mark.asyncio class TestClientAsync: @pytest.fixture(autouse=True) def setup_method(self, event_loop): self.client = ClientAsync(CONTRACT_ID, RPC_URL, NETWORK_PASSPHRASE) - @pytest.mark.asyncio async def test_hello(self): result = await self.client.hello("overcat") assert result.result() == "overcat" - @pytest.mark.asyncio async def test_void(self): result = await self.client.void() assert result.result() is None - @pytest.mark.asyncio async def test_val(self): result = await self.client.val(0, scval.to_void()) assert result.result() == scval.to_bool(True) @@ -258,7 +260,6 @@ async def test_val(self): result = await self.client.val(255, scval.to_bytes(b"test")) assert result.result() == scval.to_bytes(b"test") - @pytest.mark.asyncio async def test_u32_fail_on_even(self): result = await self.client.u32_fail_on_even(1) assert result.result() == 1 @@ -266,45 +267,37 @@ async def test_u32_fail_on_even(self): with pytest.raises(SimulationFailedError): await self.client.u32_fail_on_even(2) - @pytest.mark.asyncio async def test_u32(self): result = await self.client.u32(34543534) assert result.result() == 34543534 - @pytest.mark.asyncio async def test_i32(self): result = await self.client.i32(-34543534) assert result.result() == -34543534 - @pytest.mark.asyncio async def test_u64(self): result = await self.client.u64(34543534) assert result.result() == 34543534 - @pytest.mark.asyncio async def test_i64(self): result = await self.client.i64(-34543534) assert result.result() == -34543534 - @pytest.mark.asyncio async def test_strukt_hel(self): strukt = SimpleStruct(123, True, "world") result = await self.client.strukt_hel(strukt) assert result.result() == ["Hello", "world"] - @pytest.mark.asyncio async def test_strukt(self): strukt = SimpleStruct(123, True, "world") result = await self.client.strukt(strukt) assert result.result() == strukt - @pytest.mark.asyncio async def test_simple(self): simple = SimpleEnum(SimpleEnumKind.Second) result = await self.client.simple(simple) assert result.result() == simple - @pytest.mark.asyncio async def test_complex_struct(self): complex_struct = ComplexEnum( ComplexEnumKind.Struct, struct=SimpleStruct(123, True, "world") @@ -312,7 +305,6 @@ async def test_complex_struct(self): result = await self.client.complex(complex_struct) assert result.result() == complex_struct - @pytest.mark.asyncio async def test_complex_tuple(self): complex_tuple = ComplexEnum( ComplexEnumKind.Tuple, @@ -323,7 +315,6 @@ async def test_complex_tuple(self): result = await self.client.complex(complex_tuple) assert result.result() == complex_tuple - @pytest.mark.asyncio async def test_complex_enum(self): complex_enum = ComplexEnum( ComplexEnumKind.Enum, enum=SimpleEnum(SimpleEnumKind.Second) @@ -331,7 +322,6 @@ async def test_complex_enum(self): result = await self.client.complex(complex_enum) assert result.result() == complex_enum - @pytest.mark.asyncio async def test_complex_asset(self): complex_asset = ComplexEnum( ComplexEnumKind.Asset, @@ -343,80 +333,70 @@ async def test_complex_asset(self): result = await self.client.complex(complex_asset) assert result.result() == complex_asset - @pytest.mark.asyncio async def test_complex_void(self): complex_void = ComplexEnum(ComplexEnumKind.Void) result = await self.client.complex(complex_void) assert result.result() == complex_void - @pytest.mark.asyncio async def test_address(self): address = Address("GBXCJUTSISFIAS2UENBBO4NXVBJDL7MQHHWM2MSM6S7N4BNNUAO2CWKF") result = await self.client.address(address) assert result.result() == address - @pytest.mark.asyncio + async def test_muxed_address(self): + address = Address("MBXCJUTSISFIAS2UENBBO4NXVBJDL7MQHHWM2MSM6S7N4BNNUAO2CAAAAAAAAAAAAHJ22") + result = await self.client.muxed_address(address) + assert result.result() == address + async def test_bytes(self): result = await self.client.bytes_(b"123") assert result.result() == b"123" - @pytest.mark.asyncio async def test_bytes_n(self): result = await self.client.bytes_n(b"123456789") assert result.result() == b"123456789" - @pytest.mark.asyncio async def test_card(self): card = RoyalCard.King result = await self.client.card(card) assert result.result() == card - @pytest.mark.asyncio async def test_boolean(self): result = await self.client.boolean(True) assert result.result() is True - @pytest.mark.asyncio async def test_not(self): result = await self.client.not_(True) assert result.result() is False - @pytest.mark.asyncio async def test_i128(self): result = await self.client.i128(-170141183460469231731687303715884105728) assert result.result() == -170141183460469231731687303715884105728 - @pytest.mark.asyncio async def test_u128(self): result = await self.client.u128(340282366920938463463374607431768211455) assert result.result() == 340282366920938463463374607431768211455 - @pytest.mark.asyncio async def test_multi_args(self): result = await self.client.multi_args(123, True) assert result.result() == 123 - @pytest.mark.asyncio async def test_map(self): result = await self.client.map({13: True, 62: False, 993: True}) assert result.result() == {13: True, 62: False, 993: True} - @pytest.mark.asyncio async def test_vec(self): result = await self.client.vec([13, 62, 993]) assert result.result() == [13, 62, 993] - @pytest.mark.asyncio async def test_tuple(self): result = await self.client.tuple(("hello", 100)) assert result.result() == ("hello", 100) - @pytest.mark.asyncio async def test_empty_tuple(self): result = await self.client.empty_tuple() assert result.result() is None - @pytest.mark.asyncio async def test_option(self): result = await self.client.option(None) assert result.result() is None @@ -424,7 +404,6 @@ async def test_option(self): result = await self.client.option(100) assert result.result() == 100 - @pytest.mark.asyncio async def test_u256(self): result = await self.client.u256( 115792089237316195423570985008687907853269984665640564039457584007913129639935 @@ -434,7 +413,6 @@ async def test_u256(self): == 115792089237316195423570985008687907853269984665640564039457584007913129639935 ) - @pytest.mark.asyncio async def test_i256(self): result = await self.client.i256( -57896044618658097711785492504343953926634992332820282019728792003956564819968 @@ -444,12 +422,10 @@ async def test_i256(self): == -57896044618658097711785492504343953926634992332820282019728792003956564819968 ) - @pytest.mark.asyncio async def test_string(self): result = await self.client.string(b"hello") assert result.result() == b"hello" - @pytest.mark.asyncio async def test_tuple_strukt(self): t = TupleStruct( (SimpleStruct(1, False, "hello"), SimpleEnum(SimpleEnumKind.First)) @@ -457,18 +433,15 @@ async def test_tuple_strukt(self): result = await self.client.tuple_strukt(t) assert result.result() == t - @pytest.mark.asyncio async def test_tuple_strukt_nested(self): t = (SimpleStruct(1, False, "hello"), SimpleEnum(SimpleEnumKind.First)) result = await self.client.tuple_strukt_nested(t) assert result.result() == t - @pytest.mark.asyncio async def test_timepoint(self): result = await self.client.timepoint(123456789) assert result.result() == 123456789 - @pytest.mark.asyncio async def test_duration(self): result = await self.client.duration(123456789) assert result.result() == 123456789