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
def test_destination_source_assets(self): builder = StrictSendPathsCallBuilder( horizon_url, client, source_asset=Asset( "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), source_amount="10.25", destination=[ Asset( "USD", "GAYSHLG75RPSMXWJ5KX7O7STE6RSZTD6NE4CTWAXFZYYVYIFRUVJIBJH" ), Asset.native(), Asset( "XCN", "GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY" ), ], ) assert builder.endpoint == "paths/strict-send" assert builder.params == { "source_amount": "10.25", "source_asset_type": "credit_alphanum4", "source_asset_code": "EUR", "source_asset_issuer": "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN", "destination_assets": "USD:GAYSHLG75RPSMXWJ5KX7O7STE6RSZTD6NE4CTWAXFZYYVYIFRUVJIBJH,native,XCN:GCNY5OXYSY4FKHOPT2SPOQZAOEIGXB5LBYW3HVU3OWSTQITS65M5RCNY", }
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
def test_to_xdr_sponsored_reserves(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) op_source = "GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM" op_account_id = "GCWWANEIF3Z4DMOE4LDRCS22HLLHOEQCOF3QKAC2XWTSYR2AEEQ3P5FW" te = ( builder.append_begin_sponsoring_future_reserves_op( sponsored_id="GCEYOF66NL73LL6RIPSIP34WOCESQ3GKJOAYXOEVNKRWRNQRYUILCQWC", source=op_source, ) .append_end_sponsoring_future_reserves_op(source=op_source) .append_revoke_account_sponsorship_op( account_id=op_account_id, source=op_source ) .append_revoke_trustline_sponsorship_op( account_id=op_account_id, asset=Asset.native(), source=op_source ) .append_revoke_offer_sponsorship_op( seller_id=op_account_id, offer_id=12315, source=op_source ) .append_revoke_data_sponsorship_op( account_id=op_account_id, data_name="kuknos", source=op_source ) .append_revoke_claimable_balance_sponsorship_op( claimable_balance_id="00000000da0d57da7d4850e7fc10d2a9d0ebc731f7afb40574c03395b17d49149b91f5be", source=op_source, ) .append_revoke_ed25519_public_key_signer_sponsorship_op( account_id=op_account_id, signer_key="GBWYVWA2PZBTRRBNZI55OG4EFDJSDNL6ASP2VAQKHORNUSSXP2NCV4N2", source=op_source, ) .append_revoke_hashx_signer_sponsorship_op( account_id=op_account_id, signer_key="da0d57da7d4850e7fc10d2a9d0ebc731f7afb40574c03395b17d49149b91f5be", source=op_source, ) .append_revoke_pre_auth_tx_signer_sponsorship_op( account_id=op_account_id, signer_key="da0d57da7d4850e7fc10d2a9d0ebc731f7afb40574c03395b17d49149b91f5be", source=op_source, ) .build() ) xdr = "AAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAF3AAAAAAAAAACAAAAAQAAAABdUQHwAAAAAF1RKQAAAAABAAAAElN0ZWxsYXIgUHl0aG9uIFNESwAAAAAACgAAAAEAAAAAy9dx1iMqHHSrGewOxzPEq6pr/rmVnPqyOMcdzPKHnQkAAAAQAAAAAImHF95q/7Wv0UPkh++WcIkobMpLgYu4lWqjaLYRxRCxAAAAAQAAAADL13HWIyocdKsZ7A7HM8Srqmv+uZWc+rI4xx3M8oedCQAAABEAAAABAAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAAEgAAAAAAAAAAAAAAAK1gNIgu88GxxOLHEUtaOtZ3EgJxdwUAWr2nLEdAISG3AAAAAQAAAADL13HWIyocdKsZ7A7HM8Srqmv+uZWc+rI4xx3M8oedCQAAABIAAAAAAAAAAQAAAACtYDSILvPBscTixxFLWjrWdxICcXcFAFq9pyxHQCEhtwAAAAAAAAABAAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAAEgAAAAAAAAACAAAAAK1gNIgu88GxxOLHEUtaOtZ3EgJxdwUAWr2nLEdAISG3AAAAAAAAMBsAAAABAAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAAEgAAAAAAAAADAAAAAK1gNIgu88GxxOLHEUtaOtZ3EgJxdwUAWr2nLEdAISG3AAAAB3N0ZWxsYXIAAAAAAQAAAADL13HWIyocdKsZ7A7HM8Srqmv+uZWc+rI4xx3M8oedCQAAABIAAAAAAAAABAAAAADaDVfafUhQ5/wQ0qnQ68cx96+0BXTAM5WxfUkUm5H1vgAAAAEAAAAAy9dx1iMqHHSrGewOxzPEq6pr/rmVnPqyOMcdzPKHnQkAAAASAAAAAQAAAACtYDSILvPBscTixxFLWjrWdxICcXcFAFq9pyxHQCEhtwAAAABtitgafkM4xC3KO9cbhCjTIbV+BJ+qggo7otpKV36aKgAAAAEAAAAAy9dx1iMqHHSrGewOxzPEq6pr/rmVnPqyOMcdzPKHnQkAAAASAAAAAQAAAACtYDSILvPBscTixxFLWjrWdxICcXcFAFq9pyxHQCEhtwAAAALaDVfafUhQ5/wQ0qnQ68cx96+0BXTAM5WxfUkUm5H1vgAAAAEAAAAAy9dx1iMqHHSrGewOxzPEq6pr/rmVnPqyOMcdzPKHnQkAAAASAAAAAQAAAACtYDSILvPBscTixxFLWjrWdxICcXcFAFq9pyxHQCEhtwAAAAHaDVfafUhQ5/wQ0qnQ68cx96+0BXTAM5WxfUkUm5H1vgAAAAAAAAAA" assert te.to_xdr() == xdr restore_te = TransactionBuilder.from_xdr( xdr, Network.TESTNET_NETWORK_PASSPHRASE ).build() assert restore_te.to_xdr() == xdr
def test_invalid_resolution_raise(self): base = Asset( "XCN", "GCOMOKXUA4TAEBB2QDHZD53SNRWKNTJMVEFLE47JYN5HS7KNLOABVA4Z") counter = Asset.native() resolution = 1000 with pytest.raises(ValueError, match="Invalid resolution: {}".format(resolution)): TradeAggregationsCallBuilder(horizon_url, client, base=base, counter=counter, resolution=resolution)
def test_init(self): selling = Asset( "BTC", "GATEMHCCKCY67ZUCKTROYN24ZYT5GK4EQZ65JJLDHKHRUZI3EUEKMTCH" ) buying = Asset.native() builder = OrderbookCallBuilder(horizon_url, client, selling, buying) assert builder.endpoint == "order_book" assert builder.params == { "selling_asset_type": selling.type, "selling_asset_code": selling.code, "selling_asset_issuer": selling.issuer, "buying_asset_type": buying.type, }
def test_for_asset_pair(self): base = Asset( "XCN", "GCOMOKXUA4TAEBB2QDHZD53SNRWKNTJMVEFLE47JYN5HS7KNLOABVA4Z") counter = Asset.native() builder = TradesCallBuilder(horizon_url, client).for_asset_pair(base=base, counter=counter) assert builder.endpoint == "trades" assert builder.params == { "base_asset_type": base.type, "base_asset_code": base.code, "base_asset_issuer": base.issuer, "counter_asset_type": counter.type, }
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()
def test_for_seller(self): seller = "GATEMHCCKCY67ZUCKTROYN24ZYT5GK4EQZ65JJLDHKHRUZI3EUEKMTCH" selling = Asset( "BTC", "GATEMHCCKCY67ZUCKTROYN24ZYT5GK4EQZ65JJLDHKHRUZI3EUEKMTCH" ) buying = Asset.native() builder = OffersCallBuilder(horizon_url, client) builder.for_seller(seller) builder.for_selling(selling) builder.for_buying(buying) assert builder.endpoint == "offers" assert builder.params == { "seller": seller, "selling_asset_type": selling.type, "selling_asset_code": selling.code, "selling_asset_issuer": selling.issuer, "buying_asset_type": buying.type, }
def test_init(self): base = Asset( "XCN", "GCOMOKXUA4TAEBB2QDHZD53SNRWKNTJMVEFLE47JYN5HS7KNLOABVA4Z") counter = Asset.native() resolution = 300000 builder = TradeAggregationsCallBuilder(horizon_url, client, base=base, counter=counter, resolution=resolution) assert builder.endpoint == "trade_aggregations" assert builder.params == { "base_asset_type": base.type, "base_asset_code": base.code, "base_asset_issuer": base.issuer, "counter_asset_type": counter.type, "resolution": str(resolution), }
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
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())
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) print(create_claimable_balance_resp) # Claim Claimable Balance balance_id = "00000000550e14acbdafcd3089289363b3b0c8bec9b4edd87298c690655b4b2456d68ba0" claimant_account = server.load_account(claimant_keypair.public_key) claim_claimable_balance_te = TransactionBuilder( source_account=claimant_account, network_passphrase=network_passphrase).append_claim_claimable_balance_op( balance_id=balance_id, source=claimant_keypair.public_key).build()
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)
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
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