diff --git a/docs/tools/README.mdx b/docs/tools/README.mdx index eb9364742..5f537dff5 100644 --- a/docs/tools/README.mdx +++ b/docs/tools/README.mdx @@ -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) diff --git a/docs/tools/openzeppelin-relayer.mdx b/docs/tools/openzeppelin-relayer.mdx index e56daf8d7..e75edf018 100644 --- a/docs/tools/openzeppelin-relayer.mdx +++ b/docs/tools/openzeppelin-relayer.mdx @@ -1,23 +1,31 @@ --- 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. + +::: + +## 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 @@ -25,11 +33,11 @@ This guide assumes you have deployed the Increment smart contract example code f ### 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"; @@ -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 @@ -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); ``` @@ -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"; @@ -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!); @@ -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 @@ -211,7 +219,7 @@ The page markup code checks if result contains a value. If not, the button for i > {result ? (

- Result from Relayer: {result} + Result from Channels: {result}

) : (

@@ -219,7 +227,7 @@ The page markup code checks if result contains a value. If not, the button for i 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

)} @@ -254,7 +262,7 @@ export default function Home() {
{result ? (

- Result from Relayer: {result} + Result from Channels: {result}

) : (

@@ -262,7 +270,7 @@ export default function Home() { 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

)} @@ -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"; @@ -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(), }); @@ -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"; @@ -421,7 +429,7 @@ 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; } } @@ -429,7 +437,7 @@ export const SendTransaction = async (destinationPublicKey: string, amount: stri ### 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