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

Update fully-typed-contracts.mdx #823

Merged
merged 12 commits into from
Aug 20, 2024
61 changes: 32 additions & 29 deletions docs/build/apps/example-application-tutorial/path-payment.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,35 +114,38 @@ Most of this page has been discussed in the [Payment section](./payment.mdx#the-

// Create a payment transaction depending on user selections, and present it to the user for approval or rejection.
const previewPaymentTransaction = async () => {
let { transaction, network_passphrase } = createAccount
? await createCreateAccountTransaction({
/* ... */
})
: // highlight-start
pathPayment && strictReceive
? await createPathPaymentStrictReceiveTransaction({
source: data.publicKey,
sourceAsset: sendAsset,
sourceAmount: sendAmount,
destination: otherDestination ? otherPublicKey : destination,
destinationAsset: receiveAsset,
destinationAmount: receiveAmount,
memo: memo,
})
: pathPayment && !strictReceive
? await createPathPaymentStrictSendTransaction({
source: data.publicKey,
sourceAsset: sendAsset,
sourceAmount: sendAmount,
destination: otherDestination ? otherPublicKey : destination,
destinationAsset: receiveAsset,
destinationAmount: receiveAmount,
memo: memo,
})
: // highlight-end
await createPaymentTransaction({
/* ... */
});
let transaction, network_passphrase
if (createAccount) {
{ transaction, network_passphrase } = await createCreateAccountTransaction({
/* ... */
})
// highlight-start
} else if (pathPayment && strictReceive) {
{ transaction, network_passphrase } = await createPathPaymentStrictReceiveTransaction({
source: data.publicKey,
sourceAsset: sendAsset,
sourceAmount: sendAmount,
destination: otherDestination ? otherPublicKey : destination,
destinationAsset: receiveAsset,
destinationAmount: receiveAmount,
memo: memo,
})
} else if (pathPayment && !strictReceive) {
{ transaction, network_passphrase } = await createPathPaymentStrictSendTransaction({
source: data.publicKey,
sourceAsset: sendAsset,
sourceAmount: sendAmount,
destination: otherDestination ? otherPublicKey : destination,
destinationAsset: receiveAsset,
destinationAmount: receiveAmount,
memo: memo,
})
// highlight-end
} else {
{ transaction, network_passphrase } = await createPaymentTransaction({
/* ... */
});
}

/* ... */
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,22 @@ sidebar_label: Fully-Typed Contracts
/>
</head>

When you compile a contract created with [soroban-sdk](../../../../tools/sdks/library.mdx#soroban-rust-sdk), the Wasm file ends up with a [custom section](https://webassembly.github.io/spec/core/appendix/custom.html) containing a machine-readable description of your contract's interface types, sometimes called its [spec](https://github.com/stellar/rs-soroban-sdk/tree/main/soroban-spec) or its [API](https://github.com/stellar/soroban-docs/pull/381#issuecomment-1507283476). This is similar to [ABIs](https://www.quicknode.com/guides/ethereum-development/smart-contracts/what-is-an-abi/) in Ethereum, except that Soroban will store every single one of them on-chain from day one, and they include the comments from the contract's author.
When you compile a contract created with [soroban-sdk](../../../../tools/sdks/library.mdx#soroban-rust-sdk), the Wasm file ends up with a [custom section](https://webassembly.github.io/spec/core/appendix/custom.html) containing a machine-readable description of your contract's interface types, sometimes called its [spec](https://github.com/stellar/rs-soroban-sdk/tree/main/soroban-spec) or its [API](https://github.com/stellar/soroban-docs/pull/381#issuecomment-1507283476). This is similar to [ABIs](https://www.quicknode.com/guides/ethereum-development/smart-contracts/what-is-an-abi/) 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.

Today, these interface types are formatted using [XDR](../../data-format/xdr.mdx), but this [may change](https://github.com/stellar/rs-soroban-sdk/issues/683) down the road.
These interface types are formatted using [XDR](../../data-format/xdr.mdx), 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](../../../../tools/developer-tools/cli/README.mdx#cli) and [Stellar SDK](../../../../tools/sdks/library.mdx#javascript-sdk) are two such tools to do so. Let's look at each.

The important part is that tooling can fetch these interface types to make your life easier. [Stellar CLI](../../../../tools/developer-tools/cli/README.mdx) is the first tool to do so. Specifically, one subcommand:

## `stellar contract invoke`
## 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_.

With aliases in your shell, you can also easily make explicit CLIs out of your most-used contracts. For example, if you use the native asset contract on the Test Network:
For example, calling the native asset contract on the Test network:

```bash
$ alias native="soroban contract invoke --network testnet --id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC --"
$ native --help
$ stellar contract invoke --network testnet --id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC -- --help
Usage: CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC [COMMAND]

Commands:
Expand Down Expand Up @@ -69,29 +66,51 @@ Options:
-h, --help Print help
```

Like any other CLI, you can also get help for any of these subcommands using something like `native 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.
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.

:::tip

And just to be totally clear, you don't need to alias these commands. This would work, too:
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](https://github.com/clap-rs/clap/issues/971), gets passed to the child process. An example of other CLIs that make use of this are `npm run` and `cargo run`.

```bash
soroban contract invoke --network testnet --id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC -- balance --help
:::

## 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:

```js
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:

```js
xlm.balance({ id: "G123…" });
```

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](https://github.com/clap-rs/clap/issues/971), gets passed to the child process. An example of another CLI that makes use of this is `cargo run`.
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:

```bash
stellar contract bindings typescript \
--network testnet \
--output-dir xlm --overwrite \
--id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
```

Of course, the exact way that that Stellar CLI parses arguments is an ongoing design discussion. Representing complex custom arguments on the command line is a design challenge no blockchain CLI gets perfect yet; many, including Stellar CLI, currently use JSON. But this has downsides, and other options are possible. [How would you like to see it work?](https://docs.google.com/document/d/1LASaLyxIA2-YqLnn2NqI5NZGnEmdzx9lLh-j7n0-i4A/edit#)
This creates a fully-typed NPM module for the given contract.

## Already the best; just getting started

We love that Soroban will have 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.
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 already shows 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](https://stellar.org/foundation/grants-and-funding)—tooling that makes interacting with any contract predictable and seamless.
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](https://stellar.org/foundation/grants-and-funding)—tooling that makes interacting with any contract predictable and seamless.

Soon we'll have TypeScript/JavaScript libraries that mirror the behavior of `soroban contract invoke`, customized for browser & nodejs environments. You can expect 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.
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](https://en.wikipedia.org/wiki/WebAssembly#Implementations)—what possibilities for interop can we imagine and co-create?

Expand Down
Loading