Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add contract info #1532

Merged
merged 15 commits into from
Aug 13, 2024
Merged

Add contract info #1532

merged 15 commits into from
Aug 13, 2024

Conversation

Ifropc
Copy link
Contributor

@Ifropc Ifropc commented Aug 7, 2024

What

Adds contract info command following #1506 spec.

Available flags (for all subcommands)

* `--wasm <WASM>` — Wasm file to extract the data from
* `--wasm-hash <WASM_HASH>` — Wasm hash to get the data for
* `--id <CONTRACT_ID>` — Contract id to get the data for
* `--rpc-url <RPC_URL>` — RPC server endpoint
* `--network-passphrase <NETWORK_PASSPHRASE>` — Network passphrase to sign the transaction sent to the rpc server
* `--network <NETWORK>` — Name of network to use from config
* `--global` — Use global config
* `--config-dir <CONFIG_DIR>` — Location of config directory, default is "."

Shared output flag for meta/env-meta:

* `--output <OUTPUT>` — Format of the output

  Default value: `text`

  Possible values:
  - `text`:
    Text output of the meta info entry
  - `xdr-base64`:
    XDR output of the info entry
  - `json`:
    JSON output of the info entry (one line, not formatted)
  - `json-formatted`:
    Formatted (multiline) JSON output of the info entry

Output flag for interface:

* `--output <OUTPUT>` — Format of the output

  Default value: `rust`

  Possible values:
  - `rust`:
    Rust code output of the contract interface
  - `xdr-base64`:
    XDR output of the info entry
  - `json`:
    JSON output of the info entry (one line, not formatted)
  - `json-formatted`:
    Formatted (multiline) JSON output of the info entry

Examples of running the command:

stellar contract info env-meta

stellar-cli contract info env-meta --network testnet --wasm ~/wasm/soroban_liquidity_pool_contract.wasm 
Contract env-meta:
 • Protocol: v21
 • Interface: v0
 • Interface Version: 90194313216

stellar contract info meta

stellar-cli contract info meta --network testnet --wasm ~/wasm/soroban_liquidity_pool_contract.wasm --output json
[{"sc_meta_v0":{"key":"Description","val":"Constant product AMM with a .3% swap fee"}},{"sc_meta_v0":{"key":"rsver","val":"1.79.0"}},{"sc_meta_v0":{"key":"rssdkver","val":"21.4.0#d6f5639f643d76e758beecbb0ca391f8cd304c24"}}]

stellar-cli contract info meta --network testnet --wasm ~/wasm/soroban_liquidity_pool_contract.wasm 
Contract meta:
 • Description: Constant product AMM with a .3% swap fee
 • rsver: 1.79.0 (Rust version)
 • rssdkver: 21.4.0#d6f5639f643d76e758beecbb0ca391f8cd304c24 (Soroban SDK version and it's commit hash)

stellar contract info interface

stellar contract info interface --network testnet --wasm-hash \
102431a5a5bc74bdb6bf2803c74080b67d070c522482c278a921563cb71ecc1a
#[soroban_sdk::contractclient(name = "Client")]
pub trait Contract {
    fn hello(
        env: soroban_sdk::Env,
        to: soroban_sdk::Symbol,
    ) -> soroban_sdk::Vec<soroban_sdk::Symbol>;
}

stellar-cli contract info interface --network testnet --id CC434MK5OCXTDMZTBZXS7WQP6SOYFWVAZY23PRGAPUQZXARGQRZP3FJH
#[soroban_sdk::contractclient(name = "Client")]
pub trait Contract {
    fn initialize(
        env: soroban_sdk::Env,
        token_wasm_hash: soroban_sdk::BytesN<32>,
        token_a: soroban_sdk::Address,
        token_b: soroban_sdk::Address,
    );
    fn share_id(env: soroban_sdk::Env) -> soroban_sdk::Address;
    fn deposit(
        env: soroban_sdk::Env,
        to: soroban_sdk::Address,
        desired_a: i128,
        min_a: i128,
        desired_b: i128,
        min_b: i128,
    );
    fn swap(
        env: soroban_sdk::Env,
        to: soroban_sdk::Address,
        buy_a: bool,
        out: i128,
        in_max: i128,
    );
    fn withdraw(
        env: soroban_sdk::Env,
        to: soroban_sdk::Address,
        share_amount: i128,
        min_a: i128,
        min_b: i128,
    ) -> (i128, i128);
    fn get_rsrvs(env: soroban_sdk::Env) -> (i128, i128);
}

