def test_native_asset(self): asset_1 = Asset("PMN") asset_2 = Asset.native() assert asset_1 == asset_2 assert asset_1.code == "PMN" assert asset_1.issuer is None assert asset_1.type == "native" assert asset_1.to_dict() == {"type": "native"}
def test_equals(self): assert Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ) == Asset("XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") assert Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ) != Asset("USD", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") assert (Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") != "BAD TYPE")
def test_credit_alphanum12_asset(self): code = "Banana" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum12" asset = Asset(code, issuer) assert asset.code == code assert asset.issuer == issuer assert asset.type == type assert asset.to_dict() == { "type": type, "code": code, "issuer": issuer }
def test_non_native_asset_without_issuer_raise(self, code): with pytest.raises( AssetIssuerInvalidError, match= "The issuer cannot be `None` except for the native asset.", ): Asset(code)
def test_already_signed_raise(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [ Payment(destination, asset, amount), ManageData("hello", "world") ] tx = Transaction(source, sequence, fee, ops, memo, time_bounds) te = TransactionEnvelope(tx, Network.PUBLIC_NETWORK_PASSPHRASE) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() # te.sign(source) te.sign("SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") hashx = bytes.fromhex( "94e8223a518ac16a8cb110ab1952ef14da2c10b264645c38c8b3d82bd2b20000") te.sign_hashx(hashx) with pytest.raises(SignatureExistError, match="The keypair has already signed."): te.sign(source) with pytest.raises(SignatureExistError, match="The preimage has already signed."): te.sign_hashx(hashx)
def test_to_xdr_v0(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [ Payment(destination, asset, amount), ManageData("hello", "world") ] tx = Transaction(source, sequence, fee, ops, memo, time_bounds, False) te = TransactionEnvelope(tx, Network.PUBLIC_NETWORK_PASSPHRASE) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() te.sign(source) hashx = bytes.fromhex( "94e8223a518ac16a8cb110ab1952ef14da2c10b264645c38c8b3d82bd2b20000") te.sign_hashx(hashx) te_xdr = "AAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAAyAAAAAAAAAABAAAAAQAAAAAAADA5AAAAAAAA3dUAAAACAAAAAAAAAGQAAAACAAAAAAAAAAEAAAAA0pjFgVcRZZHpMgnpXHpb/xIbLh0/YYto0PzI7+Xl5HAAAAAAAAAAAlQL5AAAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAFd29ybGQAAAAAAAAAAAAAAvKHnQkAAABAM4dg0J1LEFBmbDESJ5d+60WCuZC8lnA80g45qyEgz2oRBSNw1mOfZETnL/BgrebkG/K03oI2Wqcs9lvDKrDGDE0sOBsAAAAglOgiOlGKwWqMsRCrGVLvFNosELJkZFw4yLPYK9KyAAA=" assert te.to_xdr() == te_xdr restore_te = TransactionEnvelope.from_xdr( te_xdr, Network.PUBLIC_NETWORK_PASSPHRASE) assert restore_te.to_xdr() == te_xdr
def test_invalid_code(self, code): with pytest.raises( AssetCodeInvalidError, match= r"Asset code is invalid \(maximum alphanumeric, 12 characters at max\).", ): Asset(code, "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ")
def test_from_xdr_object_alphanum12(self): code = "Banana" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum12" asset_code = kuknos_xdr.AssetCode12( bytearray(code, "ascii") + b"\x00" * (12 - len(code))) asset = kuknos_xdr.AssetAlphaNum12( asset_code=asset_code, issuer=Keypair.from_public_key(issuer).xdr_account_id(), ) xdr = kuknos_xdr.Asset( type=kuknos_xdr.AssetType.ASSET_TYPE_CREDIT_ALPHANUM12, alpha_num12=asset) asset = Asset.from_xdr_object(xdr) assert asset.code == code assert asset.issuer == issuer assert asset.type == type
def test_to_xdr_v1(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [Payment(destination, asset, amount)] tx = Transaction(source, sequence, fee, ops, memo, time_bounds, True) te = TransactionEnvelope(tx, Network.PUBLIC_NETWORK_PASSPHRASE) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() te.sign(source) te_xdr = "AAAAAgAAAADL13HWIyocdKsZ7A7HM8Srqmv+uZWc+rI4xx3M8oedCQAAAMgAAAAAAAAAAQAAAAEAAAAAAAAwOQAAAAAAAN3VAAAAAgAAAAAAAABkAAAAAQAAAAAAAAABAAAAANKYxYFXEWWR6TIJ6Vx6W/8SGy4dP2GLaND8yO/l5eRwAAAAAAAAAAJUC+QAAAAAAAAAAAHyh50JAAAAQCXOQnmno3he687bKRtDc6+BXRUf8t+RnTuHy+sKf35UjfFiQbIge+txehmg0N61JsFWfwbL0JtgOjzyeZw5JAs=" assert te.to_xdr() == te_xdr restore_te = TransactionEnvelope.from_xdr( te_xdr, Network.PUBLIC_NETWORK_PASSPHRASE) assert restore_te.to_xdr() == te_xdr
class TestAsset: @pytest.mark.parametrize("code", ["XCN", "Banana"]) def test_non_native_asset_without_issuer_raise(self, code): with pytest.raises( AssetIssuerInvalidError, match= "The issuer cannot be `None` except for the native asset.", ): Asset(code) @pytest.mark.parametrize("code", ["", "1234567890123", "ab_"]) def test_invalid_code(self, code): with pytest.raises( AssetCodeInvalidError, match= r"Asset code is invalid \(maximum alphanumeric, 12 characters at max\).", ): Asset(code, "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ") @pytest.mark.parametrize( "issuer", [ "", "GCEZWKCA5", "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS67BAD" ], ) def test_invalid_issuer(self, issuer): with pytest.raises(AssetIssuerInvalidError, match="The issuer should be a correct public key."): Asset("XCN", issuer) def test_native_asset(self): asset_1 = Asset("PMN") asset_2 = Asset.native() assert asset_1 == asset_2 assert asset_1.code == "PMN" assert asset_1.issuer is None assert asset_1.type == "native" assert asset_1.to_dict() == {"type": "native"} def test_credit_alphanum4_asset(self): code = "XCN" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum4" asset = Asset(code, issuer) assert asset.code == code assert asset.issuer == issuer assert asset.type == type assert asset.to_dict() == { "type": type, "code": code, "issuer": issuer } def test_credit_alphanum12_asset(self): code = "Banana" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum12" asset = Asset(code, issuer) assert asset.code == code assert asset.issuer == issuer assert asset.type == type assert asset.to_dict() == { "type": type, "code": code, "issuer": issuer } def test_set_type_raise(self): asset = Asset.native() with pytest.raises(AttributeError, match="Asset type is immutable."): asset.type = "credit_alphanum4" def test_equals(self): assert Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ) == Asset("XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") assert Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ) != Asset("USD", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") assert (Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY") != "BAD TYPE") @pytest.mark.parametrize( "asset, xdr", [ pytest.param(Asset.native(), "AAAAAA==", id="native"), pytest.param( Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ), "AAAAAVhDTgAAAAAAm466+JY4VR3PnqT3QyBxEGuHqw4ts9abdaU4InL3Wdg=", id="alphanum4", ), pytest.param( Asset( "CATCOIN", "GDJVFDG5OCW5PYWHB64MGTHGFF57DRRJEDUEFDEL2SLNIOONHYJWHA3Z", ), "AAAAAkNBVENPSU4AAAAAAAAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYw==", id="alphanum12", ), ], ) def test_to_xdr_object(self, asset, xdr): assert asset.to_xdr_object().to_xdr() == xdr def test_from_xdr_object_native(self): xdr_type = kuknos_xdr.AssetType.ASSET_TYPE_NATIVE xdr = kuknos_xdr.Asset(type=xdr_type) asset = Asset.from_xdr_object(xdr) assert asset.is_native() def test_from_xdr_object_alphanum4(self): code = "XCN" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum4" asset_code = kuknos_xdr.AssetCode4( bytearray(code, "ascii") + b"\x00" * (4 - len(code))) asset = kuknos_xdr.AssetAlphaNum4( asset_code=asset_code, issuer=Keypair.from_public_key(issuer).xdr_account_id(), ) xdr = kuknos_xdr.Asset( type=kuknos_xdr.AssetType.ASSET_TYPE_CREDIT_ALPHANUM4, alpha_num4=asset) asset = Asset.from_xdr_object(xdr) assert asset.code == code assert asset.issuer == issuer assert asset.type == type def test_from_xdr_object_alphanum12(self): code = "Banana" issuer = "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" type = "credit_alphanum12" asset_code = kuknos_xdr.AssetCode12( bytearray(code, "ascii") + b"\x00" * (12 - len(code))) asset = kuknos_xdr.AssetAlphaNum12( asset_code=asset_code, issuer=Keypair.from_public_key(issuer).xdr_account_id(), ) xdr = kuknos_xdr.Asset( type=kuknos_xdr.AssetType.ASSET_TYPE_CREDIT_ALPHANUM12, alpha_num12=asset) asset = Asset.from_xdr_object(xdr) assert asset.code == code assert asset.issuer == issuer assert asset.type == type
def test_set_type_raise(self): asset = Asset.native() with pytest.raises(AttributeError, match="Asset type is immutable."): asset.type = "credit_alphanum4"
def test_invalid_issuer(self, issuer): with pytest.raises(AssetIssuerInvalidError, match="The issuer should be a correct public key."): Asset("XCN", issuer)
def test_from_xdr_object_native(self): xdr_type = kuknos_xdr.AssetType.ASSET_TYPE_NATIVE xdr = kuknos_xdr.Asset(type=xdr_type) asset = Asset.from_xdr_object(xdr) assert asset.is_native()
def test_endpoint(self): horizon_url = "https://horizon.kuknos.org" client = RequestsClient() with Server(horizon_url, client) as server: assert server.accounts() == AccountsCallBuilder(horizon_url, client) assert server.assets() == AssetsCallBuilder(horizon_url, client) assert server.claimable_balances() == ClaimableBalancesCallBuilder( horizon_url, client ) assert server.data( "GDV6FVHPY4JH7EEBSJYPQQYZA3OC6TKTM2TAXRHWT4EEL7BJ2BTDQT5D", "hello" ) == DataCallBuilder( horizon_url, client, "GDV6FVHPY4JH7EEBSJYPQQYZA3OC6TKTM2TAXRHWT4EEL7BJ2BTDQT5D", "hello", ) assert server.effects() == EffectsCallBuilder(horizon_url, client) assert server.fee_stats() == FeeStatsCallBuilder(horizon_url, client) assert server.ledgers() == LedgersCallBuilder(horizon_url, client) assert server.offers() == OffersCallBuilder(horizon_url, client) assert server.operations() == OperationsCallBuilder(horizon_url, client) buying = Asset.native() selling = Asset( "MOE", "GDV6FVHPY4JH7EEBSJYPQQYZA3OC6TKTM2TAXRHWT4EEL7BJ2BTDQT5D" ) assert server.orderbook(buying, selling) == OrderbookCallBuilder( horizon_url, client, buying, selling ) source = "GAYSHLG75RPSMXWJ5KX7O7STE6RSZTD6NE4CTWAXFZYYVYIFRUVJIBJH" destination_asset = Asset( "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN" ) destination_amount = "20.0" assert server.strict_receive_paths( source, destination_asset, destination_amount ) == StrictReceivePathsCallBuilder( horizon_url, client, source, destination_asset, destination_amount ) source_asset = Asset( "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN" ) source_amount = "10.25" destination = "GARSFJNXJIHO6ULUBK3DBYKVSIZE7SC72S5DYBCHU7DKL22UXKVD7MXP" assert server.strict_send_paths( source_asset, source_amount, destination ) == StrictSendPathsCallBuilder( horizon_url, client, source_asset, source_amount, destination ) assert server.payments() == PaymentsCallBuilder(horizon_url, client) assert server.root() == RootCallBuilder(horizon_url, client) base = Asset.native() counter = Asset( "MOE", "GDV6FVHPY4JH7EEBSJYPQQYZA3OC6TKTM2TAXRHWT4EEL7BJ2BTDQT5D" ) resolution = 3600000 start_time = 1565272000000 end_time = 1565278000000 offset = 3600000 assert server.trade_aggregations( base, counter, resolution, start_time, end_time, offset ) == TradeAggregationsCallBuilder( horizon_url, client, base, counter, resolution, start_time, end_time, offset, ) assert server.trades() == TradesCallBuilder(horizon_url, client) assert server.transactions() == TransactionsCallBuilder(horizon_url, client)
# Keys for accounts to issue and receive the new asset issuing_keypair = Keypair.from_secret( "SCBHQEGSNBTT4S7Y73YAF3M3JSVSTSNBGAVU5M4XVFGUF7664EUXQHFU") issuing_public = issuing_keypair.public_key distributor_keypair = Keypair.from_secret( "SB6MJ6M3BPJZUGFP2QCODUIKWQWF6AIN4Z6L3J6PWL3QGDW4L6YR3QIU") distributor_public = distributor_keypair.public_key # Transactions require a valid sequence number that is specific to this account. # We can fetch the current sequence number for the source account from Horizon. distributor_account = server.load_account(distributor_public) # Create an object to represent the new asset hello_asset = Asset("Hello", issuing_public) # First, the receiving account must trust the asset trust_transaction = (TransactionBuilder( source_account=distributor_account, network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, base_fee=100, ).append_change_trust_op(asset_code=hello_asset.code, asset_issuer=hello_asset.issuer).build()) trust_transaction.sign(distributor_keypair) resp = server.submit_transaction(trust_transaction) print(f"Change Trust Op Resp:\n{resp}") print("-" * 32) issuing_account = server.load_account(issuing_public)