Fully-Typed Contracts
When you compile a contract created with soroban-sdk, the Wasm file ends up with a custom section containing a machine-readable description of your contract's interface types, sometimes called its spec or its API. This is similar to ABIs in Ethereum, except that Soroban will store every single one of them on-chain from day one, and they include comments from the contract's author.
These interface types are formatted using XDR, a data format used widely throughout Stellar. It can be tricky to create or consume XDR manually, but tooling can fetch these interface types to make your life easier. Stellar CLI and Stellar SDK are two such tools to do so. Let's look at each.
Stellar CLI: stellar contract invoke
Really, every smart contract is its own program, and deserves its own CLI.
So that's what Stellar CLI gives you.
A unique CLI for each smart contract. Constructed on-the-fly, right from the on-chain interface types. Including the author's comments. An implicit CLI.
For example, calling the native asset contract on the Test network:
$ stellar contract invoke --network testnet --id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC -- --help
Usage: CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC [COMMAND]
Commands:
balance Returns the balance of `id`.
# Arguments
* `id` - The address for which a balance is being queried. If the
address has no existing balance, returns 0.
...
transfer Transfer `amount` from `from` to `to`.
# Arguments
* `from` - The address holding the balance of tokens which will be
withdrawn from.
* `to` - The address which will receive the transferred tokens.
* `amount` - The amount of tokens to be transferred.
# Events
Emits an event with topics `["transfer", from: Address, to: Address],
data = amount: i128`
...
Options:
-h, --help Print help
Like any other CLI, you can also get help for any of these subcommands. Omitting everything before the --
in the previous command, this would look like: … -- balance --help
. Stellar CLI again fetches the on-chain interface types, this time using it to generate a full list of all arguments to the function, and even generates examples.
If you're unfamiliar with the --
double dash separator, this is a pattern used by other CLIs. Everything after the double dash, sometimes called the slop, gets passed to the child process. An example of other CLIs that make use of this are npm run
and cargo run
.
Stellar JS SDK: contract.Client
To create a contract client for the same contract as shown for contract invoke
above, you would use this JavaScript:
import { contract } from "@stellar/stellar-sdk";
const xlm = contract.Client({
contractId: "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
networkPassphrase: "Test SDF Network ; September 2015",
rpcUrl: "https://soroban-testnet.stellar.org",
});
Like the CLI, this will fetch the contract from the live network and parse the contract's types/spec. It will auto-generate a class that allows you to ergonomically call the contract's methods:
xlm.balance({ id: "G123…" });
Note that everything shown above works dynamically from a browser. However, sometimes it's nice to also have this behavior available as a library, while building apps. And in this case, it's really nice to have TypeScript, which enables type-ahead for all methods in the contract, and which can include the comments from the contract's original author. That's what the CLI's contract bindings typescript
command is for:
stellar contract bindings typescript \
--network testnet \
--output-dir xlm --overwrite \
--id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
This creates a fully-typed NPM module for the given contract.
Already the best; just getting started
We love that Soroban had all contract interface types available on-chain right from day one. No secondary API calls to external services, no secondary API token management, no signing in or creating an account anywhere else, and near-perfect reliability. It's a game-changer within the blockchain space.
Stellar CLI and JS SDK already show how this can be built into foundational tooling to give developers delightful experiences. And this is only the beginning. At every level of the stack, you can expect—and build—tooling that makes interacting with any contract predictable and seamless.
Soon we'll have GUIs that adapt to any given contract on-the-fly, functioning as interactive documentation. If you're writing contracts that make cross-contract calls, most of the code you need can also be auto-generated.
And that's still all just the beginning. With those as the foundations, what else can we build? What else can you imagine? What is the future of components, now that one small program, aka smart contract, can be easily interacted with at all layers of the software stack? When considered in combination with Wasm—on-chain, in-browser, and elsewhere—what possibilities for interop can we imagine and co-create?
We can't wait to see what you build.