Skip to content

Commit 555512e

Browse files
authored
Merge branch 'main' into old-meetings
2 parents 43199d3 + b6b20ab commit 555512e

21 files changed

Lines changed: 746 additions & 591 deletions

File tree

config/theme/navbar.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ const build: NavbarItem = {
7979
label: 'Tutorial: Dapp Frontend',
8080
activeBasePath: 'docs/build/apps/dapp-frontend',
8181
},
82+
{
83+
to: '/docs/build/apps/x402',
84+
label: 'x402 on Stellar',
85+
activeBasePath: 'docs/build/apps/x402',
86+
},
8287
{
8388
to: '/docs/build/apps/zk',
8489
label: 'ZK Proofs on Stellar',

docs/build/apps/dapp-frontend.mdx

Lines changed: 376 additions & 433 deletions
Large diffs are not rendered by default.

docs/build/apps/x402.mdx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: x402 on Stellar
3+
sidebar_position: 74
4+
sidebar_label: x402
5+
description: "Use the x402 protocol for per-request HTTP payments on Stellar, with support for AI agents and APIs."
6+
---
7+
8+
## What is x402?
9+
10+
x402 is an open protocol from the Coinbase Developer Platform that enables programmatic, per request payments over HTTP, designed especially for AI agents and APIs. It effectively turns the old “402 Payment Required” HTTP status code into something usable, for both humans and AI agents.
11+
12+
On Stellar, x402 works with Soroban authorization so that clients can pay for API requests via signed auth entries, ideal for micropayments and payment enabled apps. To build an x402-enabled service or integrate payments into your app, see [Build Applications](./README.mdx) and the resources below.
13+
14+
## x402 Compatible Wallets
15+
16+
To support x402 on Stellar, a wallet must support [auth-entry signing](../guides/transactions/signing-soroban-invocations.mdx#method-2-auth-entry-signing) (Soroban authorization entry signing). The following wallets support auth-entry signing:
17+
18+
- Freighter Browser Extension
19+
- Albedo
20+
- Hana
21+
- HOT
22+
- Klever
23+
- One Key
24+
25+
:::note
26+
27+
Freighter Mobile does not currently support x402; use the Freighter browser extension. Mobile support is planned for a future release.
28+
29+
:::
30+
31+
## x402 Facilitator from OpenZeppelin
32+
33+
The [OpenZeppelin Relayer x402 Plugin for x402](https://github.com/OpenZeppelin/relayer-plugin-x402-facilitator) implements the x402 facilitator API so you can serve x402 payments directly from a Relayer instance. It works with the Coinbase x402 ecosystem (e.g., @x402/express) and exposes the expected `/verify`, `/settle`, and `/supported` endpoints under the Relayer plugin router.
34+
35+
:::note
36+
37+
This version supports x402 v2 specification. For x402 v1 support, please use a previous version of this plugin (check git history for v1 compatible releases).
38+
39+
:::
40+
41+
## Resources
42+
43+
- **x402 Starter Template** — A starter template for building payment-enabled applications with x402. Simplified scaffolding demonstrating x402 payment protocol integration with browser wallet support; use it as a foundation for micropayment-enabled services, SaaS applications, or any project that needs frictionless web payments. [View on GitHub](https://github.com/ElliotFriend/x402/tree/stellar-browser-wallet-example/examples/typescript/fullstack/browser-wallet-example)
44+
- **Economic Load Balancer** — An intelligent multi-chain payment router that automatically selects the most cost-efficient network for high-frequency AI agent micropayments. [View on GitHub](https://github.com/marcelosalloum/x402/tree/x402-hackathon)
45+
46+
## Learn more
47+
48+
- [x402 protocol (Coinbase Developer Platform)](https://docs.cdp.coinbase.com/x402) — Official x402 protocol overview and spec
49+
- [Signing Soroban invocations](../guides/transactions/signing-soroban-invocations.mdx) — Auth-entry signing and transaction signing on Stellar

docs/build/guides/conventions/cross-contract.mdx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Making cross-contract calls
33
description: Call a smart contract from within another smart contract
44
---
55

6-
As with developing software in any language, developing a Stellar smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint.
6+
As with developing software in any language, developing a Stellar smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or built components which can be reused. The open source community is vibrant and Stellar's community does not disappoint.
77

88
There are two kinds of dependencies that can be introduced in a Stellar smart contract:
99

@@ -14,7 +14,7 @@ In the following, we will see how contracts can be leveraged from within another
1414

1515
## Contract as a dependency
1616

17-
While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Stellar smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself.
17+
While finding a contract is out of scope for this guide, there are a few places to be on the lookout. Most projects and dApps publicly disclose the address of their Stellar smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself.
1818

1919
:::info[Contract address]
2020

@@ -24,17 +24,17 @@ To depend on a project, we need to know the contract address of the contract to
2424

2525
## Public API
2626

27-
All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interface of a contract. Bindings can also be generated using the CLI:
27+
All public functions of a contract can be called. Using a network explorer can be helpful as some allow you to see the Rust interface of a contract. Bindings can also be generated using the CLI:
2828

2929
```bash
3030
stellar contract bindings rust --network --contract-id ... --output-dir ...
3131
```
3232

3333
## Making a cross-contract call
3434

35-
Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either load the Wasm or call the contract.
35+
Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either manually invoke the contract or use a contract client.
3636

37-
Let's start by using only a contract's address. In this example, we have an external contract with a public function named `add_with` which takes two `u32` as input values to sum them.
37+
Let's start by manually invoking the contract using only a contract's address. In this example, we have an external contract with a public function named `add_with` which takes two `u32` as input values to sum them.
3838

3939
```rust
4040
#[contract]
@@ -48,7 +48,9 @@ impl ContractB {
4848
}
4949
```
5050

51-
Only using the contract comes with its own challenges. Because we don't have access to the Wasm code, we don't have any typing inference and have to manually convert function inputs to `Val`. If we want more tools to help us, we can load the Wasm code in the contract. This allows us to pass normal types without needing manual conversions from our side. Behind the scenes, this way of doing it is simply a convenient wrapper around `env.invoke_contract`.
51+
Only using the contract address comes with its own challenges. We don't have a contract client so we don't have any typing inference, and have to manually convert function inputs to `Val`.
52+
53+
If we want more tools to help us, we need to get access to a contract client. A common way to do this is to load the Wasm of a contract using `contractimport!`. This allows us to pass normal types without needing manual conversions from our side. Behind the scenes, this way of doing it is simply a convenient wrapper around `env.invoke_contract`.
5254

5355
```rust
5456
mod contract_a {
@@ -83,7 +85,7 @@ client::ContractAEnum::SomeField
8385

8486
## Handling responses
8587

86-
In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This is to forward a custom error message, or even triggers an alternative code path.
88+
In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This allows you to forward a custom error message, or even trigger an alternative code path.
8789

8890
Enter `try_`. By using `env.try_invoke_contract` or `client.try_some_function`, underlying errors won't make the contract panic. Instead, errors will be wrapped and can be handled. For example if we wanted to default to 0 in case of an error:
8991

docs/build/guides/conventions/deploy-contract.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ The [deployer example](https://github.com/stellar/soroban-examples/tree/v22.0.1/
3535
1. Clone the Soroban Examples Repository:
3636

3737
```bash
38-
git clone -b v20.2.0 https://github.com/stellar/soroban-examples
38+
git clone -b v22.0.1 https://github.com/stellar/soroban-examples
3939
```
4040

4141
2. Navigate to the Deployer Example:
@@ -46,7 +46,7 @@ cd soroban-examples/deployer/deployer
4646

4747
:::note
4848

49-
For this example to work, you should navigate to `deployer/contracts` and `deployer/deployer` and run the command `stellar contract build` in each directory to generate the target files.
49+
For this example to work, you should navigate to `deployer/contract` and `deployer/deployer` and run the command `stellar contract build` in each directory to generate the target files.
5050

5151
:::
5252

@@ -219,8 +219,6 @@ stellar contract invoke \
219219
--init_args '[{"u32":8}]'
220220
```
221221

222-
replace `alice` with your own identity
223-
224222
The deployer contract invocation will return the Contract address (For example: `CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY`) of the newly deployed test contract.
225223

226224
Invoke the deployed test contract using the address returned from the previous command.

docs/build/guides/conventions/deploy-sac-with-code.mdx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ description: Deploy a SAC for a Stellar asset using Javascript SDK
2020

2121
## Overview
2222

23-
In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for a Stellar asset using the [Stellar SDK](../../../tools/sdks/client-sdks.mdx#javascript-sdk). The Stellar SDK is a set of tools and library designed to help developers build applications that interact with the Stellar blockchain network.
23+
In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../../../tokens/stellar-asset-contract.mdx) for a Stellar asset using the [Stellar SDK](../../../tools/sdks/client-sdks.mdx#javascript-sdk). The Stellar SDK is a set of tools and libraries designed to help developers build applications that interact with the Stellar blockchain network.
2424

2525
### Prerequisites:
2626

@@ -33,10 +33,9 @@ In this guide, you'll learn how to deploy a [Stellar Asset Contract (SAC)](../..
3333

3434
```javascript title="deployassetcontract.js"
3535
import * as StellarSdk from "@stellar/stellar-sdk";
36-
import { Server } from "@stellar/stellar-sdk/rpc";
3736

3837
const networkRPC = "https://soroban-testnet.stellar.org";
39-
const server = new Server(networkRPC);
38+
const server = new StellarSdk.rpc.Server(networkRPC);
4039
const networkPassphrase = StellarSdk.Networks.TESTNET;
4140

4241
const deployStellarAssetContract = async () => {
@@ -90,20 +89,19 @@ import * as StellarSdk from "@stellar/stellar-sdk";
9089

9190
const networkRPC = "https://soroban-testnet.stellar.org";
9291
const server = new StellarSdk.rpc.Server(networkRPC);
93-
const network_passphrase = StellarSdk.Networks.TESTNET;
92+
const networkPassphrase = StellarSdk.Networks.TESTNET;
9493
```
9594

9695
- `networkRPC`: The URL for the Soroban testnet.
9796
- `server`: A new instance of `rpc.Server` is created, which will be used to interact with the Soroban testnet.
98-
- `network_passphrase`: sets the network passphrase to the TESTNET
97+
- `networkPassphrase`: sets the network passphrase to the TESTNET
9998

10099
**`DeployStellarAssetContract` function**
101100

102101
```javascript
103102
const deployStellarAssetContract = async () => {
104103
const sourceSecrets =
105104
"SASI6PA4K52GQJF6BC263GLYOADVKFJ4SZ7TFX4QQF2U76T3EJ54DT7Y"; // Replace with your Secret Key
106-
const networkPassphrase = StellarSdk.Networks.TESTNET;
107105
const sourceKeypair = StellarSdk.Keypair.fromSecret(sourceSecrets);
108106
const sourceAccount = await server.getAccount(sourceKeypair.publicKey());
109107

@@ -139,8 +137,6 @@ const deployStellarAssetContract = async () => {
139137
console.error("An error occurred while Deploying assets:", e);
140138
}
141139
};
142-
143-
await deployStellarAssetContract();
144140
```
145141

146142
This function is designed to deploy a Stellar Asset Contract (SAC) on the Soroban testnet.
@@ -150,4 +146,4 @@ This function is designed to deploy a Stellar Asset Contract (SAC) on the Soroba
150146
- **Custom Asset**: Defines a custom asset with the code `JOEBOY` and the issuer's public key.
151147
- **Transaction Building**: A transaction is built using the `TransactionBuilder`, which includes the `createStellarAssetContract` operation for the custom asset. The transaction is then prepared and signed.
152148
- **Send Transaction**: The signed transaction is sent to the network using `server.sendTransaction`.
153-
- **Feedback Handling**: It waits for the transaction feedback using the `submitTx` function to ensure it has succeeded. extracts the contract buffer from the feedback and converts it to a contract ID using `StellarSdk.Address`. finally, it logs the contract ID for the deployed asset.
149+
- **Feedback Handling**: It waits for the transaction feedback using the `submitTx` function to ensure it has succeeded. Then, it extracts the return value and converts it to a contract ID using `StellarSdk.Address`. Finally, it logs the contract ID for the deployed asset.

docs/build/guides/conventions/error-enum.mdx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
title: Organize contract errors with an error enum type
33
hide_table_of_contents: true
4-
description: Manage and communicate contract errors using an enum struct stored as Status values
4+
description: Manage and communicate contract errors using an enum struct
55
---
66

7-
A convenient way to manage and meaningfully communicate contract errors is to collect them into an `enum` struct. These errors are a special type of enum integer type that are stored on ledger as Status values containing a `u32` code. First, create the `Error` struct in your smart contract.
7+
A convenient way to manage and meaningfully communicate contract errors is to collect them into an `enum` struct. These errors are a special type of enum integer type that are stored on the ledger as Error values containing a `u32` code. First, create the `Error` struct in your smart contract.
88

99
```rust
1010
#[contracterror]
@@ -18,18 +18,36 @@ pub enum Error {
1818
}
1919
```
2020

21-
Then, panic with an error when the conditions are met. This example will panic with the specified error.
21+
Smart contracts can fail with error enums in two different ways. They can either return a `Result` with their intended return value and the `#[contracterror]` struct as the error, or just invoke `panic_with_error!` with the appropriate Error enum value whenever an error condition is reached. By default, most ecosystem standards assume that contract functions do not return a `Result`, so using `panic_with_error!` is recommended.
22+
23+
However, both styles behave in the same way. If an error is returned or `panic_with_error!` is invoked, the transaction will fail. Contracts making cross contract calls have the ability to catch and handle these failures with `try_` functions.
2224

2325
```rust
2426
#[contractimpl]
2527
impl Contract {
26-
pub fn causeerror(env: Env, error_code: u32) -> Result<(), Error> {
27-
match error_code {
28-
1 => Err(Error::FirstError),
29-
2 => Err(Error::AnotherError),
30-
3 => Err(Error::YetAnotherError),
31-
_ => Err(Error::GenericError),
32-
}
28+
/// Call `panic_with_error!` to fail with custom errors
29+
/// This is the default, recommended approach adopted by most SEP standards
30+
pub fn cause_error(env: Env, error_code: u32) -> u32 {
31+
let error_type = match error_code {
32+
0 => return 0,
33+
1 => Error::FirstError,
34+
2 => Error::AnotherError,
35+
3 => Error::YetAnotherError,
36+
_ => Error::GenericError,
37+
};
38+
panic_with_error!(env, error_type);
39+
}
40+
41+
/// Return `Err` to fail with custom errors
42+
pub fn cause_error_result(env: Env, error_code: u32) -> Result<u32, Error> {
43+
let error_type = match error_code {
44+
0 => return Ok(0),
45+
1 => Error::FirstError,
46+
2 => Error::AnotherError,
47+
3 => Error::YetAnotherError,
48+
_ => Error::GenericError,
49+
};
50+
return Err(error_type);
3351
}
3452
}
3553
```

0 commit comments

Comments
 (0)