stellar-cli contract info interface --network testnet --wasm ~/wasm/soroban_custom_types_contract.wasm             
#[soroban_sdk::contractclient(name = "Client")]
pub trait Contract {
    fn hello(env: soroban_sdk::Env, hello: soroban_sdk::Symbol) -> soroban_sdk::Symbol;
    fn auth(
        env: soroban_sdk::Env,
        addr: soroban_sdk::Address,
        world: soroban_sdk::Symbol,
    ) -> soroban_sdk::Address;
    fn get_count(env: soroban_sdk::Env) -> u32;
    fn inc(env: soroban_sdk::Env) -> u32;
    fn woid(env: soroban_sdk::Env);
    fn val(env: soroban_sdk::Env) -> soroban_sdk::Val;
    fn u32_fail_on_even(
        env: soroban_sdk::Env,
        u32_: u32,
    ) -> Result<u32, soroban_sdk::Error>;
    fn u32_(env: soroban_sdk::Env, u32_: u32) -> u32;
    fn i32_(env: soroban_sdk::Env, i32_: i32) -> i32;
    fn i64_(env: soroban_sdk::Env, i64_: i64) -> i64;
    fn strukt_hel(
        env: soroban_sdk::Env,
        strukt: Test,
    ) -> soroban_sdk::Vec<soroban_sdk::Symbol>;
    fn strukt(env: soroban_sdk::Env, strukt: Test) -> Test;
    fn simple(env: soroban_sdk::Env, simple: SimpleEnum) -> SimpleEnum;
    fn complex(env: soroban_sdk::Env, complex: ComplexEnum) -> ComplexEnum;
    fn addresse(
        env: soroban_sdk::Env,
        addresse: soroban_sdk::Address,
    ) -> soroban_sdk::Address;
    fn bytes(env: soroban_sdk::Env, bytes: soroban_sdk::Bytes) -> soroban_sdk::Bytes;
    fn bytes_n(
        env: soroban_sdk::Env,
        bytes_n: soroban_sdk::BytesN<9>,
    ) -> soroban_sdk::BytesN<9>;
    fn card(env: soroban_sdk::Env, card: RoyalCard) -> RoyalCard;
    fn boolean(env: soroban_sdk::Env, boolean: bool) -> bool;
    fn not(env: soroban_sdk::Env, boolean: bool) -> bool;
    fn i128(env: soroban_sdk::Env, i128: i128) -> i128;
    fn u128(env: soroban_sdk::Env, u128: u128) -> u128;
    fn multi_args(env: soroban_sdk::Env, a: u32, b: bool) -> u32;
    fn map(
        env: soroban_sdk::Env,
        map: soroban_sdk::Map<u32, bool>,
    ) -> soroban_sdk::Map<u32, bool>;
    fn vec(env: soroban_sdk::Env, vec: soroban_sdk::Vec<u32>) -> soroban_sdk::Vec<u32>;
    fn tuple(
        env: soroban_sdk::Env,
        tuple: (soroban_sdk::Symbol, u32),
    ) -> (soroban_sdk::Symbol, u32);
    fn option(env: soroban_sdk::Env, option: Option<u32>) -> Option<u32>;
    fn u256(env: soroban_sdk::Env, u256: soroban_sdk::U256) -> soroban_sdk::U256;
    fn i256(env: soroban_sdk::Env, i256: soroban_sdk::I256) -> soroban_sdk::I256;
    fn string(env: soroban_sdk::Env, string: soroban_sdk::String) -> soroban_sdk::String;
    fn tuple_strukt(env: soroban_sdk::Env, tuple_strukt: TupleStruct) -> TupleStruct;
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct Test {
    pub a: u32,
    pub b: bool,
    pub c: soroban_sdk::Symbol,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct TupleStruct(pub Test, pub SimpleEnum);
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum SimpleEnum {
    First,
    Second,
    Third,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum ComplexEnum {
    Struct(Test),
    Tuple(TupleStruct),
    Enum(SimpleEnum),
    Asset(soroban_sdk::Address, i128),
    Void,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum RoyalCard {
    Jack = 11,
    Queen = 12,
    King = 13,
}
#[soroban_sdk::contracterror(export = false)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum Error {
    NumberMustBeOdd = 1,
}

 > stellar-cli contract info interface --network testnet --wasm ~/wasm/soroban_token_contract.wasm --output xdr-base64
AAAAAAAAAAAAAAAKaW5pdGlhbGl6ZQAAAAAABAAAAAAAAAAFYWRtaW4AAAAAAAATAAAAAAAAAAdkZWNpbWFsAAAAAAQAAAAAAAAABG5hbWUAAAAQAAAAAAAAAAZzeW1ib2wAAAAAABAAAAAAAAAAAAAAAAAAAAAEbWludAAAAAIAAAAAAAAAAnRvAAAAAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAAAAAAAAAAAAAJc2V0X2FkbWluAAAAAAAAAQAAAAAAAAAJbmV3X2FkbWluAAAAAAAAEwAAAAAAAAAAAAAAAAAAAAlhbGxvd2FuY2UAAAAAAAACAAAAAAAAAARmcm9tAAAAEwAAAAAAAAAHc3BlbmRlcgAAAAATAAAAAQAAAAsAAAAAAAAAAAAAAAdhcHByb3ZlAAAAAAQAAAAAAAAABGZyb20AAAATAAAAAAAAAAdzcGVuZGVyAAAAABMAAAAAAAAABmFtb3VudAAAAAAACwAAAAAAAAARZXhwaXJhdGlvbl9sZWRnZXIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB2JhbGFuY2UAAAAAAQAAAAAAAAACaWQAAAAAABMAAAABAAAACwAAAAAAAAAAAAAACHRyYW5zZmVyAAAAAwAAAAAAAAAEZnJvbQAAABMAAAAAAAAAAnRvAAAAAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAAAAAAAAAAAAANdHJhbnNmZXJfZnJvbQAAAAAAAAQAAAAAAAAAB3NwZW5kZXIAAAAAEwAAAAAAAAAEZnJvbQAAABMAAAAAAAAAAnRvAAAAAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAAAAAAAAAAAAAEYnVybgAAAAIAAAAAAAAABGZyb20AAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAAAAAAAAAAAAAJYnVybl9mcm9tAAAAAAAAAwAAAAAAAAAHc3BlbmRlcgAAAAATAAAAAAAAAARmcm9tAAAAEwAAAAAAAAAGYW1vdW50AAAAAAALAAAAAAAAAAAAAAAAAAAACGRlY2ltYWxzAAAAAAAAAAEAAAAEAAAAAAAAAAAAAAAEbmFtZQAAAAAAAAABAAAAEAAAAAAAAAAAAAAABnN5bWJvbAAAAAAAAAAAAAEAAAAQAAAAAQAAAAAAAAAAAAAAEEFsbG93YW5jZURhdGFLZXkAAAACAAAAAAAAAARmcm9tAAAAEwAAAAAAAAAHc3BlbmRlcgAAAAATAAAAAQAAAAAAAAAAAAAADkFsbG93YW5jZVZhbHVlAAAAAAACAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAAEWV4cGlyYXRpb25fbGVkZ2VyAAAAAAAABAAAAAIAAAAAAAAAAAAAAAdEYXRhS2V5AAAAAAQAAAABAAAAAAAAAAlBbGxvd2FuY2UAAAAAAAABAAAH0AAAABBBbGxvd2FuY2VEYXRhS2V5AAAAAQAAAAAAAAAHQmFsYW5jZQAAAAABAAAAEwAAAAEAAAAAAAAABVN0YXRlAAAAAAAAAQAAABMAAAAAAAAAAAAAAAVBZG1pbgAAAAAAAAEAAAAAAAAAAAAAAA1Ub2tlbk1ldGFkYXRhAAAAAAAAAwAAAAAAAAAHZGVjaW1hbAAAAAAEAAAAAAAAAARuYW1lAAAAEAAAAAAAAAAGc3ltYm9sAAAAAAAQ


 > stellar-cli contract info interface --network testnet --wasm ~/wasm/soroban_token_contract.wasm --output json
[{"function_v0":{"doc":"","name":"initialize","inputs":[{"doc":"","name":"admin","type_":"address"},{"doc":"","name":"decimal","type_":"u32"},{"doc":"","name":"name","type_":"string"},{"doc":"","name":"symbol","type_":"string"}],"outputs":[]}},{"function_v0":{"doc":"","name":"mint","inputs":[{"doc":"","name":"to","type_":"address"},{"doc":"","name":"amount","type_":"i128"}],"outputs":[]}},{"function_v0":{"doc":"","name":"set_admin","inputs":[{"doc":"","name":"new_admin","type_":"address"}],"outputs":[]}},{"function_v0":{"doc":"","name":"allowance","inputs":[{"doc":"","name":"from","type_":"address"},{"doc":"","name":"spender","type_":"address"}],"outputs":["i128"]}},{"function_v0":{"doc":"","name":"approve","inputs":[{"doc":"","name":"from","type_":"address"},{"doc":"","name":"spender","type_":"address"},{"doc":"","name":"amount","type_":"i128"},{"doc":"","name":"expiration_ledger","type_":"u32"}],"outputs":[]}},{"function_v0":{"doc":"","name":"balance","inputs":[{"doc":"","name":"id","type_":"address"}],"outputs":["i128"]}},{"function_v0":{"doc":"","name":"transfer","inputs":[{"doc":"","name":"from","type_":"address"},{"doc":"","name":"to","type_":"address"},{"doc":"","name":"amount","type_":"i128"}],"outputs":[]}},{"function_v0":{"doc":"","name":"transfer_from","inputs":[{"doc":"","name":"spender","type_":"address"},{"doc":"","name":"from","type_":"address"},{"doc":"","name":"to","type_":"address"},{"doc":"","name":"amount","type_":"i128"}],"outputs":[]}},{"function_v0":{"doc":"","name":"burn","inputs":[{"doc":"","name":"from","type_":"address"},{"doc":"","name":"amount","type_":"i128"}],"outputs":[]}},{"function_v0":{"doc":"","name":"burn_from","inputs":[{"doc":"","name":"spender","type_":"address"},{"doc":"","name":"from","type_":"address"},{"doc":"","name":"amount","type_":"i128"}],"outputs":[]}},{"function_v0":{"doc":"","name":"decimals","inputs":[],"outputs":["u32"]}},{"function_v0":{"doc":"","name":"name","inputs":[],"outputs":["string"]}},{"function_v0":{"doc":"","name":"symbol","inputs":[],"outputs":["string"]}},{"udt_struct_v0":{"doc":"","lib":"","name":"AllowanceDataKey","fields":[{"doc":"","name":"from","type_":"address"},{"doc":"","name":"spender","type_":"address"}]}},{"udt_struct_v0":{"doc":"","lib":"","name":"AllowanceValue","fields":[{"doc":"","name":"amount","type_":"i128"},{"doc":"","name":"expiration_ledger","type_":"u32"}]}},{"udt_union_v0":{"doc":"","lib":"","name":"DataKey","cases":[{"tuple_v0":{"doc":"","name":"Allowance","type_":[{"udt":{"name":"AllowanceDataKey"}}]}},{"tuple_v0":{"doc":"","name":"Balance","type_":["address"]}},{"tuple_v0":{"doc":"","name":"State","type_":["address"]}},{"void_v0":{"doc":"","name":"Admin"}}]}},{"udt_struct_v0":{"doc":"","lib":"","name":"TokenMetadata","fields":[{"doc":"","name":"decimal","type_":"u32"},{"doc":"","name":"name","type_":"string"},{"doc":"","name":"symbol","type_":"string"}]}}]



 > stellar-cli contract info interface --network testnet --wasm ~/wasm/soroban_token_contract.wasm
#[soroban_sdk::contractclient(name = "Client")]
pub trait Contract {
    fn initialize(
        env: soroban_sdk::Env,
        admin: soroban_sdk::Address,
        decimal: u32,
        name: soroban_sdk::String,
        symbol: soroban_sdk::String,
    );
    fn mint(env: soroban_sdk::Env, to: soroban_sdk::Address, amount: i128);
    fn set_admin(env: soroban_sdk::Env, new_admin: soroban_sdk::Address);
    fn allowance(
        env: soroban_sdk::Env,
        from: soroban_sdk::Address,
        spender: soroban_sdk::Address,
    ) -> i128;
    fn approve(
        env: soroban_sdk::Env,
        from: soroban_sdk::Address,
        spender: soroban_sdk::Address,
        amount: i128,
        expiration_ledger: u32,
    );
    fn balance(env: soroban_sdk::Env, id: soroban_sdk::Address) -> i128;
    fn transfer(
        env: soroban_sdk::Env,
        from: soroban_sdk::Address,
        to: soroban_sdk::Address,
        amount: i128,
    );
    fn transfer_from(
        env: soroban_sdk::Env,
        spender: soroban_sdk::Address,
        from: soroban_sdk::Address,
        to: soroban_sdk::Address,
        amount: i128,
    );
    fn burn(env: soroban_sdk::Env, from: soroban_sdk::Address, amount: i128);
    fn burn_from(
        env: soroban_sdk::Env,
        spender: soroban_sdk::Address,
        from: soroban_sdk::Address,
        amount: i128,
    );
    fn decimals(env: soroban_sdk::Env) -> u32;
    fn name(env: soroban_sdk::Env) -> soroban_sdk::String;
    fn symbol(env: soroban_sdk::Env) -> soroban_sdk::String;
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct AllowanceDataKey {
    pub from: soroban_sdk::Address,
    pub spender: soroban_sdk::Address,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct AllowanceValue {
    pub amount: i128,
    pub expiration_ledger: u32,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct TokenMetadata {
    pub decimal: u32,
    pub name: soroban_sdk::String,
    pub symbol: soroban_sdk::String,
}
#[soroban_sdk::contracttype(export = false)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum DataKey {
    Allowance(AllowanceDataKey),
    Balance(soroban_sdk::Address),
    State(soroban_sdk::Address),
    Admin,
}



Why

See #1506

Known limitations

Network configuration is mandatory, even when fetching from local. This is due to group can't be marked as optional with clap's derive API. We can fix that in the future, potentially using more flexible builder API instead.

Copy link
Member

@leighmcculloch leighmcculloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work. I left some comments inline.

cmd/crates/soroban-spec-tools/src/contract.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/info.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/info/meta.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/mod.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/info/shared.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/info/shared.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/commands/contract/mod.rs Outdated Show resolved Hide resolved
github-merge-queue bot pushed a commit to stellar/rs-soroban-sdk that referenced this pull request Aug 8, 2024
### What
Expose rust code gen of contracts without the file import.

### Why
The code gen function for rust code generates the interface and types as
well as an import of the wasm binary. The CLI uses this function and
wants to output the generated code without the wasm binary.

Related to:
-
stellar/stellar-cli#1532 (comment)
@fnando
Copy link
Member

fnando commented Aug 9, 2024

Can we make the json output be prettified?

@Ifropc
Copy link
Contributor Author

Ifropc commented Aug 12, 2024

@fnando pretty json is --output json-formatted. Regular json is if you want to use something like jq or process it programmatically (and we don't care about formatting)

Copy link
Member

@leighmcculloch leighmcculloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some code being deleted that is a breaking change, and one other ask, otherwise looks good.

cmd/soroban-cli/src/commands/contract/info/env_meta.rs Outdated Show resolved Hide resolved
cmd/soroban-cli/src/wasm.rs Outdated Show resolved Hide resolved
@leighmcculloch leighmcculloch linked an issue Aug 12, 2024 that may be closed by this pull request
@Ifropc Ifropc merged commit 3515ce7 into main Aug 13, 2024
26 checks passed
@Ifropc Ifropc deleted the 1506-contract-info branch August 13, 2024 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Proposal: add a new contract info command
3 participants