py-stellar-base icon indicating copy to clipboard operation
py-stellar-base copied to clipboard

Soroban CLI

Open tupui opened this issue 2 years ago • 4 comments

Are there plans for a better DX to call Soroban contracts?

There could be:

  1. A higher level API to call in Python a contract,
  2. A CLI, e.g. using Typer or Click, that would more or less correspond to the RUST CLI.

Looking at the examples in this repo, there is quite some boiler plate that could be hidden (or more easily configurable.) Or maybe all of that is out-of-scope for this library and left to downstream libraries to do?

Thanks 😃

tupui avatar Jan 05 '24 18:01 tupui

A higher level API to call in Python a contract there is quite some boiler plate that could be hidden (or more easily configurable.)

If you could provide an example, it would be more helpful for me to understand it. Thank you.

A CLI, e.g. using Typer or Click, that would more or less correspond to the RUST CLI.

I currently do not have such a plan. If there is one, I believe it should be a new project.

overcat avatar Jan 06 '24 13:01 overcat

Sure, e.g. I had to make a call to a contract so I took the code from https://github.com/StellarCN/py-stellar-base/blob/main/examples/soroban_payment.py and made a helper like:

def soroban_invoke(secret_key: str, contract_id: str, level: int):
    address_kp = Keypair.from_secret(secret_key)
    address_source = soroban_server.load_account(address_kp.public_key)

    args = [
        # claimant
        scval.to_address(address_kp.public_key),
        # level
        scval.to_int128(level),
    ]

    tx = (
        TransactionBuilder(address_source, network_passphrase, base_fee=500)
        .add_time_bounds(0, 0)
        .append_invoke_contract_function_op(
            contract_id=contract_id,
            function_name="claim",
            parameters=args,
        )
        .build()
    )

    response = False

    try:
        tx = soroban_server.prepare_transaction(tx)
    except PrepareTransactionException as e:
        print(f"Got exception: {e.simulate_transaction_response}")
        return response

    tx.sign(address_kp)
    print(f"Signed XDR:\n{tx.to_xdr()}")

    send_transaction_data = soroban_server.send_transaction(tx)
    print(f"sent transaction: {send_transaction_data}")
    if send_transaction_data.status != SendTransactionStatus.PENDING:
        print("send transaction failed")
        return response
    while True:
        print("waiting for transaction to be confirmed...")
        get_transaction_data = soroban_server.get_transaction(send_transaction_data.hash)
        if get_transaction_data.status != GetTransactionStatus.NOT_FOUND:
            break
        time.sleep(3)

    print(f"transaction: {get_transaction_data}")

    response = False
    if get_transaction_data.status == GetTransactionStatus.SUCCESS:
        transaction_meta = stellar_xdr.TransactionMeta.from_xdr(
            get_transaction_data.result_meta_xdr
        )
        if transaction_meta.v3.soroban_meta.return_value.type == stellar_xdr.SCValType.SCV_VOID:  # type: ignore[union-attr]
            print("send response")
            response = True
    else:
        print(f"Transaction failed: {get_transaction_data.result_xdr}")

    return response

This fits my needs, but we can make a more generic API by just allowing to pass the function name and it's args. The config of the server, etc. could be sourced from the env/file or another mechanism (e.g. with Pydantic).

tupui avatar Jan 06 '24 15:01 tupui

@overcat Is there any action to take here? I am happy to try to propose something.

In general, I am looking to contribute to the project actually 😄

tupui avatar Feb 13 '24 21:02 tupui

@overcat Is there any action to take here? I am happy to try to propose something.

In general, I am looking to contribute to the project actually 😄

Thank you very much, but I currently have no intention of adding it to the SDK because the methods in the SDK need to be sufficiently generic, and I have always maintained a rigorous attitude towards adding new APIs. If you are interested, you can create a new library to wrap this SDK and provide these APIs.

overcat avatar Feb 14 '24 13:02 overcat

Ok I understand. I will think about doing that.

Anyway, I am keen on helping out if there is need elsewhere 😃

tupui avatar Feb 24 '24 20:02 tupui

Just so I know, I see you own soroban-sdk on PyPi. If I were to work on that project, would you be open to give let me use this name?

tupui avatar Feb 24 '24 20:02 tupui

@overcat FYI, I started a project here https://github.com/tupui/soroban-cli-python 😄

tupui avatar Feb 25 '24 21:02 tupui

@overcat FYI, I started a project here https://github.com/tupui/soroban-cli-python 😄

This looks very cool!

Just so I know, I see you own soroban-sdk on PyPi. If I were to work on that project, would you be open to give let me use this name?

I noticed that you are currently using soroban on PyPI, which also looks good. If possible, I would like to keep the name soroban-sdk for now and see if I can provide some tools related to WebAssembly in the future. Thank you for your understanding.

overcat avatar Feb 27 '24 08:02 overcat

This looks very cool!

Thanks, feel free to "stop by" and I might have done some wrong things 😅 (Also I actually forgot to add in the readme some acknowledgment to your package, I will fix that tonight).

I noticed that you are currently using soroban on PyPI, which also looks good.

Yes I was happily surprised to see it was still available!

If possible, I would like to keep the name soroban-sdk for now and see if I can provide some tools related to WebAssembly in the future. Thank you for your understanding.

Of course no problem 😃 Also the scope might be different in the end.

Right now it's just to invoke contracts (and I am not done as I at least want to find a good way to pass params with eg a json). I am not sure yet about adding much more.

tupui avatar Feb 27 '24 13:02 tupui