def test_to_xdr_v1(self):
        source = Keypair.from_public_key(
            "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ")
        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, True)
        tx_object = tx.to_xdr_object()
        assert (
            tx_object.to_xdr() ==
            "AAAAAImbKEDtVjbFbdxfFLI5dfefG6I4jSaU5MVuzd3JYOXvAAAAyAAAAAAAAAABAAAAAQAAAAAAADA5AAAAAAAA3dUAAAACAAAAAAAAAGQAAAACAAAAAAAAAAEAAAAA0pjFgVcRZZHpMgnpXHpb/xIbLh0/YYto0PzI7+Xl5HAAAAAAAAAAAlQL5AAAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAFd29ybGQAAAAAAAAA"
        )

        restore_transaction = Transaction.from_xdr_object(tx_object, v1=True)
        assert isinstance(restore_transaction, Transaction)
        assert restore_transaction.source == Keypair.from_public_key(
            source.public_key)
        assert restore_transaction.fee == fee
        assert restore_transaction.memo == memo
        assert restore_transaction.time_bounds == time_bounds
        assert restore_transaction.sequence == sequence
        assert restore_transaction == tx
示例#2
0
 def test_tx_fee_less_than_base_fee(self):
     inner_keypair = Keypair.from_secret(
         "SBKTIFHJSS3JJWEZO2W74DZSA45WZU56LOL3AY7GAW63BXPEJQFYV53E")
     inner_source = Account(inner_keypair.public_key, 7)
     destination = "GDQERENWDDSQZS7R7WKHZI3BSOYMV3FSWR7TFUYFTKQ447PIX6NREOJM"
     amount = "2000.0000000"
     inner_tx = (TransactionBuilder(inner_source,
                                    Network.TESTNET_NETWORK_PASSPHRASE,
                                    50,
                                    v1=True).append_payment_op(
                                        destination=destination,
                                        amount=amount,
                                        asset_code="PMN").add_time_bounds(
                                            0, 0).build())
     inner_tx.sign(inner_keypair)
     fee_source = Keypair.from_secret(
         "SB7ZMPZB3YMMK5CUWENXVLZWBK4KYX4YU5JBXQNZSK2DP2Q7V3LVTO5V")
     base_fee = 60
     with pytest.raises(
             ValueError,
             match="Invalid `base_fee`, it should be at least 100 stroops.",
     ):
         TransactionBuilder.build_fee_bump_transaction(
             fee_source.public_key,
             base_fee,
             inner_tx,
             Network.TESTNET_NETWORK_PASSPHRASE,
         )
    def test_to_xdr_str_source_muxed_v1(self):
        source = "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ"
        source2 = "GDL635DMMORJHKEHHQIIB4VPYM6YGEMPLORYHHM2DEHAUOUXLSTMHQDV"
        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, True)
        tx_object = tx.to_xdr_object()
        restore_tx = Transaction.from_xdr_object(tx_object, v1=True)
        assert restore_tx.to_xdr_object().to_xdr() == tx_object.to_xdr()
        assert restore_tx.source == Keypair.from_public_key(source)
        assert (restore_tx._source_muxed.to_xdr() == Keypair.from_public_key(
            source).xdr_muxed_account().to_xdr())
        assert restore_tx == tx
        restore_tx.source = source2
        assert restore_tx.source == Keypair.from_public_key(source2)
        assert restore_tx._source_muxed is None
        assert restore_tx != tx
 async def test_check_memo_required_with_fee_bump_transaction_async(
         self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     async with Server(horizon_url, AiohttpClient()) as server:
         transaction = (TransactionBuilder(
             account, v1=True).append_payment_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_A, "10", "PMN"
             ).append_path_payment_strict_send_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_C,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_account_merge_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_D).add_text_memo(
                     "hello, world").build())
         transaction.sign(keypair)
         fee_bump_tx = TransactionBuilder.build_fee_bump_transaction(
             fee_source=Keypair.random().public_key,
             base_fee=200,
             inner_transaction_envelope=transaction,
             network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
         )
         await server.submit_transaction(fee_bump_tx)
 async def test_check_memo_required_with_memo_muxed_account_async(
         self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     async with Server(horizon_url, AiohttpClient()) as server:
         transaction = (TransactionBuilder(account).append_payment_op(
             self.DESTINATION_ACCOUNT_MEMO_REQUIRED_A, "10",
             "PMN").append_path_payment_strict_receive_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_B,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_path_payment_strict_send_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_C,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_account_merge_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_D).add_text_memo(
                     "hello, world").build())
         transaction.sign(keypair)
         await server.submit_transaction(transaction)
 async def test_check_memo_required_with_fetch_account_error_raise_async(
         self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     async with Server(horizon_url, AiohttpClient()) as server:
         transaction = (TransactionBuilder(account).append_payment_op(
             self.DESTINATION_ACCOUNT_FETCH_ERROR, "10",
             "PMN").append_path_payment_strict_receive_op(
                 self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_path_payment_strict_send_op(
                 self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_account_merge_op(
                 self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED).build())
         transaction.sign(keypair)
         with pytest.raises(BadRequestError) as err:
             await server.submit_transaction(transaction)
         assert err.value.status == 400
 def test_check_memo_required_with_account_not_found_sync(self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     server = Server(horizon_url)
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     transaction = (TransactionBuilder(account).append_payment_op(
         self.DESTINATION_ACCOUNT_NO_FOUND, "10",
         "PMN").append_path_payment_strict_receive_op(
             self.DESTINATION_ACCOUNT_NO_FOUND,
             "PMN",
             None,
             "10",
             "BTC",
             "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
             "1",
             [],
         ).append_path_payment_strict_send_op(
             self.DESTINATION_ACCOUNT_NO_FOUND,
             "PMN",
             None,
             "10",
             "BTC",
             "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
             "1",
             [],
         ).append_account_merge_op(
             self.DESTINATION_ACCOUNT_NO_FOUND).build())
     transaction.sign(keypair)
     server.submit_transaction(transaction)
示例#8
0
 def test_to_txrep_return_memo(self):
     keypair = Keypair.from_secret(
         "SAHGKA7QJB6SRFDZSPZDEEIOEHUHTQS4XVN4IMR5YCKBPEN5A6YNKKUO")
     account = Account(keypair.public_key, 46489056724385792)
     transaction_builder = TransactionBuilder(
         source_account=account,
         network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
         base_fee=100,
     )
     transaction_builder.add_return_hash_memo(
         "ef14f82df770697f56789b4db4e59d1ece902484739ba167cf99fae319ebcc34")
     transaction_builder.add_time_bounds(1535756672, 1567292672)
     transaction_builder.append_payment_op(
         destination=
         "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
         asset_code="USD",
         asset_issuer=
         "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
         amount="40.0004",
         source=keypair.public_key,
     )
     te = transaction_builder.build()
     te.sign(keypair)
     txrep = to_txrep(te)
     assert txrep == get_txrep_file("test_to_txrep_return_memo.txt")
     assert (from_txrep(
         txrep, Network.TESTNET_NETWORK_PASSPHRASE).to_xdr() == te.to_xdr())
示例#9
0
 def test_to_txrep_fullline_comment(self):
     keypair = Keypair.from_secret(
         "SAHGKA7QJB6SRFDZSPZDEEIOEHUHTQS4XVN4IMR5YCKBPEN5A6YNKKUO")
     account = Account(keypair.public_key, 46489056724385792)
     transaction_builder = TransactionBuilder(
         source_account=account,
         network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
         base_fee=100,
     )
     transaction_builder.add_text_memo("Enjoy this transaction")
     transaction_builder.add_time_bounds(1535756672, 1567292672)
     transaction_builder.append_payment_op(
         destination=
         "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
         asset_code="USD",
         asset_issuer=
         "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
         amount="40.0004",
         source=keypair.public_key,
     )
     te = transaction_builder.build()
     te.sign(keypair)
     txrep = to_txrep(te)
     file_txrep = get_txrep_file("test_to_txrep_fullline_comment.txt")
     assert txrep == to_txrep(
         from_txrep(file_txrep, Network.TESTNET_NETWORK_PASSPHRASE))
示例#10
0
    def test_to_source_muxed_xdr(self):
        inner_keypair = Keypair.from_secret(
            "SBKTIFHJSS3JJWEZO2W74DZSA45WZU56LOL3AY7GAW63BXPEJQFYV53E")
        inner_source = Account(inner_keypair.public_key, 7)
        destination = "GDQERENWDDSQZS7R7WKHZI3BSOYMV3FSWR7TFUYFTKQ447PIX6NREOJM"
        amount = "2000.0000000"
        inner_tx = (TransactionBuilder(inner_source,
                                       Network.TESTNET_NETWORK_PASSPHRASE,
                                       200,
                                       v1=True).append_payment_op(
                                           destination=destination,
                                           amount=amount,
                                           asset_code="PMN").add_time_bounds(
                                               0, 0).build())
        inner_tx.sign(inner_keypair)
        fee_source = Keypair.from_secret(
            "SB7ZMPZB3YMMK5CUWENXVLZWBK4KYX4YU5JBXQNZSK2DP2Q7V3LVTO5V")
        fee_source2 = Keypair.from_secret(
            "SCVFDAOOXWR5TSPZF5U2MIE6V7M4LTOCNCD624Q6AEVBZ2XMH7HOWFZL")
        base_fee = 200
        fee_bump_tx = TransactionBuilder.build_fee_bump_transaction(
            fee_source.public_key,
            base_fee,
            inner_tx,
            Network.TESTNET_NETWORK_PASSPHRASE,
        )
        fee_bump_tx.sign(fee_source)
        xdr = "AAAABQAAAADgSJG2GOUMy/H9lHyjYZOwyuyytH8y0wWaoc596L+bEgAAAAAAAAGQAAAAAgAAAAAcVPE+R/n1VnbIrAK3tu5yVfTkhkqVz04ShWk2SrF3wAAAAMgAAAAAAAAACAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAADgSJG2GOUMy/H9lHyjYZOwyuyytH8y0wWaoc596L+bEgAAAAAAAAAEqBfIAAAAAAAAAAABSrF3wAAAAEAordQh63kT50muRLVYaWW7Pgtt8i1tc4t9Bv9MWFWFN3WfTHSU2Jxv7hedjZEyfBPvaS/XnwvYJFcHgPDd1JkNAAAAAAAAAAHov5sSAAAAQKu/RuArXn/P13IIJ8WlnVDStwOquXM0CsWzA4ooZY6gqJ3k1EfmMVIJ0cir0bMTJD9r+g2IUZCANU7wdC38PA0="

        assert fee_bump_tx.to_xdr() == xdr
        restore_te = FeeBumpTransactionEnvelope.from_xdr(
            xdr, Network.TESTNET_NETWORK_PASSPHRASE)
        assert restore_te == fee_bump_tx
        assert restore_te.transaction == fee_bump_tx.transaction
        assert restore_te.transaction == FeeBumpTransaction.from_xdr(
            fee_bump_tx.transaction.to_xdr_object().to_xdr(),
            Network.TESTNET_NETWORK_PASSPHRASE,
        )
        assert (restore_te.to_xdr() == TransactionBuilder.from_xdr(
            xdr, Network.TESTNET_NETWORK_PASSPHRASE).to_xdr())
        assert (restore_te.transaction._fee_source_muxed.to_xdr() ==
                fee_source.xdr_muxed_account().to_xdr())
        restore_te.transaction.fee_source = fee_source2.public_key
        assert restore_te.transaction.fee_source.public_key == fee_source2.public_key
        assert restore_te.transaction._fee_source_muxed is None
 async def test_check_memo_required_with_no_destination_operation_async(
         self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     async with Server(horizon_url, AiohttpClient()) as server:
         transaction = (TransactionBuilder(account).append_manage_data_op(
             "Hello", "world").build())
         transaction.sign(keypair)
         await server.submit_transaction(transaction)
    def test_none_memo_v1(self):
        source = Keypair.from_public_key(
            "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ")
        destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2"
        amount = "1000.0"
        sequence = 1
        fee = 200
        asset = Asset.native()
        ops = [
            Payment(destination, asset, amount),
            ManageData("hello", "world")
        ]

        tx = Transaction(source, sequence, fee, ops)
        assert tx.memo == NoneMemo()
示例#13
0
    def test_to_txrep_fee_bump(self):
        keypair = Keypair.from_secret(
            "SAHGKA7QJB6SRFDZSPZDEEIOEHUHTQS4XVN4IMR5YCKBPEN5A6YNKKUO")
        account = Account(keypair.public_key, 46489056724385792)
        transaction_builder = TransactionBuilder(
            source_account=account,
            network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
            base_fee=100,
        )
        transaction_builder.add_text_memo("Enjoy this transaction")
        transaction_builder.add_time_bounds(1535756672, 1567292672)
        transaction_builder.append_payment_op(
            destination=
            "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
            asset_code="USD",
            asset_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            amount="40.0004",
            source=keypair.public_key,
        )
        inner_tx = transaction_builder.build()
        inner_tx.sign(keypair)
        fee_source_keypair = Keypair.from_secret(
            "SASZKBDB6PFHXN6LRH4NQNTRGLGDTI3PSUVIKMZMLTYYBB7NDVMA6DSL")

        fee_bump_tx = TransactionBuilder.build_fee_bump_transaction(
            fee_source=fee_source_keypair,
            base_fee=200,
            inner_transaction_envelope=inner_tx,
            network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
        )
        fee_bump_tx.sign(fee_source_keypair)
        txrep = to_txrep(fee_bump_tx)
        assert txrep == get_txrep_file("test_to_txrep_fee_bump.txt")
        assert (from_txrep(txrep, Network.TESTNET_NETWORK_PASSPHRASE).to_xdr()
                == fee_bump_tx.to_xdr())
 async def test_check_memo_required_with_two_operation_with_same_destination_async(
         self, httpserver):
     self.__inject_mock_server(httpserver)
     horizon_url = httpserver.url_for("/")
     keypair = Keypair.from_secret(
         "SDQXFKA32UVQHUTLYJ42N56ZUEM5PNVVI4XE7EA5QFMLA2DHDCQX3GPY")
     account = Account(keypair.public_key, 1)
     async with Server(horizon_url, AiohttpClient()) as server:
         transaction = (TransactionBuilder(account).append_payment_op(
             self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED, "10",
             "PMN").append_path_payment_strict_receive_op(
                 self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_path_payment_strict_send_op(
                 self.DESTINATION_ACCOUNT_NO_MEMO_REQUIRED,
                 "PMN",
                 None,
                 "10",
                 "BTC",
                 "GA7GYB3QGLTZNHNGXN3BMANS6TC7KJT3TCGTR763J4JOU4QHKL37RVV2",
                 "1",
                 [],
             ).append_account_merge_op(
                 self.DESTINATION_ACCOUNT_MEMO_REQUIRED_D).build())
         transaction.sign(keypair)
         with pytest.raises(
                 AccountRequiresMemoError,
                 match=
                 "Destination account requires a memo in the transaction.",
         ) as err:
             await server.submit_transaction(transaction)
         assert err.value.account_id == self.DESTINATION_ACCOUNT_MEMO_REQUIRED_D
         assert err.value.operation_index == 3
    def test_to_xdr_v0(self):
        source = Keypair.from_public_key(
            "GC3GJU6L7V7ZLPLKG3NTMC6GYYKBMNNKCPP36FG3LWEVPOHUPY6QJIGL")
        destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2"
        amount = "1000.0"
        sequence = 2
        memo = NoneMemo()
        fee = 200
        asset = Asset.native()
        time_bounds = TimeBounds(12345, 56789)
        ops = [Payment(destination, asset, amount)]
        tx = Transaction(source, sequence, fee, ops, memo, time_bounds, False)
        tx_object = tx.to_xdr_object()

        restore_transaction = Transaction.from_xdr_object(tx_object, False)
        assert isinstance(restore_transaction, Transaction)
        assert restore_transaction.source == source
        assert restore_transaction.fee == fee
        assert restore_transaction.memo == memo
        assert restore_transaction.time_bounds == time_bounds
        assert restore_transaction.sequence == sequence
        assert restore_transaction == tx
示例#16
0
from kuknos_sdk import Server, TransactionBuilder, Keypair, Network
from kuknos_sdk.exceptions import NotFoundError
from kuknos_sdk.sep.exceptions import InvalidSep10ChallengeError
from kuknos_sdk.sep.kuknos_web_authentication import build_challenge_transaction, read_challenge_transaction, \
    verify_challenge_transaction_threshold, verify_challenge_transaction_signed_by_client_master_key

server_keypair = Keypair.from_secret(
    "SBGCNEOQGECW5R4A55C26ZFS736IONKCHY5PPPSFZVXSJSU63MWNM4K6")
client_master_keypair = Keypair.from_secret(
    "SDWZHXKWSHTQ2YGPT6YQQSOJWJX5JX2IEU7KOLGQ2XEJEECIQHUU3RMR")
client_signer_keypair1 = Keypair.from_secret(
    "SCKJFEF2H767XINUY5YFBORUO7AAWOAXSTQ2B2YHSI6N4UF23HFV42I7")
client_signer_keypair2 = Keypair.from_secret(
    "SCE2JBZ6FKPTQ5LM4X4NIZOOZPIC5DXVG6VP2TKSBZCQAGXABJV55IN5")

server = Server("https://hz1-test.kuknos.org")
home_domain = "example.com"
web_auth_domain = "auth.example.com"
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE


def setup_multisig():
    client_master_account = server.load_account(
        client_master_keypair.public_key)
    te = TransactionBuilder(client_master_account, network_passphrase) \
        .append_ed25519_public_key_signer(client_signer_keypair1.public_key, 40) \
        .append_ed25519_public_key_signer(client_signer_keypair2.public_key, 60) \
        .append_set_options_op(master_weight=0, low_threshold=1, med_threshold=10, high_threshold=100) \
        .build()
    te.sign(client_master_keypair)
    resp = server.submit_transaction(te)
示例#17
0
Assumes that you have the following items:
1. Secret key of a funded account to be the source account
2. Public key of an existing account as a recipient
    These two keys can be created and funded by the friendbot at
    https://www.kuknos.org/laboratory/ under the heading "Quick Start: Test Account"
3. Access to Python Kuknos SDK (https://github.com/javadnikbakht/py-kuknos-base) through Python shell.
"""
import asyncio

from kuknos_sdk import Server, Keypair, TransactionBuilder, Network, AiohttpClient

# The source account is the account we will be signing and sending from.
source_secret_key = "SBFZCHU5645DOKRWYBXVOXY2ELGJKFRX6VGGPRYUWHQ7PMXXJNDZFMKD"

# Derive Keypair object and public key (that starts with a G) from the secret
source_keypair = Keypair.from_secret(source_secret_key)
source_public_key = source_keypair.public_key

receiver_public_key = "GA7YNBW5CBTJZ3ZZOWX3ZNBKD6OE7A7IHUQVWMY62W2ZBG2SGZVOOPVH"


async def main():
    # Configure KuknosSdk to talk to the horizon instance hosted by Kuknos.org
    # To use the live network, set the hostname to 'horizon.kuknos.org'
    # When we use the `with` syntax, it automatically releases the resources it occupies.
    async with Server(
            horizon_url="https://hz1-test.kuknos.org", client=AiohttpClient()
    ) as server:
        # 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.
        source_account = await server.load_account(source_public_key)
示例#18
0
from kuknos_sdk import TransactionBuilder, Server, Network, Keypair

server = Server(horizon_url="https://hz1-test.kuknos.org")
source = Keypair.from_secret("SBFZCHU5645DOKRWYBXVOXY2ELGJKFRX6VGGPRYUWHQ7PMXXJNDZFMKD")
destination = Keypair.random()

source_account = server.load_account(account_id=source.public_key)
transaction = TransactionBuilder(
    source_account=source_account,
    network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
    base_fee=100) \
    .append_create_account_op(destination=destination.public_key, starting_balance="12.25") \
    .build()
transaction.sign(source)
response = server.submit_transaction(transaction)
print("Transaction hash: {}".format(response["hash"]))
print("New Keypair: \n\taccount id: {account_id}\n\tsecret seed: {secret_seed}".format(
    account_id=destination.public_key, secret_seed=destination.secret))
class TestKuknosTransactionKuknosUri:
    xdr = "AAAAAP+yw+ZEuNg533pUmwlYxfrq6/BoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH//////////AAAAAAAAAAA="
    tx = TransactionEnvelope.from_xdr(xdr, Network.TESTNET_NETWORK_PASSPHRASE)

    fee_bump_tx_xdr = "AAAABQAAAABDqliFalCjYChydhLNq0lXO8PWMJGrsl8naSePTpNR2wAAAAAAAAGQAAAAAgAAAABzdv3ojkzWHMD7KUoXhrPx0GH18vHKV0ZfqpMiEblG1gAAADIAAAAAAAAwOgAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAGqka26GRAaOmdSR+9P28gWFYn/iQ3GPQsRGAuT5bF4JAAAAAAAAAAA7msoAAAAAAAAAAAERuUbWAAAAQM7EA7Pnkeyqzpa+KgOTDLX66WKBk32BSF4NocSAeOkfUDwIODWvgcToOAH4+jaeOqdWhmxjC0mQ0vO3V14u7AwAAAAAAAAAAU6TUdsAAABAt2wuZNUirKyCkv7Sc3B1kk5CUPt7eitpaZjRBpbrW1p8wVIZ6IsaRzzIVHP7YpGhzbPImXkahlolf0IL3sevBA=="
    fee_bump_tx = FeeBumpTransactionEnvelope.from_xdr(
        fee_bump_tx_xdr, Network.TESTNET_NETWORK_PASSPHRASE
    )

    @pytest.mark.parametrize(
        "tx, replace, callback, pubkey, message, network_passphrase, origin_domain, signature, signer, uri",
        [
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline",
            ),
            (
                tx,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    ),
                    Replacement("seqNum", "Y", "sequence for sourceAccount"),
                ],
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%2CseqNum%3AY%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline%2CY%3Asequence%20for%20sourceAccount",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                None,
                None,
                None,
                None,
                None,
                None,
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&signature=VES7qVW1mbxV7PFDi8DvyrxP2EUhYqqGnw%2B%2BQEeIZeYIlrdvc9qqQo0dqtOR4qb2npoml1rlp%2F30WPikSaE6Bg%3D%3D",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                None,
                None,
                None,
                None,
                None,
                "testSignature",
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&signature=VES7qVW1mbxV7PFDi8DvyrxP2EUhYqqGnw%2B%2BQEeIZeYIlrdvc9qqQo0dqtOR4qb2npoml1rlp%2F30WPikSaE6Bg%3D%3D",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                None,
                None,
                None,
                None,
                None,
                "testSignature",
                None,
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&signature=testSignature",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                None,
                None,
                None,
                None,
                None,
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&signature=VES7qVW1mbxV7PFDi8DvyrxP2EUhYqqGnw%2B%2BQEeIZeYIlrdvc9qqQo0dqtOR4qb2npoml1rlp%2F30WPikSaE6Bg%3D%3D",
            ),
            (
                tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                "https://someSigningService.com",
                "GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS",
                "a" * 300,
                Network.TESTNET_NETWORK_PASSPHRASE,
                "someDomain.com",
                "testSignature",
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D",
            ),
            (
                fee_bump_tx,
                [
                    Replacement(
                        "sourceAccount", "X", "account on which to create the trustline"
                    )
                ],
                "https://someSigningService.com",
                "GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS",
                "a" * 300,
                Network.TESTNET_NETWORK_PASSPHRASE,
                "someDomain.com",
                "testSignature",
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:tx?xdr=AAAABQAAAABDqliFalCjYChydhLNq0lXO8PWMJGrsl8naSePTpNR2wAAAAAAAAGQAAAAAgAAAABzdv3ojkzWHMD7KUoXhrPx0GH18vHKV0ZfqpMiEblG1gAAADIAAAAAAAAwOgAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAGqka26GRAaOmdSR%2B9P28gWFYn%2FiQ3GPQsRGAuT5bF4JAAAAAAAAAAA7msoAAAAAAAAAAAERuUbWAAAAQM7EA7Pnkeyqzpa%2BKgOTDLX66WKBk32BSF4NocSAeOkfUDwIODWvgcToOAH4%2BjaeOqdWhmxjC0mQ0vO3V14u7AwAAAAAAAAAAU6TUdsAAABAt2wuZNUirKyCkv7Sc3B1kk5CUPt7eitpaZjRBpbrW1p8wVIZ6IsaRzzIVHP7YpGhzbPImXkahlolf0IL3sevBA%3D%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=x968yy0d2uFhx6At2mxd6yK%2F0ZZCz%2F%2FQT%2BmlIXmJwI6xe4RuYVIPZpROVx8HUYtcL9ok%2FrwzlQHnBg%2F%2Ba0YYDg%3D%3D",
            ),
        ],
    )
    def test_to_uri(
        self,
        tx,
        replace,
        callback,
        pubkey,
        message,
        network_passphrase,
        origin_domain,
        signature,
        signer,
        uri,
    ):
        uri_builder = TransactionKuknosUri(
            transaction_envelope=tx,
            replace=replace,
            callback=callback,
            pubkey=pubkey,
            message=message,
            network_passphrase=network_passphrase,
            origin_domain=origin_domain,
            signature=signature,
        )
        if signer:
            uri_builder.sign(signer)
        assert uri_builder.to_uri() == uri
        restore_uri = TransactionKuknosUri.from_uri(
            uri_builder.to_uri(), Network.TESTNET_NETWORK_PASSPHRASE
        ).to_uri()
        if network_passphrase is None:
            restore_uri = restore_uri.replace(
                "&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015", ""
            )
        assert restore_uri == uri

    def test_message_too_long_raise(self):
        message = "_" * 301
        with pytest.raises(ValueError, match="Message must not exceed 300 characters."):
            TransactionKuknosUri(
                transaction_envelope=self.tx, message=message,
            )

    def test_equal(self):
        assert TransactionKuknosUri(
            transaction_envelope=self.tx
        ) == TransactionKuknosUri(transaction_envelope=self.tx)

    def test_invalid_callback_raise(self):
        uri = "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=https%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(ValueError, match="`callback` should start with `url:`."):
            TransactionKuknosUri.from_uri(uri, Network.TESTNET_NETWORK_PASSPHRASE)

    def test_missing_network_passphrase_raise(self):
        uri = "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=https%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(ValueError, match="`network_passphrase` is required."):
            TransactionKuknosUri.from_uri(uri, None)

    def test_invalid_scheme_raise(self):
        uri = "invalid+web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        # TODO: recheck: Kuknos URI scheme should be `web+kuknos`, but got `invalid+web+kuknos`.
        with pytest.raises(ValueError, match="Kuknos URI scheme should be"):
            TransactionKuknosUri.from_uri(uri, Network.TESTNET_NETWORK_PASSPHRASE)

    def test_invalid_path_raise(self):
        uri = "web+kuknos:invalid_tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(
            ValueError, match="Kuknos URI path should be `tx`, but got `invalid_tx`."
        ):
            TransactionKuknosUri.from_uri(uri, Network.TESTNET_NETWORK_PASSPHRASE)

    # TODO: add more tests
    def test_invalid_replace_raise(self):
        uri = "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BY%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(ValueError, match="Invalid `replace`."):
            TransactionKuknosUri.from_uri(uri, Network.TESTNET_NETWORK_PASSPHRASE)

    def test_missing_xdr_passphrase_raise(self):
        uri = "web+kuknos:tx?callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(ValueError, match="`xdr` is missing from uri."):
            TransactionKuknosUri.from_uri(uri, Network.TESTNET_NETWORK_PASSPHRASE)

    def test_network_passphrase_mismatch_raise(self):
        uri = "web+kuknos:tx?xdr=AAAAAP%2Byw%2BZEuNg533pUmwlYxfrq6%2FBoMJqiJ8vuQhf6rHWmAAAAZAB8NHAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABSFVHAAAAAABAH0wIyY3BJBS2qHdRPAV80M8hF7NBpxRjXyjuT9kEbH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAAAAAAAAAAA%3D&callback=url%3Ahttps%3A%2F%2FsomeSigningService.com&replace=sourceAccount%3AX%3BX%3Aaccount%20on%20which%20to%20create%20the%20trustline&pubkey=GAU2ZSYYEYO5S5ZQSMMUENJ2TANY4FPXYGGIMU6GMGKTNVDG5QYFW6JS&msg=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=8uiZ2r7KT3gRsO%2BrzmofGHyl%2FLFMfOgNtx5oOddK2rAy8M%2BOgBYOSQpASNbIm%2BIvZVojxv8tKTYuzOkbyhPODA%3D%3D"
        with pytest.raises(
            ValueError,
            match="The `network_passphrase` in the function parameter does not "
            "match the `network_passphrase` in the uri.",
        ):
            TransactionKuknosUri.from_uri(uri, Network.PUBLIC_NETWORK_PASSPHRASE)
from kuknos_sdk import Server, TransactionBuilder, Keypair, Network

sponsor_secret = "SAOJHTVFCYVKUMPNQI7RUSI566GKWXP7RXOHP4SV6JAVUQKSIWGPZFPJ"
new_account_secret = "SCN5D72JHQAHUHGIA23SLS3LBYCPHJWD7HLYNJRBBZIG4PD74UCGQBYM"

sponsor_keypair = Keypair.from_secret(sponsor_secret)
newly_created_keypair = Keypair.from_secret(new_account_secret)

server = Server("https://hz1-test.kuknos.org")
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE

# Sponsoring Account Creation
# https://github.com/kuknos/kuknos-protocol/blob/master/core/cap-0033.md#example-sponsoring-account-creation
sponsor_account = server.load_account(sponsor_keypair.public_key)
sponsoring_account_creation_te = TransactionBuilder(
    source_account=sponsor_account,
    network_passphrase=network_passphrase
).append_begin_sponsoring_future_reserves_op(
    sponsored_id=newly_created_keypair.public_key,
    source=sponsor_keypair.public_key
).append_create_account_op(
    destination=newly_created_keypair.public_key,
    starting_balance="10",
    source=sponsor_keypair.public_key
).append_end_sponsoring_future_reserves_op(
    source=newly_created_keypair.public_key
).build()
sponsoring_account_creation_te.sign(sponsor_keypair)
sponsoring_account_creation_te.sign(new_account_secret)
sponsoring_account_creation_resp = server.submit_transaction(sponsoring_account_creation_te)
print(sponsoring_account_creation_resp)
class TestPayKuknosUri:
    @pytest.mark.parametrize(
        "destination, amount, asset, memo, callback, message, network_passphrase, origin_domain, signature, signer, uri",
        [
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=tbsLtlK%2FfouvRWk2UWFP47yHYeI1g1NEC%2FfEQvuXG6V8P%2BbeLxplYbOVtTk1g94Wp97cHZ3pVJy%2FtZNYobl3Cw%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                "testSignature",
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=tbsLtlK%2FfouvRWk2UWFP47yHYeI1g1NEC%2FfEQvuXG6V8P%2BbeLxplYbOVtTk1g94Wp97cHZ3pVJy%2FtZNYobl3Cw%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                None,
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                "testSignature",
                None,
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=testSignature",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "_" * 300,
                None,
                "someDomain.com",
                None,
                "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC",
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________&origin_domain=someDomain.com&signature=d94yTtEX0PMUDwwYfzLuVx6luuEiVlxyVQrkR%2FM4NIundX2VqXLVE%2F6FX8G5x4MZ1qc0u661t4Rfu5SKyTIjCg%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                NoneMemo(),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=t9glBiurQ1MUyk3T5BIqxgJwbrNT1ZDIzQ6aKDJmPgM8heN1NEk%2FusfMq6lSaqtxUuysfZisgPM8TiSY0ckyCw%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                None,
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=tbsLtlK%2FfouvRWk2UWFP47yHYeI1g1NEC%2FfEQvuXG6V8P%2BbeLxplYbOVtTk1g94Wp97cHZ3pVJy%2FtZNYobl3Cw%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                Asset.native(),
                TextMemo("skdjfasf"),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=skdjfasf&memo_type=MEMO_TEXT&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=tbsLtlK%2FfouvRWk2UWFP47yHYeI1g1NEC%2FfEQvuXG6V8P%2BbeLxplYbOVtTk1g94Wp97cHZ3pVJy%2FtZNYobl3Cw%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                Asset.native(),
                IdMemo(10086),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=10086&memo_type=MEMO_ID&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=cTyphv1qE6YqnwKu1O4psEzA8O6vNYu%2FDbvGb0Nu53V%2FL8U7LoGknX1JOGLsgGjOXdfAmJbG8rxF8I9DD%2BvjCA%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                Asset.native(),
                HashMemo(
                    "218a3ef357324c496d07f7d7b31be5c2a11a1ac44af9b81938a6c5b9c0684af4"
                ),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=IYo%2B81cyTEltB%2FfXsxvlwqEaGsRK%2BbgZOKbFucBoSvQ%3D&memo_type=MEMO_HASH&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=CzqyewhypDQGCBlvxSj%2BazIm5iS2GDqcOlBeXT%2FB7s8ogEXC8hNa6HjOArdbTkvNCUvTl6lgyKOj%2FeeNE%2BA5DQ%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                Asset.native(),
                ReturnHashMemo(
                    "218a3ef357324c496d07f7d7b31be5c2a11a1ac44af9b81938a6c5b9c0684af4"
                ),
                None,
                "pay me with paymons",
                None,
                "someDomain.com",
                None,
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&memo=IYo%2B81cyTEltB%2FfXsxvlwqEaGsRK%2BbgZOKbFucBoSvQ%3D&memo_type=MEMO_RETURN&msg=pay%20me%20with%20paymons&origin_domain=someDomain.com&signature=4OJcgA0qxjUhqJL79MeK%2BkHgNjdKXiGhufvw2yjcXud7Ce%2BG53N0qSUpgXDT8OBDQRrI7Pe%2FUPu0%2FCM7DJkXAQ%3D%3D",
            ),
            (
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                "120.1234567",
                Asset(
                    "Hello", "GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF"
                ),
                TextMemo("Hello World"),
                "https://example.com/callback",
                "pay me with paymons",
                Network.TESTNET_NETWORK_PASSPHRASE,
                "someDomain.com",
                "testSignature",
                Keypair.from_secret(
                    "SBPOVRVKTTV7W3IOX2FJPSMPCJ5L2WU2YKTP3HCLYPXNI5MDIGREVNYC"
                ),
                "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D",
            ),
        ],
    )
    def test_to_uri(
        self,
        destination,
        amount,
        asset,
        memo,
        callback,
        message,
        network_passphrase,
        origin_domain,
        signature,
        signer,
        uri,
    ):
        uri_builder = PayKuknosUri(
            destination=destination,
            amount=amount,
            asset=asset,
            memo=memo,
            callback=callback,
            message=message,
            network_passphrase=network_passphrase,
            origin_domain=origin_domain,
            signature=signature,
        )
        if signer:
            uri_builder.sign(signer)
        assert uri_builder.to_uri() == uri
        assert PayKuknosUri.from_uri(uri_builder.to_uri()).to_uri() == uri

    def test_message_too_long_raise(self):
        message = "_" * 301
        with pytest.raises(ValueError, match="Message must not exceed 300 characters."):
            PayKuknosUri(
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
                message=message,
            )

    def test_invalid_memo_raise(self):
        memo = "invalid memo"
        with pytest.raises(ValueError, match="Invalid memo."):
            PayKuknosUri(
                "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO", memo=memo
            )

    def test_equal(self):
        assert PayKuknosUri(
            "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO"
        ) == PayKuknosUri("GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO")

    def test_invalid_callback_raise(self):
        uri = "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT&callback=https%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        with pytest.raises(ValueError, match="`callback` should start with `url:`."):
            PayKuknosUri.from_uri(uri)

    def test_invalid_scheme_raise(self):
        uri = "invalid+web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        # TODO: recheck: Kuknos URI scheme should be `web+kuknos`, but got `invalid+web+kuknos`.
        with pytest.raises(ValueError, match="Kuknos URI scheme should be"):
            PayKuknosUri.from_uri(uri)

    def test_invalid_path_raise(self):
        uri = "web+kuknos:invalid_pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        with pytest.raises(
            ValueError, match="Kuknos URI path should be `pay`, but got `invalid_pay`."
        ):
            PayKuknosUri.from_uri(uri)

    def test_destination_missing_raise(self):
        uri = "web+kuknos:pay?amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        with pytest.raises(ValueError, match="`destination` is missing from uri."):
            PayKuknosUri.from_uri(uri)

    def test_memo_no_value_raise(self):
        uri = "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo_type=MEMO_TEXT&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        with pytest.raises(ValueError, match="`memo` is missing from uri."):
            PayKuknosUri.from_uri(uri)

    def test_invalid_memo_type_raise(self):
        uri = "web+kuknos:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567&asset_code=Hello&asset_issuer=GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF&memo=Hello%20World&memo_type=MEMO_TEXT_INVALID&callback=url%3Ahttps%3A%2F%2Fexample.com%2Fcallback&msg=pay%20me%20with%20paymons&network_passphrase=Test%20SDF%20Network%20%3B%20September%202015&origin_domain=someDomain.com&signature=k5cDMVTD2W2lKeEGqakjOTf3aPuPumlr8ObBOvauaa2QiXqa7%2Bw9WRgtmo6NaPXdOoFG5ScUIp9k7PdeuPieCw%3D%3D"
        with pytest.raises(ValueError, match="Invalid `memo_type`."):
            PayKuknosUri.from_uri(uri)
示例#22
0
    def test_to_txrep_full_tx(self):
        keypair = Keypair.from_secret(
            "SAHGKA7QJB6SRFDZSPZDEEIOEHUHTQS4XVN4IMR5YCKBPEN5A6YNKKUO")
        account = Account(keypair.public_key, 46489056724385792)
        transaction_builder = TransactionBuilder(
            source_account=account,
            network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
            base_fee=200,
        )
        transaction_builder.add_text_memo("Enjoy this transaction")
        transaction_builder.add_time_bounds(1535756672, 1567292672)
        transaction_builder.append_create_account_op(
            destination=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            starting_balance="10",
            source=keypair.public_key,
        )
        transaction_builder.append_payment_op(
            destination=
            "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
            asset_code="USD",
            asset_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            amount="40.0004",
            source=keypair.public_key,
        ),
        transaction_builder.append_path_payment_strict_receive_op(
            destination=
            "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
            send_code="USD",
            send_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            send_max="10",
            dest_code="XCN",
            dest_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            dest_amount="5.125",
            path=[
                Asset(
                    "Hello",
                    "GD3RXMK2GHSXXEHPBZY5IL7VW5BXQEDJMCD4KVMXOH2GRFKDGZXR5PFO"
                ),
                Asset.native(),
                Asset(
                    "MOEW",
                    "GBR765FQTCAJLLJGZVYLXCFAOZI6ORTHPDPOOHJOHFRZ5GHNVYGK4IFM"
                ),
            ],
            source=keypair.public_key,
        )
        transaction_builder.append_manage_sell_offer_op(
            selling_code="XCN",
            selling_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            buying_code="USD",
            buying_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            amount="100.123",
            price=Price(n=7, d=1),
            offer_id=12345,
            source=keypair.public_key,
        )
        transaction_builder.append_create_passive_sell_offer_op(
            selling_code="XCN",
            selling_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            buying_code="USD",
            buying_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            amount="100.123",
            price="7.1",
            source=keypair.public_key,
        )
        transaction_builder.append_set_options_op(
            inflation_dest=
            "GCVAZXCGX3HLHZ6P5WKEPE3U2YJMTLMPTZJFGY67MTNPSOA4COKVJ6AF",
            clear_flags=3,
            set_flags=3,
            master_weight=255,
            low_threshold=1,
            med_threshold=2,
            high_threshold=3,
            home_domain="kuknos.org",
            signer=Signer.ed25519_public_key(
                "GAO3YIWNOBP4DN3ORDXYXTUMLF5S54OK4PKAFCWE23TTOML4COGQOIYA",
                255),
            source=keypair.public_key,
        )
        transaction_builder.append_set_options_op(home_domain="kuknoscn.org")
        transaction_builder.append_pre_auth_tx_signer(
            "0ab0c76b1c661db0e829abfdd9e32e6ce3c11f756bdf71aa23846582106c1783",
            5)
        transaction_builder.append_hashx_signer(
            "0d64fac556c1545616b3c915a4ec215239500bce287007cff038b6020950af46",
            10)
        transaction_builder.append_change_trust_op(
            asset_code="XCN",
            asset_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            limit="1000",
            source=keypair.public_key,
        )
        transaction_builder.append_allow_trust_op(
            trustor="GDU64QWPRTO3LW5VGZPTLRR6QROFWV36XG5QT4C6FZBPHQBBFYRCWZTZ",
            asset_code="CAT",
            authorize=True,
            source=keypair.public_key,
        )
        transaction_builder.append_account_merge_op(
            destination=
            "GDU64QWPRTO3LW5VGZPTLRR6QROFWV36XG5QT4C6FZBPHQBBFYRCWZTZ",
            source=keypair.public_key,
        )
        transaction_builder.append_manage_data_op("Hello",
                                                  "Kuknos",
                                                  source=keypair.public_key)
        transaction_builder.append_manage_data_op("World",
                                                  None,
                                                  source=keypair.public_key)
        transaction_builder.append_bump_sequence_op(bump_to=46489056724385800,
                                                    source=keypair.public_key)
        transaction_builder.append_manage_buy_offer_op(
            selling_code="XCN",
            selling_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            buying_code="USD",
            buying_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            amount="100.123",
            price="7.1",
            source=keypair.public_key,
        )
        transaction_builder.append_path_payment_strict_send_op(
            destination=
            "GBAF6NXN3DHSF357QBZLTBNWUTABKUODJXJYYE32ZDKA2QBM2H33IK6O",
            send_code="USD",
            send_issuer=
            "GAZFEVBSEGJJ63WPVVIWXLZLWN2JYZECECGT6GUNP4FJDVZVNXWQWMYI",
            send_amount="10",
            dest_code="XCN",
            dest_issuer=
            "GAYE5SDEM5JIEMGQ7LBMQVRQRVJB6A5E7AZVLJYFL3CNHLZX24DFD35F",
            dest_min="5.125",
            path=[
                Asset(
                    "Hello",
                    "GD3RXMK2GHSXXEHPBZY5IL7VW5BXQEDJMCD4KVMXOH2GRFKDGZXR5PFO"
                ),
                Asset.native(),
                Asset(
                    "MOEW",
                    "GBR765FQTCAJLLJGZVYLXCFAOZI6ORTHPDPOOHJOHFRZ5GHNVYGK4IFM"
                ),
            ],
            source=keypair.public_key,
        )
        transaction_builder.append_inflation_op()

        te = transaction_builder.build()
        te.sign(keypair)
        te.sign_hashx(
            bytes.fromhex(
                "8b73f9e12fcc8cd9580a2a26aec14d6175aa1ff45e76b816618635d03f3256b8"
            ))
        txrep = to_txrep(te)
        assert txrep == get_txrep_file("test_to_txrep_full_tx.txt")
        assert (from_txrep(
            txrep, Network.TESTNET_NETWORK_PASSPHRASE).to_xdr() == te.to_xdr())
示例#23
0
from kuknos_sdk import Server, TransactionBuilder, Signer, Network, Keypair

server = Server(horizon_url="https://hz1-test.kuknos.org/")
root_keypair = Keypair.from_secret("SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")
root_account = server.load_account(account_id=root_keypair.public_key)
secondary_keypair = Keypair.from_secret("SAMZUAAPLRUH62HH3XE7NVD6ZSMTWPWGM6DS4X47HLVRHEBKP4U2H5E7")

secondary_signer = Signer.ed25519_public_key(account_id=secondary_keypair.public_key, weight=1)
transaction = TransactionBuilder(
    source_account=root_account,
    network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
    base_fee=100) \
    .append_set_options_op(
    master_weight=1,  # set master key weight
    low_threshold=1,
    med_threshold=2,  # a payment is medium threshold
    high_threshold=2,  # make sure to have enough weight to add up to the high threshold!
    signer=secondary_signer) \
    .set_timeout(30) \
    .build()

# only need to sign with the root signer as the 2nd signer won't
# be added to the account till after this transaction completes
transaction.sign(root_keypair)
response = server.submit_transaction(transaction)
print(response)

# now create a payment with the account that has two signers
destination = "GBA5SMM5OYAOOPL6R773MV7O3CCLUDVLCWHIVVL3W4XTD3DA5FJ4JSEZ"
transaction = TransactionBuilder(
    source_account=root_account,
from kuknos_sdk import TransactionBuilder, Network, Keypair, Account

root_keypair = Keypair.from_secret(
    "SA6XHAH4GNLRWWWF6TEVEWNS44CBNFAJWHWOPZCVZOUXSQA7BOYN7XHC")
# Create an Account object from an address and sequence number.
root_account = Account(account_id=root_keypair.public_key, sequence=1)

transaction = TransactionBuilder(
    source_account=root_account,
    network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
    base_fee=100).add_text_memo("Happy birthday!").append_payment_op(
        destination="GASOCNHNNLYFNMDJYQ3XFMI7BYHIOCFW3GJEOWRPEGK2TDPGTG2E5EDW",
        amount="2000",
        asset_code="PMN").set_timeout(30).build()
示例#25
0
from kuknos_sdk import Server, TransactionBuilder, Keypair, ClaimPredicate, Claimant, Asset, Network

sponsor_secret = "SAOJHTVFCYVKUMPNQI7RUSI566GKWXP7RXOHP4SV6JAVUQKSIWGPZFPJ"
claimant_secret = "SBOLGU7D7A7MTY4JZ3WZUKSKB6NZBQFNQG3BZT4HZW4AAVZJRG7TWXGQ"

sponsor_keypair = Keypair.from_secret(sponsor_secret)
claimant_keypair = Keypair.from_secret(claimant_secret)

server = Server("https://hz1-test.kuknos.org/")
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE

# Create Claimable Balance
sponsor_account = server.load_account(sponsor_keypair.public_key)

predicate_left = ClaimPredicate.predicate_before_relative_time(60 * 60 * 24 *
                                                               7)
predicate_right = ClaimPredicate.predicate_not(
    ClaimPredicate.predicate_before_relative_time(60 * 3))
predicate = ClaimPredicate.predicate_and(predicate_left, predicate_right)
claimant = Claimant(destination=claimant_keypair.public_key,
                    predicate=predicate)
create_claimable_balance_te = TransactionBuilder(
    source_account=sponsor_account,
    network_passphrase=network_passphrase).append_create_claimable_balance_op(
        asset=Asset.native(),
        amount="100",
        claimants=[claimant],
        source=sponsor_keypair.public_key).build()
create_claimable_balance_te.sign(sponsor_keypair)
create_claimable_balance_resp = server.submit_transaction(
    create_claimable_balance_te)
import requests

from kuknos_sdk import Keypair

keypair = Keypair.random()

print("Public Key: " + keypair.public_key)
print("Secret Seed: " + keypair.secret)

url = 'https://friendbot.kuknos.org'
url = 'https://friendbot.stellar.org'
response = requests.get(url, params={'addr': keypair.public_key})
print(response)
    def test_to_xdr_v0(self):
        sequence = 1
        source = Account(
            "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM", sequence
        )
        builder = TransactionBuilder(
            source, Network.TESTNET_NETWORK_PASSPHRASE, base_fee=150, v1=False
        )
        builder.add_text_memo("Kuknos Python SDK")
        builder.add_time_bounds(1565590000, 1565600000)
        te = (
            builder.append_create_account_op(
                "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                "5.5",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
            )
            .append_change_trust_op(
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "100000",
            )
            .append_payment_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "12.25",
                "PMN",
            )
            .append_path_payment_strict_receive_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "PMN",
                None,
                "100",
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "1000.5",
                [
                    Asset(
                        "USD",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                    Asset(
                        "BTC",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                ],
            )
            .append_path_payment_strict_send_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "PMN",
                None,
                "100",
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "1000.5",
                [
                    Asset(
                        "USD",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                    Asset(
                        "BTC",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                ],
            )
            .append_allow_trust_op(
                "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", "XCN", True
            )
            .append_set_options_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                1,
                6,
                20,
                20,
                20,
                20,
                "kuknoscn.org",
                Signer.ed25519_public_key(
                    "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF", 10
                ),
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
            )
            .append_ed25519_public_key_signer(
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD", 5
            )
            .append_hashx_signer(
                bytes.fromhex(
                    "3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8000"
                ),
                10,
            )
            .append_pre_auth_tx_signer(
                bytes.fromhex(
                    "2db4b22ca018119c5027a80578813ffcf582cda4aa9e31cd92b43cfa4fc5a000"
                ),
                10,
            )
            .append_inflation_op()
            .append_manage_data_op("hello", "overcat")
            .append_bump_sequence_op(10)
            .append_manage_buy_offer_op(
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "PMN",
                None,
                "10.5",
                "11.25",
            )
            .append_manage_sell_offer_op(
                "PMN",
                None,
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "10.5",
                Price(8, 9),
                10086,
            )
            .append_create_passive_sell_offer_op(
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "PMN",
                None,
                "10.5",
                "11.25",
            )
            .append_account_merge_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF"
            )
            .append_claim_claimable_balance_op(
                "00000000da0d57da7d4850e7fc10d2a9d0ebc731f7afb40574c03395b17d49149b91f5be"
            )
            .append_create_claimable_balance_op(
                Asset.native(),
                "100",
                [
                    Claimant(
                        destination="GCXGGIREYPENNT3LYFRD5I2SDALFWM3NKKLIQD3DMJ63ML5N3FG4OQQG"
                    )
                ],
            )
            .build()
        )
        xdr = "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"
        assert te.to_xdr() == xdr

        xdr_signed = "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"
        signer = Keypair.from_secret(
            "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH"
        )
        te.sign(signer)
        assert te.to_xdr() == xdr_signed

        restore_te = TransactionBuilder.from_xdr(
            xdr_signed, Network.TESTNET_NETWORK_PASSPHRASE
        ).build()
        assert restore_te.to_xdr() == xdr
        assert source.sequence == sequence + 1
        restore_builder = TransactionBuilder.from_xdr(
            xdr_signed, Network.TESTNET_NETWORK_PASSPHRASE
        )
        assert restore_builder.v1 is False
        assert restore_builder.build().to_xdr() == xdr
import pprint

from kuknos_sdk import Keypair, Server, TransactionBuilder, Network
from kuknos_sdk.exceptions import BadRequestError

horizon_url = "https://hz1-test.kuknos.org/"
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE

fee_source_keypair = Keypair.from_secret(
    "SASZKBDB6PFHXN6LRH4NQNTRGLGDTI3PSUVIKMZMLTYYBB7NDVMA6DSL")
inner_source_keypair = Keypair.from_secret(
    "SC5O7VZUXDJ6JBDSZ74DSERXL7W3Y5LTOAMRF7RQRL3TAGAPS7LUVG3L")
destination_address = "GBVKI23OQZCANDUZ2SI7XU7W6ICYKYT74JBXDD2CYRDAFZHZNRPASSQK"

server = Server(horizon_url=horizon_url)
inner_account = server.load_account(inner_source_keypair)

inner_tx = (TransactionBuilder(source_account=inner_account,
                               network_passphrase=network_passphrase,
                               base_fee=50,
                               v1=True).append_payment_op(
                                   destination=destination_address,
                                   amount="100",
                                   asset_code="PMN").build())
inner_tx.sign(inner_source_keypair)

try:
    # This transaction will fail.
    tx_insufficient_fee_resp = server.submit_transaction(inner_tx)
except BadRequestError as e:
    print(e)
    def test_to_xdr_v1(self):
        sequence = 1
        source = Account(
            "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM", sequence
        )
        builder = TransactionBuilder(
            source, Network.TESTNET_NETWORK_PASSPHRASE, base_fee=150, v1=True
        )
        builder.add_text_memo("Kuknos Python SDK")
        builder.add_time_bounds(1565590000, 1565600000)
        te = (
            builder.append_create_account_op(
                "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                "5.5",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
            )
            .append_change_trust_op(
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "100000",
            )
            .append_payment_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "12.25",
                "PMN",
            )
            .append_path_payment_strict_receive_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "PMN",
                None,
                "100",
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "1000.5",
                [
                    Asset(
                        "USD",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                    Asset(
                        "BTC",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                ],
            )
            .append_path_payment_strict_send_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                "PMN",
                None,
                "100",
                "XCN",
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
                "1000.5",
                [
                    Asset(
                        "USD",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                    Asset(
                        "BTC",
                        "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6",
                    ),
                ],
            )
            .append_allow_trust_op(
                "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", "XCN", True
            )
            .append_set_options_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF",
                1,
                6,
                20,
                20,
                20,
                20,
                "kuknoscn.org",
                Signer.ed25519_public_key(
                    "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF", 10
                ),
                "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM",
            )
            .append_ed25519_public_key_signer(
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD", 5
            )
            .append_hashx_signer(
                bytes.fromhex(
                    "3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8000"
                ),
                10,
            )
            .append_pre_auth_tx_signer(
                bytes.fromhex(
                    "2db4b22ca018119c5027a80578813ffcf582cda4aa9e31cd92b43cfa4fc5a000"
                ),
                10,
            )
            .append_inflation_op()
            .append_manage_data_op("hello", "overcat")
            .append_bump_sequence_op(10)
            .append_manage_buy_offer_op(
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "PMN",
                None,
                "10.5",
                "11.25",
            )
            .append_manage_sell_offer_op(
                "PMN",
                None,
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "10.5",
                Price(8, 9),
                10086,
            )
            .append_create_passive_sell_offer_op(
                "XCN",
                "GCN4HBZGFPOAI5DF4YQIS6OBC6KJKDC7CJSS5B4FWEXMJSWOPEYABLSD",
                "PMN",
                None,
                "10.5",
                "11.25",
            )
            .append_account_merge_op(
                "GAXN7HZQTHIPW7N2HGPAXMR42LPJ5VLYXMCCOX4D3JC4CQZGID3UYUPF"
            )
            .append_claim_claimable_balance_op(
                "00000000da0d57da7d4850e7fc10d2a9d0ebc731f7afb40574c03395b17d49149b91f5be"
            )
            .append_create_claimable_balance_op(
                Asset.native(),
                "100",
                [
                    Claimant(
                        destination="GCXGGIREYPENNT3LYFRD5I2SDALFWM3NKKLIQD3DMJ63ML5N3FG4OQQG"
                    )
                ],
            )
            .append_clawback_op(
                Asset(
                    "XCN", "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM"
                ),
                "GCXGGIREYPENNT3LYFRD5I2SDALFWM3NKKLIQD3DMJ63ML5N3FG4OQQG",
                "100",
            )
            .append_clawback_claimable_balance_op(
                "00000000929b20b72e5890ab51c24f1cc46fa01c4f318d8d33367d24dd614cfdf5491072"
            )
            .append_set_trust_line_flags_op(
                "GCXGGIREYPENNT3LYFRD5I2SDALFWM3NKKLIQD3DMJ63ML5N3FG4OQQG",
                Asset(
                    "XCN", "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM"
                ),
                TrustLineFlags.AUTHORIZED_FLAG,
            )
            .build()
        )

        xdr_unsigned = te.to_xdr()

        signer = Keypair.from_secret(
            "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH"
        )
        te.sign(signer)
        restore_builder = TransactionBuilder.from_xdr(
            te.to_xdr(), Network.TESTNET_NETWORK_PASSPHRASE
        )
        assert restore_builder.v1 is True
        assert restore_builder.build().to_xdr() == xdr_unsigned