Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tools/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Quickstart is a local Stellar network environment (node) that allows developers

### [OpenZeppelin Relayer](./openzeppelin-relayer.mdx)

OpenZeppelin Relayer, also known as Stellar Channels Service, is a managed infrastructure for submitting Stellar Soroban transactions with automatic parallel processing and fee management. The service handles all the complexity of transaction submission, allowing you to focus on building your application.
OpenZeppelin Relayer is an open source framework for submitting Stellar transactions, with automatic parallel processing and fee management. You can run your own instance, or you can use [Stellar Channels](https://docs.openzeppelin.com/relayer/1.3.x/guides/stellar-channels-guide), the managed service OpenZeppelin operates on top of the Relayer, where OpenZeppelin runs the pool of channel accounts and covers the fees under a fair use policy.

### [OpenZeppelin Contracts](./openzeppelin-contracts.mdx)

Expand Down
76 changes: 42 additions & 34 deletions docs/tools/openzeppelin-relayer.mdx
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
---
title: OpenZeppelin Relayer
description: OpenZeppelin Relayer is a service that provides infrastructure to relay transactions to the Stellar network.
description: OpenZeppelin Relayer is an open source framework for submitting transactions to the Stellar network, and Stellar Channels is the managed service OpenZeppelin runs on top of it.
sidebar_label: OpenZeppelin Relayer
sidebar_position: 43
---

Launchtube, which served as an experimental service for fee sponsorship and contract invocations, has been instrumental in early-stage deployments and developer experimentation. However, while functional for testing and early use cases, Launchtube does not have the maturity, scalability and auditing as OpenZeppelin’s Relayer service, which is why the Stellar Development Foundation is discontinuing the Launchtube service and provides the Relayer service as a replacement.
Launchtube, which served as an experimental service for fee sponsorship and contract invocations, has been instrumental in early-stage deployments and developer experimentation. However, while functional for testing and early use cases, Launchtube does not have the same maturity, scalability, or level of auditing as OpenZeppelin’s Relayer, which is why the Stellar Development Foundation is discontinuing the Launchtube service and points developers to OpenZeppelin’s managed Stellar Channels service as the replacement.

OpenZeppelin Relayer, also known as [Stellar Channels Service](https://docs.openzeppelin.com/relayer/1.3.x/guides/stellar-channels-guide), is a managed infrastructure for submitting Stellar Soroban transactions with automatic parallel processing and fee management. The service handles all the complexity of transaction submission, allowing you to focus on building your application.
OpenZeppelin Relayer is an open source (AGPL-3.0) framework for submitting Stellar transactions, including Soroban contract invocations, with automatic parallel processing and fee management. If you [run your own instance](https://github.com/OpenZeppelin/openzeppelin-relayer), you hold the signing keys and you fund the accounts that pay the fees.

## OpenZeppelin Relayer Status
[Stellar Channels](https://docs.openzeppelin.com/relayer/1.3.x/guides/stellar-channels-guide) is the managed service OpenZeppelin operates on top of the Relayer. There are no servers, relayers, or channel accounts for you to configure, because OpenZeppelin runs the pool of channel accounts and covers the fees, subject to a fair use policy.

To see live status of the OpenZeppelin relayer, please visit this [Status] page: https://status.channels.openzeppelin.com/.
:::note

The examples on this page use the managed Channels service, so they authenticate with a Channels API key rather than talking to a relayer you run yourself.
Comment thread
ElliotFriend marked this conversation as resolved.

:::

## Stellar Channels status

To see the live status of Stellar Channels, please visit this [Status] page: https://status.channels.openzeppelin.com/.

## Smart contract invocation

Let’s create a simple application that submits a transaction, invoking a smart contract function, using Relayer. The application calls the Increment smart contract and returns the current counter value.
Let’s create a simple application that submits a transaction, invoking a smart contract function, using Channels. The application calls the Increment smart contract and returns the current counter value.

The application is based on the Next.js framework and has server side code and client side code. The OpenZeppelin Relayer SDK makes HTTPS-requests to OpenZeppelin endpoints, which will trigger CORS errors when run client side, but by using the SDK server side, CORS will not be an issue.
The application is based on the Next.js framework and has server side code and client side code. The `@openzeppelin/relayer-plugin-channels` SDK makes HTTPS-requests to OpenZeppelin endpoints, which will trigger CORS errors when run client side, but by using the SDK server side, CORS will not be an issue.

### Prerequisites

This guide assumes you have deployed the Increment smart contract example code found [here](https://github.com/stellar/soroban-examples/tree/v22.0.1/increment). See the [Getting Started](../build/smart-contracts/getting-started) tutorial section 3 and 4 for more information about building and deploying the Increment contract.

### Server Side

In this simple application we only have one function server side, and that’s a function calling a smart contract function, by submitting a transaction through Relayer.
In this simple application we only have one function server side, and that’s a function calling a smart contract function, by submitting a transaction through Channels.

#### 1. Initialize Relayer client
#### 1. Initialize the Channels client

First the two necessary SDKs are imported, and the Relayer client is initialized. In this tutorial we use testnet, so the Relayer service endpoint for testnet is used as the base URL. The API key can be generated [here](https://channels.openzeppelin.com/testnet/gen).
First the two necessary SDKs are imported, and the Channels client is initialized. In this tutorial we use testnet, so the Channels endpoint for testnet is used as the base URL. The API key can be generated [here](https://channels.openzeppelin.com/testnet/gen).

```js
"use server";
Expand Down Expand Up @@ -71,9 +79,9 @@ const tx = new StellarSDK.TransactionBuilder(account, {

#### 4. Simulate transaction and get XDRs

The final steps before we can submit the transaction to Relayer is to simulate the transaction, bundle the transaction and simulation, and extract the transaction’s function and auth XDRs.
The final steps before we can submit the transaction to Channels is to simulate the transaction, bundle the transaction and simulation, and extract the transaction’s function and auth XDRs.

We are extracting the function and auth from the assembled transaction, in XDR format, because that’s what we need to submit to Relayer.
We are extracting the function and auth from the assembled transaction, in XDR format, because that’s what we need to submit to Channels.

```js
// Simulate to get auth entries
Expand All @@ -85,17 +93,17 @@ const contractFunc = op.func.toXDR("base64");
const contractAuth = (op.auth ?? []).map((a) => a.toXDR("base64"));
```

#### 5. Build Relayer request and submit it
#### 5. Build the Channels request and submit it

Now we have completed all necessary steps to submit a transaction to Relayer. First the request is built, and then the request is submitted to Relayer.
Now we have completed all necessary steps to submit a transaction to Channels. First the request is built, and then the request is submitted to Channels.

```typescript
// Build request for Relayer
// Build request for Channels
const request: RPChannels.ChannelsFuncAuthRequest = {
func: contractFunc,
auth: contractAuth,
};
// Submit to Channels Relayer
// Submit to Channels
const response: RPChannels.ChannelsTransactionResponse =
await client.submitSorobanTransaction(request);
```
Expand Down Expand Up @@ -125,7 +133,7 @@ return StellarSDK.scValToNative(txResponse.returnValue);

#### 7. The complete code

The previous six steps contain all the functionality needed for invoking a smart contract function through Relayer. This is the complete code for the function that we will call from the client side (frontend):
The previous six steps contain all the functionality needed for invoking a smart contract function through Channels. This is the complete code for the function that we will call from the client side (frontend):

```js title="backend/index.tsx"
"use server";
Expand Down Expand Up @@ -159,12 +167,12 @@ export const SendContractTransaction = async (sourceId: string, contractId: stri
const op = assembled.operations[0];
const contractFunc = op.func.toXDR('base64');
const contractAuth = (op.auth ?? []).map((a) => a.toXDR('base64'));
// Build request for Relayer
// Build request for Channels
const request: RPChannels.ChannelsFuncAuthRequest = {
func: contractFunc,
auth: contractAuth,
};
// Submit to Channels Relayer
// Submit to Channels
const response: RPChannels.ChannelsTransactionResponse = await client.submitSorobanTransaction(request);
// Poll for transaction result
let txResponse = await rpc.pollTransaction(response.hash!);
Expand All @@ -175,7 +183,7 @@ export const SendContractTransaction = async (sourceId: string, contractId: stri

### Client Side

The client side code shows a button on the page in the browser, and when clicked, the server side function will be called with the relevant parameters. When the function returns a value, the value is shown on the page instead of the button. The functionality is very simple, but serves well as an end-to-end example of submitting a transaction with Relayer.
The client side code shows a button on the page in the browser, and when clicked, the server side function will be called with the relevant parameters. When the function returns a value, the value is shown on the page instead of the button. The functionality is very simple, but serves well as an end-to-end example of submitting a transaction with Channels.

#### 1. Call server side function

Expand Down Expand Up @@ -211,15 +219,15 @@ The page markup code checks if result contains a value. If not, the button for i
>
{result ? (
<h2 className="mb-10 text-2xl font-semibold text-black dark:text-white">
Result from Relayer: {result}
Result from Channels: {result}
</h2>
) : (
<h2 className="mb-10 text-2xl font-semibold text-black dark:text-white">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick="{callContract}"
>
Call Contract via Relayer
Call Contract via Channels
</button>
</h2>
)}
Expand Down Expand Up @@ -254,15 +262,15 @@ export default function Home() {
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
{result ? (
<h2 className="mb-10 text-2xl font-semibold text-black dark:text-white">
Result from Relayer: {result}
Result from Channels: {result}
</h2>
) : (
<h2 className="mb-10 text-2xl font-semibold text-black dark:text-white">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={callContract}
>
Call Contract via Relayer
Call Contract via Channels
</button>
</h2>
)}
Expand All @@ -274,17 +282,17 @@ export default function Home() {

## Account transfer

Let’s create another simple application, this application submits a transfer transaction, sending XLM tokens from one account to another, using Relayer.
Let’s create another simple application, this application submits a transfer transaction, sending XLM tokens from one account to another, using Channels.

The application is based on the Next.js framework and has server side code and client side code. The OpenZeppelin Relayer SDK makes HTTPS-requests to OpenZeppelin endpoints, which will trigger CORS errors when run client side, but by using the SDK server side, CORS will not be an issue.
The application is based on the Next.js framework and has server side code and client side code. The `@openzeppelin/relayer-plugin-channels` SDK makes HTTPS-requests to OpenZeppelin endpoints, which will trigger CORS errors when run client side, but by using the SDK server side, CORS will not be an issue.

### Server Side

In this simple application we only have one function server side, and that’s a function making a transfer of XLM tokens from one account to another, by submitting a transaction through Relayer.
In this simple application we only have one function server side, and that’s a function making a transfer of XLM tokens from one account to another, by submitting a transaction through Channels.

#### 1. Initialize Relayer client
#### 1. Initialize the Channels client

First the two necessary SDKs are imported, and the Relayer client is initialized. In this tutorial we use testnet, so the Relayer service endpoint for testnet is used as the base URL. The API key can be generated [here](https://channels.openzeppelin.com/testnet/gen).
First the two necessary SDKs are imported, and the Channels client is initialized. In this tutorial we use testnet, so the Channels endpoint for testnet is used as the base URL. The API key can be generated [here](https://channels.openzeppelin.com/testnet/gen).

```js
"use server";
Expand Down Expand Up @@ -341,10 +349,10 @@ transaction.sign(sourceKeypair);

#### 4. Submit the transaction

Now we have completed all necessary steps to submit the transaction to Relayer. The Relayer SDK function `submitTransaction()` takes the transaction in XDR-format as an argument.
Now we have completed all necessary steps to submit the transaction to Channels. The Channels client function `submitTransaction()` takes the transaction in XDR-format as an argument.

```js
// Submit to Channels Relayer
// Submit to Channels
const response = await client.submitTransaction({
xdr: transaction.toXDR(),
});
Expand All @@ -370,7 +378,7 @@ return response.hash;

#### 6. The complete code

The previous five steps contain all the functionality needed for transferring XLM tokens from the source account to another account through Relayer. This is the complete code for the function that we will call from the client side (frontend):
The previous five steps contain all the functionality needed for transferring XLM tokens from the source account to another account through Channels. This is the complete code for the function that we will call from the client side (frontend):

```js title="backend/index.tsx"
"use server";
Expand Down Expand Up @@ -421,15 +429,15 @@ export const SendTransaction = async (destinationPublicKey: string, amount: stri

return response.hash;
} catch (error) {
console.error('Failed to submit Stellar transaction via OpenZeppelin Relayer:', error);
console.error('Failed to submit Stellar transaction via OpenZeppelin Channels:', error);
throw error;
}
}
```

### Client Side

The client side code shows a form with input fields for a transfer-to-address, and amount to transfer, on the page in the browser. When the form is filled out and submitted, the server side function will be called with the form values as parameters. When the function returns with the transaction hash, the hash is shown on the page instead of the form. The functionality is very simple, but serves well as an end-to-end example of submitting a token transfer transaction with Relayer.
The client side code shows a form with input fields for a transfer-to-address, and amount to transfer, on the page in the browser. When the form is filled out and submitted, the server side function will be called with the form values as parameters. When the function returns with the transaction hash, the hash is shown on the page instead of the form. The functionality is very simple, but serves well as an end-to-end example of submitting a token transfer transaction with Channels.

#### 1. Call server side function

Expand Down