From 90c35268725ba3e80ff38f1c8d115be3fe72b6c1 Mon Sep 17 00:00:00 2001 From: Sebas <157399509+SebasGuaquetaRSK@users.noreply.github.com> Date: Thu, 19 Dec 2024 08:20:56 -0500 Subject: [PATCH] Devportal auto implemlementation (#294) * feat adding settings for automation in devportal --- .github/workflows/devportal-update.yml | 266 ++++++++++++++ README.md | 47 +++ Readme.md | 54 --- docs/architecture.md | 246 +++++++++++++ docs/contracts.md | 106 ++++++ docs/deployment.md | 341 ++++++++++++++++++ docs/develop.md | 19 + docs/gas-costs.md | 24 ++ docs/installation-requirements.md | 36 ++ docs/integrate.md | 292 +++++++++++++++ docs/sample-dapp.md | 132 +++++++ docs/smart-wallets.md | 68 ++++ docs/versions.md | 59 +++ {docs => docs[DEPRECATED]}/README.md | 0 .../basic_requirements.md | 0 .../development_guide.md | 0 .../enveloping_architecture.md | 0 .../integration_guide.md | 0 .../launching_enveloping.md | 0 .../overhead_tx_costs.md | 0 .../pr_128_changelog.md | 0 21 files changed, 1636 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/devportal-update.yml create mode 100644 README.md delete mode 100644 Readme.md create mode 100644 docs/architecture.md create mode 100644 docs/contracts.md create mode 100644 docs/deployment.md create mode 100644 docs/develop.md create mode 100644 docs/gas-costs.md create mode 100644 docs/installation-requirements.md create mode 100644 docs/integrate.md create mode 100644 docs/sample-dapp.md create mode 100644 docs/smart-wallets.md create mode 100644 docs/versions.md rename {docs => docs[DEPRECATED]}/README.md (100%) rename {docs => docs[DEPRECATED]}/basic_requirements.md (100%) rename {docs => docs[DEPRECATED]}/development_guide.md (100%) rename {docs => docs[DEPRECATED]}/enveloping_architecture.md (100%) rename {docs => docs[DEPRECATED]}/integration_guide.md (100%) rename {docs => docs[DEPRECATED]}/launching_enveloping.md (100%) rename {docs => docs[DEPRECATED]}/overhead_tx_costs.md (100%) rename {docs => docs[DEPRECATED]}/pr_128_changelog.md (100%) diff --git a/.github/workflows/devportal-update.yml b/.github/workflows/devportal-update.yml new file mode 100644 index 00000000..4e71861a --- /dev/null +++ b/.github/workflows/devportal-update.yml @@ -0,0 +1,266 @@ +name: Update Devportal Documentation + +on: + push: + paths: + - 'README.md' + branches: + - main + +permissions: read-all + +jobs: + update-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + + # Step 1: Clone the Devportal Repository + - name: Clone Devportal Repository + env: + GITHUB_TOKEN: ${{ secrets.DEVPORTAL_DOCS_UPDATE_TOKEN }} + run: | + TIMESTAMP=$(date +'%Y%m%d-%H%M%S') + BRANCH_NAME="update-from-rif-relay-${TIMESTAMP}" + echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV + + git clone https://github.com/rsksmart/devportal.git + cd devportal + git checkout -b ${BRANCH_NAME} || git checkout ${BRANCH_NAME} + cd .. + + # Step 2: Transform Each File and Copy to Devportal Repository + - name: Transform Files for Devportal + run: | + mkdir -p transformed + + # Remove the unwanted first lines from README.md + TEMP_FILE="temp_README.md" + tail -n +1 README.md > ${TEMP_FILE} + # Remove the unwanted lines between START and END comments + sed '//,//d' README.md > ${TEMP_FILE} + # Process main README.md + TRANSFORMED_FILE="transformed/README.md" + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Overview" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 100" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay - Overview" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Overview." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integrate, integration guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + echo ":::info[Note]" >> ${TRANSFORMED_FILE} + echo "If you wish to suggest changes on this document, please open a PR on the [Rif Relay Repository](https://github.com/rsksmart/rif-relay.git)" >> ${TRANSFORMED_FILE} + echo ":::" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/overview.md + + # Process integrations section + TEMP_FILE="temp_integrate.md" + TRANSFORMED_FILE="transformed/integrate.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/integrate.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Integrations" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 200" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Integration" >> ${TRANSFORMED_FILE} + echo "description: Integrating RIF Relay in a dApp." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integration guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/integrate.md + + # Process setup section + TEMP_FILE="temp_installation-requirements.md" + TRANSFORMED_FILE="transformed/installation-requirements.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/installation-requirements.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Setup" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 300" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Installation Requirements" >> ${TRANSFORMED_FILE} + echo "description: Requirements for installing RIF Relay." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, user, guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/installation-requirements.md + + # Process sample dapp section + TEMP_FILE="temp_sample-dapp.md" + TRANSFORMED_FILE="transformed/sample-dapp.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/sample-dapp.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: RIF Relay Sample dApp" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 400" >> ${TRANSFORMED_FILE} + echo "title: How to use the RIF Relay Sample dApp SDK" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Sample dApp SDK Starter kit." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integration guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/sample-dapp.md + + # Process deployment section + TEMP_FILE="temp_deployment.md" + TRANSFORMED_FILE="transformed/deployment.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/deployment.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: RIF Relay Deployment" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 500" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Deployment" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay deployment process." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integration guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/deployment.md + + # Process develop section + TEMP_FILE="temp_develop.md" + TRANSFORMED_FILE="transformed/develop.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/develop.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Develop" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 600" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Develop" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay deployment process." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, user, guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/develop.md + + # Process contracts section + TEMP_FILE="temp_contracts.md" + TRANSFORMED_FILE="transformed/contracts.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/contracts.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Contracts" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 700" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay - Contracts" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Contracts." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integrate]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/contracts.md + + # Process smart wallets section + TEMP_FILE="temp_smart-wallets.md" + TRANSFORMED_FILE="transformed/smart-wallets.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/smart-wallets.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Smart Wallets" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 800" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Smart Wallets" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Smart Wallets." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, user, guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/smart-wallets.md + + # Process versions section + TEMP_FILE="temp_versions.md" + TRANSFORMED_FILE="transformed/versions.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/versions.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Versions" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 900" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay Versions" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Versions." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, rif relay, integration guide]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/versions.md + + # Process gas costs section + TEMP_FILE="temp_gas-costs.md" + TRANSFORMED_FILE="transformed/gas-costs.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/gas-costs.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Gas Costs" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 950" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay - Gas Costs" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Gas Costs." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integrate]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/gas-costs.md + + # Process architecture section + TEMP_FILE="temp_architecture.md" + TRANSFORMED_FILE="transformed/architecture.md" + # Remove the unwanted first lines from section (title) + tail -n +2 docs/architecture.md > ${TEMP_FILE} + echo "---" > ${TRANSFORMED_FILE} + echo "sidebar_label: Architecture" >> ${TRANSFORMED_FILE} + echo "sidebar_position: 980" >> ${TRANSFORMED_FILE} + echo "title: RIF Relay - Architecture" >> ${TRANSFORMED_FILE} + echo "description: RIF Relay Architeture." >> ${TRANSFORMED_FILE} + echo "tags: [rif, envelope, relay, integrate]" >> ${TRANSFORMED_FILE} + echo "---" >> ${TRANSFORMED_FILE} + echo "" >> ${TRANSFORMED_FILE} + cat ${TEMP_FILE} >> ${TRANSFORMED_FILE} + # Clean up temporary file + rm ${TEMP_FILE} + cp ${TRANSFORMED_FILE} devportal/docs/02-developers/06-integrate/01-rif-relay/architecture.md + + # Step 3: Commit and Push Changes to Devportal Repository + - name: Commit and Push Changes + env: + GITHUB_TOKEN: ${{ secrets.DEVPORTAL_DOCS_UPDATE_TOKEN }} + run: | + cd devportal + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add docs/02-developers/06-integrate/01-rif-relay/overview.md docs/02-developers/06-integrate/01-rif-relay/integrate.md docs/02-developers/06-integrate/01-rif-relay/installation-requirements.md docs/02-developers/06-integrate/01-rif-relay/sample-dapp.md docs/02-developers/06-integrate/01-rif-relay/deployment.md docs/02-developers/06-integrate/01-rif-relay/develop.md docs/02-developers/06-integrate/01-rif-relay/contracts.md docs/02-developers/06-integrate/01-rif-relay/smart-wallets.md docs/02-developers/06-integrate/01-rif-relay/versions.md docs/02-developers/06-integrate/01-rif-relay/gas-costs.md docs/02-developers/06-integrate/01-rif-relay/architecture.md + git commit -m "Automated update from repository" + # Configure the remote URL with the token for authentication + git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/rsksmart/devportal.git + git push -f origin ${BRANCH_NAME} + + # Step 4: Create a Pull Request in the Devportal Repository + - name: Create Pull Request + env: + GITHUB_TOKEN: ${{ secrets.DEVPORTAL_DOCS_UPDATE_TOKEN }} + run: | + cd devportal + curl -L -X POST -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.DEVPORTAL_DOCS_UPDATE_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/rsksmart/devportal/pulls \ + -d "{\"title\":\"Rif-relay automated update of documentation ${BRANCH_NAME}\",\"body\":\"This PR updates the Devportal documentation with the latest changes from the original repository.\",\"head\":\"${BRANCH_NAME}\",\"base\":\"main\"}" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..d392ac56 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# RIF Relay +Most blockchains have native cryptocurrency to pay for transaction fees and gas consumption; this simple design has many benefits. First, to bootstrap an economy, the native cryptocurrency model creates an initial demand for it. Second, it simplifies the interaction between users and miners because it forces them to use the same means of payment. Third, it reduces the complexity of the consensus rules. Finally, it provides Denial of Service (DoS) protection to the network as full nodes can pay what the miners expect to include a received transaction. This way nodes can decide to propagate a transaction or not, preventing the free consumption of network bandwidth, and stop spam transactions. + +Cryptocurrencies tend to be associated with volatility and to counter measure this fact, Stablecoins were introduced. Stablecoins bridge the worlds of cryptocurrency and everyday fiat currency because their prices are pegged to a reserve asset like the U.S. dollar or gold. + +But with the advent of Decentralized Finance (DeFi), several stable coins have become a preferred means of payment and savings for both users and miners, therefore, separate systems to facilitate alternative payment mechanisms. Transactions that enable paying transactions with any coin other than the native currency are named meta-transactions because in some systems the user transaction is embedded in a higher-level (or meta) transaction created by a third party. A more accessible term for these transactions is “envelopes” or, for the whole system, a relay system. A meta-transaction/relay system can serve at least two different use cases: 1) pay the transaction fees with tokens, where one new party receives the tokens (from the user) and pays the fees on behalf of the user, and 2) enable smart contract developers to subsidize the gas used to interact with their contracts. + +With this in mind, the main goal of the RIF Relay Project is to **provide the Rootstock (RSK) ecosystem with the means to allow blockchain applications and end-users (wallet-apps) to transact without needing RBTC**. The system should allow Rootstock (RSK) users to pay transaction fees with methods of payment (i.e., tokens) other than RBTC while maintaining their accounts as transaction senders. + +RIF Relay takes its inspiration from the [Gas Station Network (GSN) project](https://github.com/opengsn/gsn). GSN is a decentralized system that improves dApp usability without sacrificing security. In a nutshell, GSN abstracts away gas (used to pay transaction fees) to minimize onboarding and UX friction for dApps. With GSN, "gasless clients" can interact with smart contracts paying for gas with tokens instead of native-currency. + + + +## Index +The project information is divided into different sections, which you can explore through the following links: + +- [RIF Relay Integration](./docs/integrate.md) +- [RIF Relay Installation Requirements](./docs/installation-requirements.md) +- [How to use the RIF Relay Sample dApp SDK](./docs/sample-dapp.md) +- [RIF Relay Deployment](./docs/deployment.md) +- [RIF Relay Develop](./docs/develop.md) +- [RIF Relay - Contracts](./docs/contracts.md) +- [RIF Relay Smart Wallets](./docs/smart-wallets.md) +- [RIF Relay Versions](./docs/versions.md) +- [RIF Relay - Gas Costs](./docs/gas-costs.md) +- [RIF Relay - Architecture](./docs/architecture.md) + + + +## Modules + +RIF Relay is built in modules, the entire system is made up by 3 modules. + +1. [RIF Relay Contracts](https://github.com/rsksmart/rif-relay-contracts) contains all the contracts used by the RIF Relay System. +2. [RIF Relay Client](https://github.com/rsksmart/rif-relay-client) contains a library to interact with the relay server. +3. [RIF Relay Server](https://github.com/rsksmart/rif-relay-server) has all the relay server code. You can run the server directly from there. + +Each module has instructions for development and usage. + +[Deprecated Docs](docs/README.md) + + +## Contribution Guidelines +* Please refer to the Rootstock Contribution Guidelines for more information on how to contribute to this project. + +## License: +MIT License - Copyright (c) 2023 Rootstock \ No newline at end of file diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 546bf710..00000000 --- a/Readme.md +++ /dev/null @@ -1,54 +0,0 @@ -# RIF Relay - -A secure transaction relay system to enable users to pay fees using ERC-20 tokens. - -## Description - -RIF Relay takes its inspiration from the [Gas Station Network (GSN) project](https://github.com/opengsn/gsn). GSN is a decentralized system that improves dApp usability without sacrificing security. In a nutshell, GSN abstracts away gas (used to pay transaction fees) to minimize onboarding and UX friction for dApps. With GSN, “gasless clients” can interact with smart contracts paying for gas with tokens instead of native-currency. - -Our main objective is to provide the RSK ecosystem with the means to enable blockchain applications and end-users (wallet-apps) to pay for transaction fees using tokens (e.g. RIF tokens), and thereby remove the need to acquire RBTC in advance. - -It is important to recall that - as a security measure - the version 1 contracts deployed on Mainnet have limits on the staked amounts to operate, these limits were removed in version 2. - -## Modules - -RIF Relay is built in modules, the entire system is made up by 3 modules. - -1. [RIF Relay Contracts](https://github.com/rsksmart/rif-relay-contracts) contains all the contracts used by the RIF Relay System. -2. [RIF Relay Client](https://github.com/rsksmart/rif-relay-client) contains a library to interact with the relay server. -3. [RIF Relay Server](https://github.com/rsksmart/rif-relay-server) has all the relay server code. You can run the server directly from there. - -Each module has instructions for development and usage. - -## Getting Started with the RIF Relay Sample dApp SDK - -We've created a sample dApp to showcase how users can submit relayed transactions to the Rootstock blockchain using the RIF Relay Sample dApp SDK. For details, see [RIF Relaying Services SDK sample dApp](https://github.com/rsksmart/rif-relay-sample-dapp). - -## Testing - -This repository contains all the integration tests. These tests verify the behavior of the entire system. -You have two ways to run tests: - -1. Executing `npm test` will run all the test suite and verify all the system. This could take - a few hours since executing the entire test suite is a heavy task. -2. Running `npm run testOnly ` where `` it’s the typescript file -that contains the test code inside will execute only that test and make the verifications inside it. An example could be `npm run testOnly ./test/relayserver/RelayServer.test.ts`. - -**Important Note**: when you run the tests you will see folders like `contracts`, `migrations` and some other files -appearing during the tests and disappearing after, that’s because we need to have the contracts -on the same context as this repository during tests, this is a normal behavior. - -## Scripts - -This repository contains a script that analyzes gas consumption for relay and deploy transactions. It prints different metrics related to gas usage when relaying a transaction or deploying a smart wallet. -To run it, execute the command: - -`npm run analyze:gas ` - -where: -- `` is a required parameter for the network name, taken from the `hardhat.config.ts`, and must correspond to a valid RSK Node (commonly, regtest is used). Do not use this with the default network (hardhat) as it will fail. - -Example: -`npm run analyze:gas regtest` - -[Deprecated Doc](docs/README.md) diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..6ce4a1a0 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,246 @@ +# RIF Relay - Architecture + +The RIF Relay system is designed to achieve transaction sponsorship at a low cost. The cost of the relay service provided by the “sponsors” is agreed upon among the parties off-chain. The low cost of transactions on Rootstock (RSK) contributes to keeping overall service costs low as well. + +The RIF Relay system is made up of various components, some of which are essential and others which are auxiliary. + +An overview of this is as follows: + +**On-chain**, the system cannot work without its Smart Contracts, which encompass Smart Wallets plus the Relay Hub and Verifiers. + +**Off-chain**, at least one Relay Server is needed to interact with the contracts. Without a Relay Server, envelopes cannot be created and sent to the contracts. + +Details for each of these components are expanded down below, as well as an introductory glossary. + +### Glossary + +| Term | Description | +|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Sponsor | A third party that pays the gas consumed by a sponsored transaction (see below) by submitting it to the blockchain. | +| Sponsored Transaction | A transaction sent by the requester (see below) through the Sponsor, this type of transaction aims to separate the gas payer from the sender of the transaction. | +| Requester | It’s an EOA (see below). The requester sends a sponsored transaction to the Sponsor. They do not pay the gas with native cryptocurrency but with an accepted token by the Sponsor, if they don’t subsidize it. | +| Recipient | An abbreviation for recipient contract. It’s the destination of the requester’s transaction.| +| Envelope | Using the “envelopes” analogy, it’s the transaction, (funded with native cryptocurrency as gas) sent by the Sponsor to the blockchain, that wraps the requester’s transaction payload (sponsored transaction). | +| RIF Relay | The entire system which allows the relay of sponsored transactions. | +| DoS | A Denial of Service is an information-security threat whose goal is to become a service unavailable. | +| DeFi | An acronym for Decentralized Finance, it’s a novel form for finance based in blockchain technology. | +| EOA | An Externally Owned Account (EOA) is an account managed with a key, which is capable of signing and sending transactions, and paying the cost for it. | +| Fee | Token amount that is being charged for each relayed transaction. | +| Revenue Sharing Model | A way to relay transactions so that fees are shared among multiple partners. | +| Fees Receiver | Is the designated Worker/Collector that will receive the fees | + + +## On-Chain components + +### Relay Hub +The Relay Hub is the main component of the RIF Relay architecture. It acts as an interface with the Relay Server and the whole on-chain architecture. It forwards all the transactions to their respective contracts while checking the validity of the worker that is processing the transaction. + +It also forms part of the Relay Workers registration process together with the Relay Managers. Furthermore, the Relay Hub keeps the stake amount for each Relay Manager to guarantee good behavior from their workers. +The account staking for a specific Relay Manager for the first time becomes the owner of the stake, only this account can make subsequent stakes for this specific RelayManager. + +When a Relay Manager unauthorized a Relay Hub, it means it is unstaking from it, which also means not being able to relay through that hub any more. Any balance held in the Relay Hub is sent to the original sender of the stake (the owner). + +Unstaking has a predefined delay (in blocks). This is intended to prevent the Relay Manager from unstaking before a slashing that was going to occur. + +### Smart Wallet +It’s the “contract-based account” owned by the Requester’s EOA. Before executing any transaction using the smart wallet, the smart wallet contract needs to be deployed. + +Smart Wallet are contracts that verify forwarded data and subsequently invoke the recipient contract of the transaction. Creating smart wallets does not have any gas cost providing the advantage that can be deployed only when necessary. + +It is the component that calls the Recipient contract (i.e, the `msg.sender` address the Recipient will see). During the execution, the contract verifies the Relay Request and, if it’s valid, it calls the defined Recipient’s function, otherwise it reverts the invocation. The verification includes checking that the owner of the SmartWallet made the request, rejecting any request with an invalid signature, and preventing replay attacks using a nonce. + +The `smart wallet` was designed to only interact with the RIF Relay system, therefore any native currency balance will be transferred back to the owner of `smart wallet` after each transaction. + +### Native Holder Smart Wallet + +The `native holder smart wallet` is a `smart wallet` that was designed to have interactions outside the RIF Relay system. This means that it can hold native currency as it's name describes. + +The behavior of the `native holder smart wallet` is the same as the `smart wallet` with the difference that the native currency will not be transferred back to the owner after each transaction and can dispose the usage of the native currency. + +### Custom Smart Wallet + +The `custom smart wallet` is a `smart wallet` that was designed to execute custom logic after each transaction. The custom logic is created at the moment of the contract deployment and can be executed on each transaction. + +### Relay Manager +An EOA that has a staked balance. Any penalization done against a Relay Worker impacts the Relay Manager’s stake. A Relay Worker can be managed by only one Relay Manager. A Relay Manager can have one or more Relay Workers. The responsibilities of the Relay Manager are: registering the Relay Server and adding Relay Workers, both in the Relay Hub. + +### Stake Manager +The Stake Manager supports multiple Relay Hubs, the stakers are the Relay Managers and they can authorize/de-authorize specific Relay Hubs so they can penalize the managers if needed. The staked cryptocurrency is held in the StakeManager contract. + +The account staking for a specific Relay Manager for the first time becomes the owner of the stake, only this account can make subsequent stakes for this specific RelayManager. + +When a Relay Manager unauthorised a Relay Hub, it means it is unstaking from it, which also means not being able to relay through that hub any more. Any balance held in the Relay Hub is sent to the original sender of the stake (the owner). Also, the workers’ balances are transferred to the stake owner, and, if configured, the Relay Manager’s balance can also be transferred to the stake owner. + +Unstaking has a predefined delay (in blocks). This is intended to prevent the Relay Manager from unstaking before a slashing that was going to occur. + +### Relay Worker +An EOA that belongs to only one Relay Manager. Since the Relay Worker is the sender of the request, it is the one that pays for the gas fees for each transaction. It **may** also collect the fees in ERC20 that are charged for relaying the transactions. + +### Relay & Deploy Verifier +Contracts that authorize a specific relay or deploy request (see the [Relay & Deploy Requests](#relay--deploy-requests) section). + +Two example implementations are provided: + - **Relay Verifier**: The Relay Verifier has a list of tokens that it accepts. When it receives a relay request, it checks the token’s acceptance and the payer’s balance for the token. + - **Deploy Verifier**: An implementation used in the SmartWallet deployment process. It performs the same relay verifier checks but also makes sure that the SmartWallet to be deployed doesn’t already exist. It also checks that a Proxy Factory address is provided in the Relay Request. + +### Collector + +The Collector is an optional smart contract used for the Revenue Sharing feature. Normally, relay fees are paid to the worker account which relays the transaction. + +Collector contracts are designed to hold revenue generated from relayed transactions so that in the future they can be later given out to partners according to the distribution of shares written in the contract. They are initialized with a specific token to hold, a set of partner addresses (each set with their own share of collected revenues) plus an owner which can modify the shares or execute the withdrawal and distribution of funds. Shares for each partner are expressed in integers representing a percentage and must add up to exactly 100. Any number of partners can be specified. + +The owner of the contract can be any address, including but not limited to a multisig contract (see [Gnosis Safe Contracts](https://github.com/gnosis/safe-contracts)). Using a multisig address can be a good idea if ownership of the contract needs to be shared, so that decisions like distributing collected fees to partners or modifying revenue shares can be taken collectively. An ownership transfer function is also available. + +Any number of Collector contracts can be deployed and used to share revenue, as long as their addresses are specified in relay requests. The withdrawal of funds from any Collector contract is completely independent of the RIF Relay flow and can be executed at any arbitrary point in time. + +For steps on how to deploy a Collector contract (plus other technical details) please see [the Collector section](/developers/integrate/rif-relay/deployment) of the deployment process. + +### Proxies + +#### Template +It's the logic that would be executed on each transaction. In this specific scenario, it is the Smart Wallet contract. + +#### Proxy Factory +Factory of Proxies to the SmartWallet. The proxy factory is in charge of deploying the smart wallets contracts using the template, during the deployment it executes the initialization from each smart wallet. + +#### Proxy +The proxy is only implemented in the Custom Smart Wallet because it delegates every call to a SmartWallet logic address. This proxy is the one instantiated per SmartWallet, and it will receive the SmartWallet address as Master Copy (MC). So every call made to this proxy will end up executing the logic defined in the MC. + +For the transaction execution (`execute()` call), MC logic will do the signature verification and payment. Then it will execute the request, and, if custom logic was defined, it will forward the flow to it before returning. + +During the initialization of the Custom Smart Wallet a custom logic can be set (which would impact the proxy’s state of course), the initialization process and set of the custom logic can only be done during the deployment of the smart wallet. + + +### GSNEip712Library +This is an auxiliary library that bridges the Relay Request into a call of a Smart Wallet or Proxy Factory (in such case, the Request is a Deploy Request). + +Detailed documentation can be found [here](https://eips.ethereum.org/EIPS/eip-712). + +## Off-chain components + +### Relay Server +The Relay Server receives sponsored transactions via HTTP. + +The server has only one Relay Manager address and at least one Relay Worker, and points to just one Relay Hub. +When the Relay Server receives an HTTP Relay request, it creates an Envelope, wrapping the sponsored transaction, signs it using its Relay Worker account and then sends it to the Relay Hub contract. + +The server is a service daemon, running as an HTTP service. It advertises itself (through the Relay Hub) and waits for client requests. + +The Relay Server has mechanisms that try to avoid running out of balance in the workers. The Relay Manager keeps sending native cryptocurrency to the workers based on a specific minimum balance. + +#### Start Flow + +The start flow diagram represents the process that is followed by the Relay Server to start receiving requests, even that the server will be receiving requests doesn't mean that can handle it, since it needs balance to process each request. +![Relay - Start Flow](/img/rif-relay/start.jpg) + +1. Generates(private keys) the Workers and Manager accounts. +2. Initialise the instance for each contract that will be interacting with the server. + - The RelayHub contract is the key contract for the start flow since its the contract that have the events of interest. +3. Initalise the Relay Server. + -The Relay Server has all logic for the interaction between off-chain and on-chain components. +4. Initialise the RegistationManager. + - The Registration Manager starts querying for events related to the registration process(StakeAdded, WorkerAdded) to identify if can register the Server on the RelayHub. +5. The Relay Server start querying for changes on the blochain using the RelayHub. + +#### Register Flow + +The register flow diagram represents the process to provide the necessary stake/balance to the manager/workers for the Relay Server start processing requests and to register the server in the RelayHub. + +![Relay - Register Flow](/img/rif-relay/register.jpg) + +1. Gets the Relay Server data. +2. Validate if the server was already register in the RelayHub. +3. Initialise the instance for each contract that will be interacting with the server. + - The RelayHub contract is the key contract for the register flow since its the contract that have the events of interest. +4. Query the stakeInfo for the manager and validates if already staked. +5. Funds the manager if necessary. + +### Interval Handler + +The interval handler diagram represents the process from the Relay Server to interact with the blockchain and process the transactions. + +![Relay - Interval Handler Flow](/img/rif-relay/interval-handler.jpg) + +1. Get the latest mined block by the blockachain. +2. Check if the Relay Server state needs to be refreshed based on the blocks minted. +3. Refresh the gas price. +4. Get the past events from the RelayHub. +5. Add the workers and register the Relay Server if meets the requirements. +6. Keep listening for transactions and new events. + +### Relay & Deploy Requests +A relay request is the sponsored transaction, the structure used to relay a transaction. It is formed by Relay Data and Forward Request: + +- **Relay Data**: All information required to relay the defined Forward Request. +- **Forward/Deploy Request**: It is formed by all the “common” transaction fields in addition to all the token-payment data. + +When the Sponsor creates an Envelope (the actual blockchain transaction to submit), it will add this Relay Request (sponsored transaction) as part of the encoded data, along with the contract and method to call (RelayHub and relayCall respectively) + +The **Relay request** is structure that wraps the transaction sent by an end-user. It includes data required for relaying the trasaction e.g. address of the payer, address of the original requester, token payment data. + +The **Deploy request** structure that wraps the transaction sent to deploy a Smart wallet. + +### Tools + +### Relay Client +This is a typescript library to interact with the RIF Relay system. It provides APIs to find a relay, and to send transactions through it. It also exposes methods to interact with the blockchain. + +It can work as an access point to the Relay system. It creates, signs, and sends the Sponsored transaction, which is signed by the requester and forwarded to the Relay Server via the HTTP protocol. + +It is not _strictly_ needed since any dApp or user could relay transactions using merely a Relay Server and the smart contracts, although this is arguably harder to do manually. + +### Relay Provider +It's the access point to the RIF Relay system. It wraps the `Relay Client` to provider Ethers.js compatibility. + +## Execution flow + +### Relaying (Smart Wallet already deployed) + +![Relay - Execution Flow](/img/rif-relay/execution.jpg) + +1. A Requester creates a request. +2. A Requester sends the request to the Relay Client (through a Relay Provider). +3. The Relay Client wraps the request into a Relay Request and signs it. +4. The Relay Client sends the Relay Request to the Relay Server (via HTTP Client ↔ HTTP Server). +5. The Relay Server create a transaction including the Relay Request and signs it with a Relay Worker account. +6. The Relay Worker account is an EOA registered in the Relay Hub. +7. The Relay Server sends the transaction to the Relay Hub using the same worker account as the previous step, executing the `relayCall` function of the Relay Hub contract. + - When the Relay Hub receives a transaction from a Relay Worker, it verifies with the Stake Manager that the Worker’s Relay Manager has indeed locked funds for staking. If not, the execution is reverted. + - The Relay Worker account must have funds to pay for the consumed gas (RBTC). + - This verification is done in the Relay Client and in the Relay Server as well, by calling the Relay Verifier. The verifier checks that it accepts the token used to pay and that the payer has a sufficient token balance. In addition, it verifies that the used smart wallet is the correct one. +8. The RelayHub instructs the Smart Wallet to execute the Relay Request through the [GsnEip712Library](#gsneip712library) library. +9. The Smart Wallet checks the signature and the nonce of the Requester, reverting if it fails the checks. +10. Then, the Smart Wallet performs the token transfer between the Requester and the token recipient, using the data received within the Relay Request. +11. It invokes the recipient contract with the indicated method in the Forward Request. + +### Sponsored Smart Wallet deployment + +![Relay - Sponsored Smart Wallet](/img/rif-relay/relay.jpg) + +The gas-less requester has a SmartWallet address where they receive tokens but don't use them. If the requester needs to call a contract, e.g., to send the tokens to another account, they must deploy a Smart Wallet first. + +1. A Requester creates a deploy wallet request. +2. A Requester sends the request to the Relay Server through the Relay Client. +3. The Relay Client wraps the transaction sent by the Requester in a Deploy Request to create the Smart Wallet and signs it. +4. The Relay Client sends to the Relay Server a Deploy Request (via HTTP Client ↔ HTTP Server). +5. The Relay Server signs the transaction containing the Deploy Request, with the Relay Worker account. +6. The Relay Server sends the request to the Relay Hub using the Relay Worker account executing the `relayCall` function of the Relay Hub contract. + - Here's where the Relay Server will typically call the Deploy Verifier to ensure: + - The Verifier accepts the offered tokens. + - The Proxy Factory instance to use is known by the verifier. + - The Proxy Factory contract isn’t creating an existing Smart Wallet. + - The requester has enough tokens to pay. +7. The Relay Hub calls the Proxy Factory using the method `relayedUserSmartWalletCreation`. +8. The Proxy Factory performs the following checks: + - Checks the sender's nonce. + - Checks the Deploy Request signature. +9. The Proxy Factory creates the Smart Wallet using the `create2` opcode. +10. Then it calls the `initialize` function in the Smart Wallet contract. + - The Smart Wallet, during its initialization, executes the token transfer. + - Then it initializes the Smart Wallet state and sets the requester’s EOA as the owner of the Smart Wallet. + - In the case there is a custom logic, its initialization is called as well. + +## Deprecated + +### Paymaster +V0.2 deprecated the Paymaster contracts in favor of the Verifiers (see [versions](/developers/integrate/rif-relay/versions/)). \ No newline at end of file diff --git a/docs/contracts.md b/docs/contracts.md new file mode 100644 index 00000000..6f7d6de3 --- /dev/null +++ b/docs/contracts.md @@ -0,0 +1,106 @@ +# RIF Relay - Contracts + +## Mainnet + +### Version 1 + + +#### Primary contracts** + + | Contract | Address | + |--------------------|--------------------------------------------| + | Penalizer | 0x4fd591b8330d352c57CA1CC1dA172dCa516722E3 | + | RelayHub | 0x438Ce7f1FEC910588Be0fa0fAcD27D82De1DE0bC | + | SmartWallet | 0x59C40304E8a428BF1D17f03a6aE84B635964DB19 | + | SmartWalletFactory | 0x9EEbEC6C5157bEE13b451b1dfE1eE2cB40846323 | + | DeployVerifier | 0x2FD633E358bc50Ccf6bf926D621E8612B55264C9 | + | RelayVerifier | 0x5C9c7d96E6C59E55dA4dCf7F791AE58dAF8DBc86 | + +#### For CustomSmartWallet support + + | Contract | Address | + |---------------------------------|--------------------------------------------| + | CustomSmartWallet | 0x4b2464E8d062633D18ba0928c064037Da415eD1f | + | CustomSmartWalletFactory | 0x0002E79883280C1717e41EE5D3705D55960B5bAe | + | CustomSmartWalletDeployVerifier | 0x5910868059431026ACa58a73124DedbEF4cb97db | + | CustomSmartWalletRelayVerifier | 0xb6eFDB335b4D52705e9973069500fd79410BEC01 | + +#### For Testing purposes + + | Contract | Address | + |-------------------|--------------------------------------------| + | SampleRecipient | 0x479eA66AAEfC00EdC1590c9da07152def9452cf9 | + | TestToken | 0xe49b8906A3ceFd184621A4193e2451b1c3C3dB0B | + +## Testnet + +### Version 1 + +#### Primary contracts + + | Contract | Address | + |--------------------|--------------------------------------------| + | Penalizer | 0x8e67406bD3A926b43Fda158C673230B77f874CDd | + | RelayHub | 0xAd525463961399793f8716b0D85133ff7503a7C2 | + | SmartWallet | 0x86bD3006B757614D17786428ADf3B442b2722f59 | + | SmartWalletFactory | 0xCBc3BC24da96Ef5606d3801E13E1DC6E98C5c877 | + | DeployVerifier | 0xc67f193Bb1D64F13FD49E2da6586a2F417e56b16 | + | RelayVerifier | 0xB86c972Ff212838C4c396199B27a0DBe45560df8 | + +#### For CustomSmartWallet support + + | Contract | Address | + |---------------------------------|--------------------------------------------| + | CustomSmartWallet | 0x2c66922D704999Ff9F378838172fe5c5e0Ac2d27 | + | CustomSmartWalletFactory | 0x91C186Dcb11EcBf234c778D7779e8e10f8ADD1a8 | + | CustomSmartWalletDeployVerifier | 0x87421afb27FC680D99E82Bce8Df140E81F5c11a3 | + | CustomSmartWalletRelayVerifier | 0x6e23B72723886b066a5C26Baa2b2AfB0b1d51e5c | + +#### For Testing purposes + + | Contract | Address | + |-------------------|--------------------------------------------| + | SampleRecipient | 0xc4B8B6C02EC34d84630Ba8C684954a0A04C656FC | + | TestToken | 0x3F49BaB0afdC36E9f5784da91b32E3D5156fAa5C | + +### Version 0.2 + +#### Primary contracts + + | Contract | Address | + |--------------------|--------------------------------------------| + | Penalizer | 0x5FdeE07Fa5Fed81bd82e3C067e322B44589362d9 | + | RelayHub | 0xe90592939fE8bb6017A8a533264a5894B41aF7d5 | + | SmartWallet | 0x27646c85F9Ad255989797DB0d99bC4a9DF2EdA68 | + | SmartWalletFactory | 0xEbb8AA43CA09fD39FC712eb57F47A9534F251996 | + | DeployVerifier | 0x345799D90aF318fd2d8CbA87cAD4894feF2f3518 | + | RelayVerifier | 0xDe988dB9a901C29A9f04050eB7ab08f71868a8fc | + +#### For CustomSmartWallet support + + | Contract | Address | + |---------------------------------|--------------------------------------------| + | CustomSmartWallet | 0xB8dB52615B1a94a03C2251fD417cA4d945484530 | + | CustomSmartWalletFactory | 0xA756bD95D8647be254de40B842297c945D8bB9a5 | + | CustomSmartWalletDeployVerifier | 0x3c26685CE3ac89F755D68A81175655b4bBE54AE0 | + | CustomSmartWalletRelayVerifier | 0xBcCA9B8faA9cee911849bFF83B869d230f83f945 | + +### For Testing purposes + + | Contract | Address | + |-------------------|--------------------------------------------| + | SampleRecipient | 0x4De3eB249409e8E40a99e3264a379BCfa10634F5 | + | TestToken | 0x77740cE4d7897430E74D5E06540A9Eac2C2Dee70 | + +#### Version 0.1 + + | Contract | Address | + |----------------|--------------------------------------------| + | StakeManager | 0x4aD91a4315b3C060F60B69Fd0d1eBaf16c14148D | + | Penalizer | 0xd3021763366708d5FD07bD3A7Cd04F94Fc5e1726 | + | RelayHub | 0x3f8e67A0aCc07ff2F4f46dcF173C652765a9CA6C | + | TestRecipient | 0xFBE5bF13F7533F00dF301e752b41c96965c10Bfa | + | SmartWallet | 0xE7552f1FF31670aa36b08c17e3F1F582Af6302d1 | + | ProxyFactory | 0xb7a5370F126d51138d60e20E3F332c81f1507Ce2 | + | DeployVerifier | 0x3AD4EDEc75570c3B03620f84d37EF7F9021665bC | + | RelayVerifier | 0x053b4a77e9d5895920cBF505eB8108F99d929395 | diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 00000000..9b932090 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,341 @@ +# RIF Relay Deployment + +## Set Up RIF Relay Contracts and Server + +### Deploy Contracts + +Start by deploying on-chain components. All tools needed are in the [RIF Relay Contract repository](https://github.com/rsksmart/rif-relay-contracts) + +#### Regtest + +1. Clone the Repository: + ```bash + git clone https://github.com/rsksmart/rif-relay-contracts + ``` +2. Navigate to the directory and install dependencies: + ```bash + cd rif-relay-contracts + npm install + ``` +3. Deploy the contract: + ```bash + npx hardhat deploy --network regtest + ``` + +> This uses the Regtest configuration from `hardhat.config.ts`. + +After deployment, you'll see a summary of the deployed contracts. This summary includes the on-chain components essential for RIF Relay, and additional contracts for testing and validation purposes. + ```text + ┌───────────────────────────────────────┬──────────────────────────────────────────────┐ + │ (index) │ Values │ + ├───────────────────────────────────────┼──────────────────────────────────────────────┤ + │ Penalizer │ '0x77045E71a7A2c50903d88e564cD72fab11e82051' │ + │ RelayHub │ '0xDA7Ce79725418F4F6E13Bf5F520C89Cec5f6A974' │ + │ SmartWallet │ '0x83C5541A6c8D2dBAD642f385d8d06Ca9B6C731ee' │ + │ SmartWalletFactory │ '0xE0825f57Dd05Ef62FF731c27222A86E104CC4Cad' │ + │ DeployVerifier │ '0x73ec81da0C72DD112e06c09A6ec03B5544d26F05' │ + │ RelayVerifier │ '0x03F23ae1917722d5A27a2Ea0Bcc98725a2a2a49a' │ + │ CustomSmartWallet │ '0x1eD614cd3443EFd9c70F04b6d777aed947A4b0c4' │ + │ CustomSmartWalletFactory │ '0x5159345aaB821172e795d56274D0f5FDFdC6aBD9' │ + │ CustomSmartWalletDeployVerifier │ '0x7557fcE0BbFAe81a9508FF469D481f2c72a8B5f3' │ + │ CustomSmartWalletRelayVerifier │ '0x0e19674ebc2c2B6Df3e7a1417c49b50235c61924' │ + │ NativeHolderSmartWallet │ '0x4aC9422c7720eF71Cb219B006aB363Ab54BB4183' │ + │ NativeHolderSmartWalletFactory │ '0xBaDb31cAf5B95edd785446B76219b60fB1f07233' │ + │ NativeHolderSmartWalletDeployVerifier │ '0xAe59e767768c6c25d64619Ee1c498Fd7D83e3c24' │ + │ NativeHolderSmartWalletRelayVerifier │ '0x5897E84216220663F306676458Afc7bf2A6A3C52' │ + │ UtilToken │ '0x1Af2844A588759D0DE58abD568ADD96BB8B3B6D8' │ + │ VersionRegistry │ '0x8901a2Bbf639bFD21A97004BA4D7aE2BD00B8DA8' │ + └───────────────────────────────────────┴──────────────────────────────────────────────┘ + ``` +The deployment summary shows two sets of Smart Wallets, each paired with its verifiers. This is because the verifier is used for both deployment and transaction validation. For testing purposes, the focus will be on using these Smart Wallet Contracts. + +#### Testnet +1. Ensure your account is funded. You can get funds from the [tRBTC Faucet](https://faucet.rootstock.io/). Additional faucet options include; [Thirdweb](https://thirdweb.com/rootstock-testnet) and [Blast](https://blastapi.io/faucets/rootstock-testnet) Faucets. +2. Deploy on Testnet: + ```bash + npx hardhat deploy --network testnet + ``` +> Remember to configure Testnet in `hardhat.config.ts`. Existing RIF Relay contracts deployed on Testnet can be found in the [contracts section](/developers/integrate/rif-relay/contracts). + +#### Mainnet + +1. Ensure your account is funded. +2. Deploy on Mainnet: + ```bash + npx hardhat deploy --network mainnet + ``` +> Ensure Mainnet is set up in `hardhat.config.ts`. Existing RIF Relay contracts deployed on Mainnet can be found in the [contracts section](/developers/integrate/rif-relay/contracts). + +### Revenue Sharing + +Revenue Sharing is an optional feature in RIF Relay that can be implemented using collector contracts. You can deploy multiple Collector contracts, but they are not included in the default Relay contract deployment. For detailed information on Collector contracts, refer to the [architecture documentation](/developers/integrate/rif-relay/architecture#collector). + +Before deploying a Collector contract ensure the following: +1. Ensure the chosen token for the Collector contract is the same as the one used for transaction fees. + > **Note:** You cannot retrieve any other tokens other than the one set during Collector deployment. +2. Select an appropriate owner for the Collector contract. This owner doesn't have to be the deployer but must have the authority to execute the withdraw function, or else the revenue funds will be locked in the contract. +3. Set up partners and their share percentages, ensuring the total adds up to 100%. Incorrectly sent tokens to an inaccessible address without a private key from the beneficiary will be lost. For an example of a structurally valid revenue shares definition see [sample configuration](https://github.com/rsksmart/rif-relay-contracts/blob/master/deploy-collector.input.sample.json). + + +#### Regtest + +To deploy the Collector contract, we'll use the [RIF Relay Contract](https://github.com/rsksmart/). + +1. Create a configuration file named `deploy-collector.input.json` with the required structure: + ```json + { + "collectorOwner": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + "partners": [ + { + "beneficiary": "0x7986b3DF570230288501EEa3D890bd66948C9B79", + "share": 20 + }, + { + "beneficiary": "0x0a3aA774752ec2042c46548456c094A76C7F3a79", + "share": 35 + }, + { + "beneficiary": "0xCF7CDBbB5F7BA79d3ffe74A0bBA13FC0295F6036", + "share": 13 + }, + { + "beneficiary": "0x39B12C05E8503356E3a7DF0B7B33efA4c054C409", + "share": 32 + } + ], + "tokenAddresses": ["0x1Af2844A588759D0DE58abD568ADD96BB8B3B6D8"], + "remainderAddress": "0xc354D97642FAa06781b76Ffb6786f72cd7746C97" + } + ``` + +> **Note:** The `collectorOwner`, `beneficiaries`, and `remainderAddress` are the first five accounts provided by the node in Regtest. + +2. Deploy the contract: + ```bash + npx hardhat collector:deploy --network regtest + ``` + +The collector is ready and can start receiving fees. + +#### Testnet + +Using the configuration file you created in the regtest section, run this command to deploy the contract: + ```js + npx hardhat collector:deploy --network testnet + ``` +#### Mainnet + +Using the configuration file you created in the regtest section, run this command to deploy the contract: +```js + npx hardhat collector:deploy --network mainnet +``` + +### Allow Tokens + +RIF Relay only accepts whitelisted tokens, primarily to ensure only tokens of value to the operator are accepted. To whitelist a token: +Execute the `acceptToken(address token)` function on the Relay Verifiers contracts, which include: +- `SmartWalletDeployVerifier` +- `SmartWalletRelayVerifier` + +:::info[Note] +This action must be performed by the contracts' owner, typically the account that conducted the deployment. +::: + +#### Regtest + +In the RIF Relay Contracts, execute this command: + +```js + npx hardhat allow-tokens --network regtest --token-list +``` + +> `` is a comma-separated list of the token addresses to be allowed on the available verifiers. The `allowTokens` uses the first account (referred to as account[0]) as the owner of the contracts. This is important because only the account owner can allow tokens. + +#### Testnet + +In the RIF Relay Contracts, execute the command: + + ```js + npx hardhat allow-tokens --network testnet --token-list + ``` + +> `` is a comma-separated list of the token addresses to be allowed on the available verifiers. The `allowTokens` script will use the Testnet network configured in the `hardhat.config.ts`, this network will be required to use the account that deployed the contracts. +> You can also modify the allowed tokens for specific verifiers only by using the `--verifier-list` option as follows: + +```js + npx hardhat allow-tokens --network testnet --token-list --verifier-list +``` + +> The ``, `` is a comma-seperated list of verifier addresses to allow the tokens for. + +#### Mainnet + +In the RIF Relay Contracts, execute the command: + +```js + npx hardhat allow-tokens --network mainnet --token-list +``` + +> `` is a comma-separated list of the token addresses to be allowed on the available verifiers. The `allowTokens` script will use the Mainnet network configured in `hardhat.config.ts`, this network will be required to use the account that did the deployment of the contracts. +> You can also modify the allowed tokens for specific verifiers only by using the `--verifier-list` option as follows: + +```js + npx hardhat allow-tokens --network testnet --token-list --verifier-list +``` +> The ``, `` is a comma-seperated list of verifier addresses to allow the tokens for. + +:::info[Note] +The network name; regtest, testnet, or mainnet, is an optional parameter that is taken from the hardhat.config.ts file. The network name you specify must be the same as the one used to deploy the contract. +::: + +### Run the RIF Relay Server + +After setting up on-chain components, the next step is to set up off-chain components, using the [RIF Relay Server](https://github.com/rsksmart/rif-relay-server). +Configuration of the Relay Server is streamlined using the [node-config](https://www.npmjs.com/package/config) package. For detailed advantages of this package, visit their [wiki](https://github.com/node-config/node-config/wiki). + +The TL;DR: In the `config` directory, create a file named `local.json`. +For visual insights into how the Relay Server functions, refer to the diagrams available [here](/developers/integrate/rif-relay/architecture/). + +#### Regtest + +Here's a configuration example for setting up the RSKj node locally with the contracts deployed in Regtest: + +```json +{ + "app": { + "url": "http://127.0.0.1", + "port": 8090, + "devMode": true, + "logLevel": 1, + "workdir": "./enveloping/environment/", + }, + "blockchain": { + "rskNodeUrl": "http://127.0.0.1:4444", + }, + "contracts": { + "relayHubAddress": "0xDA7Ce79725418F4F6E13Bf5F520C89Cec5f6A974", + "relayVerifierAddress": "0x03F23ae1917722d5A27a2Ea0Bcc98725a2a2a49a", + "deployVerifierAddress": "0x73ec81da0C72DD112e06c09A6ec03B5544d26F05" + } +} + ``` +> **Note:** Relay and Deploy verifiers use the contracts from the Smart Wallet section in the summary. + +The meaning of each key can be found in [RIF Relay Server Configuration](https://github.com/rsksmart/rif-relay-server#server-configuration) + +To start the server, run the following command: + +```js + npm run start +``` + +> By default, the server uses the `default.json5` file in the config directory. Depending on the profile in `NODE_ENV`, the values in the `default.json5` file is overriden. + +At this point the server should be running and ready to start processing transactions, however, you still need to register the off-chain components in the Relay Hub. + +To enable the server for transaction processing, you must register the off-chain components in the Relay Hub. This step requires the server to be active. To register the components, in a different terminal window, execute the following command: + +```js + npm run register +``` + +The register process performs the following actions: +- Stakes the Relay Manager +- Adds the Relay Worker +- Registers the Relay Server + +The server is now ready to start processing transactions and a `ready` message is diplayed on the console. For more details on configuration and registration parameters, refer to the [RIF Relay Server documentation](https://github.com/rsksmart/rif-relay-server#overrides). + +#### Testnet + +Here's an example configuration file using the off-chain components deployed on the Rootstock Testnet (https://rpc.testnet.rootstock.io/{YOUR_APIKEY}). + +> **Important:** Due to specific modules enabled in the RSKj nodes, the RIF Relay Server cannot connect to the public nodes. + +```json + { + "app": { + "url": "https://backend.dev.relay.rifcomputing.net", + "port": 8090, + "devMode": true, + "logLevel": 1, + "feePercentage": "0", + "workdir": "/srv/app/environment" + }, + "blockchain": { + "rskNodeUrl": "http://172.17.0.1:4444" + }, + "contracts": { + "relayHubAddress": "0xAd525463961399793f8716b0D85133ff7503a7C2", + "relayVerifierAddress": "0xB86c972Ff212838C4c396199B27a0DBe45560df8", + "deployVerifierAddress": "0xc67f193Bb1D64F13FD49E2da6586a2F417e56b16" + } + } +``` + +> The [contracts](/developers/integrate/rif-relay/contracts/) used in this setup are the primary contracts available on the Rootstock network. These primary contracts, however, do not include support for the `CustomSmartWallet`. + +For details of each configuration key used in setting up the RIF Relay Server, refer to the [RIF Relay Server Configuration](https://github.com/rsksmart/rif-relay-server#server-configuration) documentation. + +To start the server, execute the following command: + +```js + npm run start +``` +> By default, the server uses the `default.json5` file in the config directory. Depending on the profile in `NODE_ENV`, the values in the `default.json5` file is overriden. Therefore you need to setup the `NODE_ENV` environment to `testnet`. + +At this point, the server should be running and ready to start processing transactions; however, you still need to register the off-chain components in the Relay Hub. For the registration process, the Relay Manager and Worker must have funds. + +To get the addresses, this requires the server to be active. In a different terminal window, execute the following command: + +```bash + curl http:///chain-info +``` + +```json +{ + "relayWorkerAddress": "0xabf898bd73b746298462915ca91623f5630f2462", + "relayManagerAddress": "0xa71d65cbe28689e9358407f87e0b4481161c7e57", + "relayHubAddress": "0xe90592939fE8bb6017A8a533264a5894B41aF7d5", + "feesReceiver": "0x52D107bB12d83EbCBFb4A6Ad0ec866Bb69FdB5Db", + "minGasPrice": "6000000000", + "chainId": "31", + "networkId": "31", + "ready": false, + "version": "2.0.1" +} +``` + +1. Send an arbitrary amount of tRBTC, 0.001 tRBTC for example, to the Worker and Manager. +2. Now execute the register command. + +```js + npm run register +``` + +Here's an example of the `register.json5` + +```json + { + "register": { + "stake": "REGISTER_STAKE", + "funds": "REGISTER_FUNDS", + "mnemonic": "REGISTER_MNEMONIC", + "privateKey": "REGISTER_PRIVATE_KEY", + "hub": "REGISTER_HUB_ADDRESS", + "gasPrice": "REGISTER_GAS_PRICE", + "relayUrl": "REGISTER_RELAY_URL", + "unstakeDelay": "REGISTER_UNSTAKE_DELAY" + } + } +``` + +The register process performs the following actions: +- Stakes the Relay Manager +- Adds the Relay Worker +- Registers the Relay Server + +The server is now ready to start processing transactions and a ready message is diplayed on the console. For more details on configuration and registration parameters, refer to the [RIF Relay Server documentation](https://github.com/rsksmart/rif-relay-server#overrides). + +#### Mainnet +- To run RIF Relay Server on the Rootstock Mainnet, the procedure is the same as the one on Testnet, the only difference is the configuration. Configure it to use contracts deployed on Mainnet and an RSKj node connected to Mainnet. diff --git a/docs/develop.md b/docs/develop.md new file mode 100644 index 00000000..3898e3c8 --- /dev/null +++ b/docs/develop.md @@ -0,0 +1,19 @@ +# RIF Relay Develop + +## Initializing the project + +To use RIF Relay, follow these steps to build the project. + +## Project structure + +The project is divided into multiple modules that interact with each other. +Each project has its own documentation in its repository. + +1. [RIF Relay Contracts](https://github.com/rsksmart/rif-relay-contracts) +2. [RIF Relay Client](https://github.com/rsksmart/rif-relay-client) +3. [RIF Relay Server](https://github.com/rsksmart/rif-relay-server) +4. [RIF Relay Sample dApp](https://github.com/rsksmart/rif-relay-sample-dapp) + +## Committing changes + +To contribute to the project, create a branch with the name of the new feature you are implementing (e.g. `gas-optimization`). When you commit to git, a hook is executed. The hook executes a linter and all the tests. \ No newline at end of file diff --git a/docs/gas-costs.md b/docs/gas-costs.md new file mode 100644 index 00000000..59ee20d3 --- /dev/null +++ b/docs/gas-costs.md @@ -0,0 +1,24 @@ +# RIF Relay - Gas Costs + +The overhead gas cost is the extra amount of gas required to process the relay call requested by the user. Let's call **X** the gas consumed by the destination contract method call, and **Y** the total gas consumed by the relay call, then the relay call cost (i.e. overhead gas cost) is: **Z = Y - X**. + +## SmartWallet templates + +RIF Relay V0.1 only has one SmartWallet [template](https://github.com/rsksmart/rif-relay/blob/master/contracts/smartwallet/SmartWallet.sol), which can be used as-is, or be injected with extra logic during the SmartWallet instance creation. + +V0.2 introduces a cheaper template ([SmartWallet](https://github.com/rsksmart/rif-relay/blob/master/contracts/smartwallet/SmartWallet.sol)), to be used when there's no need for extra custom-logic in the smart wallets. The behaviour is the same as the CustomSmartWallet [template](https://github.com/rsksmart/rif-relay/blob/master/contracts/smartwallet/SmartWallet.sol) of V0.2, but without this capability. + +### Gas cost from the deployment of each template. + +| RIF Version | SW Template | Avg. overhead gas | +|-------------|-------------------|-------------------| +| 0.1 | SmartWallet | 172400 | +| 0.2 | CustomSmartWallet | 98070 | +| 0.2 | SmartWallet | 97695 | +| 1 | CustomSmartWallet | TBD | +| 1 | SmartWallet | TBD | + + +:::tip[Note] +The instance of CustomSmartWallet used didn't point to any extra custom logic. +::: \ No newline at end of file diff --git a/docs/installation-requirements.md b/docs/installation-requirements.md new file mode 100644 index 00000000..03499d3c --- /dev/null +++ b/docs/installation-requirements.md @@ -0,0 +1,36 @@ +# RIF Relay Installation Requirements + +To set up the RIF Relay system running locally there are some tools that are required. All of these tools are open source and have their own support page. The functionality of RIF Relay does not depend on these technologies and could be updated or replaced, if necessary. + +## Hardware Requirements + - **A Computer Running x86_64 architecture or Apple Silicon Mac:** A Mac or PC with an Intel x64 architecture or Apple M1 chip (or later models) is required. +## Software Requirements + - **macOS, Windows or Linux:** For macOS, you'll need a recent version that supports Apple Silicon (ARM architecture) and Rosetta 2 translation for running x86_64 applications. + Similarly, for Windows or Linux, any recent distribution that suits your preferences or requirements will work. + - **Rosetta 2:** This translation layer enables x86_64 applications to run on Apple Silicon. It's crucial for running software that is yet to be optimized for ARM architecture. + - **Homebrew:** This is a package manager for macOS used for installing various software, including the x86_64 version of Java. Depending on the software requirements, you might need both the ARM and x86_64 versions of Homebrew. + - **Chocolatey:** This is a Windows equivalent of Homebrew that allows you to install various software, including Java JDK. + - **Java Development Kit (JDK):** An ARM-compatible version of Java JDK (like OpenJDK for ARM). + - **x86_64 JDK:** For compatibility with specific libraries or applications not yet available for ARM, an x86_64 version of Java is also needed. This can be installed using Homebrew under Rosetta 2. + - **Docker:** You need to have `docker` and `docker-compose` installed locally. If you don't have these installed, we recommend following the guidelines in the official [Docker documentation](https://docs.docker.com/get-docker/) for installation and updates. + - **Node & NPM:** We use Node version `v18`. It's recommended to manage Node versions with [`nvm`](https://github.com/nvm-sh/nvm). After installing nvm, run these commands to install and switch to Node version 18: + ```bash + nvm install 18 + nvm use 18 + ``` + To use Node without `nvm`, follow the installation instructions on Node's [official website](https://nodejs.org/en/). After installation, verify it by executing `node -v` in your command line, which will display the installed Node version. This step ensures Node is correctly installed on your system. + - **Ethers:** The interaction with the blockchain is done using [Ethers v5](https://docs.ethers.org/v5/). + +## Getting Started with RIF Relay + +For a detailed step-by-step guide on getting started with RIF Relay, refer to the [Sample dApp](/developers/integrate/rif-relay/sample-dapp/). + + +## RIF Relay Contract Deployment Requirements + +### Hardhat +- We use `Hardhat` version `v2.10.2` for blockchain interactions. For details on how to install Hardhat, follow the instructions on the [Hardhat website](https://hardhat.org/hardhat-runner/docs/getting-started#installation). Use the `npx` prefix for Hardhat commands to ensure the use of the project-specific version. Verify the installation with `npx hardhat version`. For configuration, refer to `hardhat.config.ts`. Detailed usage and configuration instructions are available in [Hardhat's documentation](https://hardhat.org/docs). + +### Using Docker + +- RIF Relay components can be deployed using Docker or locally using [Hardhat](#hardhat). A guide for the [RIF Relay Server](https://github.com/rsksmart/rif-relay-server#execute-as-a-docker-container) can be found in the repository. \ No newline at end of file diff --git a/docs/integrate.md b/docs/integrate.md new file mode 100644 index 00000000..99d3367a --- /dev/null +++ b/docs/integrate.md @@ -0,0 +1,292 @@ +# RIF Relay Integration + +This guide goes over the exposed RIF Relay methods that dApps and wallets can consume to provide relaying as a service, with the purpose of allowing users to pay transaction fees with tokens in a particular system. + +## Introduction + +There are multiple ways to integrate RIF Relay into a system. These will be detailed down below. + +Additionally, it's important to note that not _all_ of the RIF Relay components are needed for a successful integration, as explained in the following section. + +## Requirements + +### RIF Relay Smart Contracts + +These need to be deployed and their addresses known. For steps on how to do this, please refer to the [Contract Deployment](/developers/integrate/rif-relay/deployment/) page of this guide. + +### RIF Relay Server + +The RIF Relay Server is the off-chain component in charge of receiving transactions and sending them to the on-chain components, chiefly the RIF Relay Hub. The RIF Relay Hub manages information about the RIF Relay Workers and RIF Relay Managers, but also communicates with the rest of the on-chain components in turn: the Smart Wallets, Factory and Verifier contracts. + +The RIF Relay Manager owns RIF Relay Worker accounts with funds in native coin. To relay a transaction, a Worker signs it and sends it to the RIF Relay Hub paying for the gas consumed. In the case of a happy flow, transactions will ultimately be relayed through the RIF Relay Hub, using the EIP-712 library. + +For more details on this, please refer to the [Architecture page](/developers/integrate/rif-relay/). + +Users can interact with the RIF Relay Server directly or indirectly. For the latter, a user can communicate with a RIF Relay Server through a RIF Relay Client. A RIF Relay Client knows the addresses of different RIF Relay Servers and it can send on-chain requests to any one of them. The RIF Relay Client then sends the transaction to be sponsored to the RIF Relay Server via HTTP request. + +In any case, you'll need to have the server installed and running. To achieve this please refer to the following guides: +1. [RIF Relay Installation Requirements](/developers/integrate/rif-relay/installation-requirements/) +2. [RIF Relay Deployment](/developers/integrate/rif-relay/deployment/) + +### RIF Relay Client + +The `RelayClient` class, from the RIF Relay Client library, assists in building a relay request, searching for an available server and sending the request via http protocol. + +To create a `RelayClient` we need to follow these steps: + +1. Set the configuration. +2. Set (ethers) provider. +3. Create instance. + +```typescript +import { + RelayClient, + setEnvelopingConfig, + setProvider, +} from '@rsksmart/rif-relay-client'; + + setEnvelopingConfig({ + chainId: , + preferredRelays: , + relayHubAddress: , + deployVerifierAddress: , + relayVerifierAddress: , + smartWalletFactoryAddress: + }); + + setProvider(ethersProvider); + + const relayClient = new RelayClient(); +``` + +Where variables are: + + * **CHAIN_ID**: Identifies a network to interact with. + * **SERVER_URL_ARRAY**: An array of relay server URL strings that the RelayClient can interact with. + * **RELAY_HUB_ADDRESS**: The relay hub contract address. + * **DEPLOY_VERIFIER_ADDRESS**: The deploy verifier contract address. + * **RELAY_VERIFIER_ADDRESS**: The relay verifier contract address. + * **SMART_WALLET_FACTORY_ADDRESS**: The smart wallet factory contract address. + +After setting the configuration and the ethers provider, we can start creating instances from the `Relay Client`. + +#### Account Manager + +The `Account Manager` manager is a singleton component from the RIF Relay Client library that helps to sign relay transactions. This component can sign the transactions with an internal account that was previously added or using a wallet provider like [metamask](https://metamask.io/). The `Account Manager` will look first for manually added accounts and, if none is found, will try to use the provider that was [previously setup](#rif-relay-client). + +The `Account Manager` accepts [Ethers V5 Wallets](https://docs.ethers.org/v5/api/signer/#Wallet) as internal accounts. + +To interact with the `Account Manager` we need to follow the next steps: + +1. Get an instance. +2. Add a new account. + +```typescript + import { + AccountManager, + } from '@rsksmart/rif-relay-client'; + + const accountManager = AccountManager.getInstance(); + + accountManager.addAccount(); +``` + +Where variables are: + + * **INTERNAL_ACCOUNT_OBJECT**: [Ethers V5 Wallet](https://docs.ethers.org/v5/api/signer/#Wallet) object. + +### Relay Transaction + +To relay transactions we need a smart wallet already deployed, the deployment process and definition of a smart wallet can be found [Smart Wallet](/developers/integrate/rif-relay/smart-wallets). + +The steps that we must follow are: + +1. Deploy the smart wallet. +2. Create the transaction that we would like to relay. +3. Relay the transaction. + +```typescript + const relayTransactionOpts: UserDefinedEnvelopingRequest = { + request: { + from: , + data: , + to: , + tokenContract: , + tokenAmount: , + }, + relayData: { + callForwarder: , + }, + }; + + const transaction: Transaction = await relayClient.relayTransaction( + relayTransactionOpts + ); +``` + +Where variables are: + + * **EOA**: Externally Owned Account, the owner of the smart wallet. + * **DATA_TO_EXECUTE**: The encoded function that we want to relay. + * **DESTINATION_ADDRESS**: The address of the destination contract that we want to execute. + * **TOKEN_ADDRESS**: The token contract address that we want to use to pay for the fee. + * **AMOUNT_OF_TOKENS_IN_WEI**: The amount that we want to pay for the fee in wei. + * **SMART_WALLET_ADDRESS**: The smart wallet address that is going to execute the relayed transaction. + +### Relay Verifiers + +To obtain the verifier addresses we need to execute the command: + ``` + curl http:///verifiers + ``` + > The command needs to be executed in a different terminal since it needs the server to be running to perform the request. + +```json + { + "trustedVerifiers": [ + "0x03f23ae1917722d5a27a2ea0bcc98725a2a2a49a", + "0x73ec81da0c72dd112e06c09a6ec03b5544d26f05" + ] + } +``` + +### Build Request + +To relay transactions, the Relay Server exposes an HTTP post handler to the following path `http:///relay`. The Relay Client provides an abstraction to build and send each transaction to the available servers; although the client can simplify the interaction with the server, it's always possible to send HTTP requests to the server without using the Relay Client. + +Each transaction that will be sent, needs to have the following structure: + +```json + { + "relayRequest": "", + "metadata": "" + } +``` + +Below we will describe each field that is required in the request. + +#### Relay Request + + ```json + { + "request": { + "relayHub": "0xDA7Ce79725418F4F6E13Bf5F520C89Cec5f6A974", + "to": "0x1Af2844A588759D0DE58abD568ADD96BB8B3B6D8", + "data": "0xa9059cbb000000000000000000000000c60b724c0865e294d64c94fed89c1e90bce0a7fe0000000000000000000000000000000000000000000000008ac7230489e80000", + "from": "0x553f430066ea56bd4fa9190218af17bad23dcdb1", + "value": "0", + "nonce": "1", + "tokenAmount": "2803630780191436371", + "tokenGas": "31643", + "tokenContract": "0x726ECC75d5D51356AA4d0a5B648790cC345985ED", + "gas": "31515", + "validUntilTime": 1676747217, + }, + "relayData": { + "gasPrice": "60000000", + "callVerifier": "0x03F23ae1917722d5A27a2Ea0Bcc98725a2a2a49a", + "callForwarder": "0x1C8bb3b6809b92F2e38e305FD6bDE9687Bb4ba54", + "feesReceiver": "0x9C34f2225987b0725A4201F1C6EC1adB35562126" + } + } + ``` +Where each key from `request` is: + + * **relayHub**: The relay hub address that will be used to validate the caller from the transaction. + * **to**: The address of the destination contract that we want to execute. + * **data**: The encoded function that we want to relay. + * **from**: Externally Owned Account, the owner of the smart wallet. + * **value**: The native currency value that wants to be transferred from smart wallet during the execution. + * **nonce**: Smart Wallet [nonce](https://github.com/rsksmart/rif-relay-contracts/blob/d1b1ee1c429786f967205f32ed015b3f9a1edaaf/contracts/smartwallet/SmartWallet.sol#L18) to avoid replay attacks. + * **tokenAmount**: The amount of token that we want to pay for the fee in wei. + * **tokenGas**: The gas limit for the token payment transaction. + * **tokenContract**: The token contract address that we want to use to pay for the fee. + * **gas**: The gas limit for the execution of the relaying transaction. + * **validUntilTime**: Transaction expiration time in seconds. + +Where each key from `relayData` is: + + * **gasPrice**: The gas price that will be used to relay the transaction. + * **callVerifier**: The relay verifier address to validate the correctness of the transaction. + * **callForwarder**: The smart wallet address that is going to execute the transaction. + * **feesReceiver**: The address of the worker or collector contract that is going to receive fees. + +#### Deploy Request + + ```json + { + "request": { + "relayHub": "0xDA7Ce79725418F4F6E13Bf5F520C89Cec5f6A974", + "to": "0x0000000000000000000000000000000000000000", + "data": "0x", + "from": "0x553f430066EA56BD4fa9190218AF17bAD23dCdb1", + "value": "0", + "nonce": "0", + "tokenAmount": "0", + "tokenGas": "0", + "tokenContract": "0x1Af2844A588759D0DE58abD568ADD96BB8B3B6D8", + "recoverer": "0x0000000000000000000000000000000000000000", + "index": "1", + "validUntilTime": 1676747036, + }, + "relayData": { + "gasPrice": "60000000", + "callVerifier": "0x73ec81da0C72DD112e06c09A6ec03B5544d26F05", + "callForwarder": "0xE0825f57Dd05Ef62FF731c27222A86E104CC4Cad", + "feesReceiver": "0x9C34f2225987b0725A4201F1C6EC1adB35562126" + } + } + ``` + +Where each key from `request` is: + + * **relayHub**: The relay hub address that will be used to validate the caller from the transaction. + * **to**: The address of the destination contract that we want to execute (`0x0000000000000000000000000000000000000000` for the Smart Wallet deployment). + * **data**: The encoded function that we want to relay (`0x` for the Smart Wallet deployment). + * **from**: Externally Owned Account, the owner of the smart wallet. + * **value**: The native currency value that wants to be transferred from smart wallet during the execution. + * **nonce**: The SmartWalletFactory keeps track of the [nonces](https://github.com/rsksmart/rif-relay-contracts/blob/d1b1ee1c429786f967205f32ed015b3f9a1edaaf/contracts/factory/SmartWalletFactory.sol#L95) used for each smart wallet owner, to avoid replay attacks. It can be retrieved with [`IWalletFactory.nonce(from)`](https://github.com/rsksmart/rif-relay-contracts/blob/d1b1ee1c429786f967205f32ed015b3f9a1edaaf/contracts/interfaces/IWalletFactory.sol#L8) + * **tokenAmount**: The amount that we want to pay for the fee in wei. + * **tokenGas**: The gas limit for the token payment transaction. + * **tokenContract**: The token contract address that we want to use to pay for the fee. + * **recoverer**: The recoverer address, to recover funds from the smart wallet. This feature is still pending to implement. + * **index**: The index from the smart wallet that we want to deploy. + * **validUntilTime**: Transaction expiration time in seconds. + +Where each key from `relayData` is: + + * **gasPrice**: The gas price that will be used to relay the transaction. + * **callVerifier**: The deploy verifier address to validate the correctness of the transaction. + * **callForwarder**: The smart wallet factory address that is going to perform the deployment. + * **feesReceiver**: The address from the worker or collector contract that is going to receive fees. + +#### Metadata + +```json + { + "relayHubAddress": "0xDA7Ce79725418F4F6E13Bf5F520C89Cec5f6A974", + "signature": "0xa9f579cf964c03ac194f577b5fca5271ba13e2965c...", + "relayMaxNonce": 4 + } +``` + +Where each key is: + +* **relayHubAddress**: The relay hub that will be used by the server to relay the transaction. +* **signature**: The relay transaction signed by the owner. After signing the transaction, it cannot be changed, since there is a on-chain validation that is part of the EIP712. +* **relayMaxNonce**: Relay worker nonce plus an extra gap. + +### Custom worker replenish function + +Each relayed transaction is signed by a Relay Worker account. The worker accounts are controlled by the Relay Manager. When a relay worker signs and relays a transaction, the cost for that transaction is paid using the funds in that worker's account. If the transaction is not subsidized, then the worker is compensated with tokens. + +Worker accounts must always have some minimum balance to pay gas for the transaction. These balances can be managed by implementing a replenishment strategy. The Relay Manager can use the strategy to top off a relay worker's account when the balance gets too low. + +We provide a default implementation for a replenish strategy. RIF Relay solution integrators can implement their own replenish strategy. + +To implement and use your own replenish strategy: + +1. In the folder `src` from the RIF Relay Server project, open `ReplenishFunction.ts` with a text editor. +2. On the function `replenishStrategy` write your new replenish strategy. +3. Re build the project `npm run build` +4. Change the config JSON file to set `customReplenish` on true. \ No newline at end of file diff --git a/docs/sample-dapp.md b/docs/sample-dapp.md new file mode 100644 index 00000000..e87cf09a --- /dev/null +++ b/docs/sample-dapp.md @@ -0,0 +1,132 @@ +# How to use the RIF Relay Sample dApp SDK + +## Getting Started + +This guide helps to quickly get started with setting up your environment to use RIF Relay and also use the sample dApp to test relay services. + +### Step 1: Run the Rootstock node + +You need to set up and run a Rootstock node, preferably the latest version from RSKj releases. The node can operate locally or via Docker. In either case, a [`node.conf`](https://github.com/rsksmart/rif-relay/blob/main/docker/node.conf) file is used. + +Refer to the [Rootstock Node Installation Guide](/node-operators/setup/installation/) for a detailed guide on this step. + + +### Step 2: Add network to Metamask + +To interact with the Rootstock network, you need to add it to Metamask. Since we're using the node on `--regtest mode`, follow the Metatmask guide on [How to add a custom network RPC](https://support.metamask.io/hc/en-us/articles/360043227612-How-to-add-a-custom-network-RPC) and add the Rootstock RegTest Network to Metamask with the following data: + +```text +- Network name: RSK regtest +- New RPC URL: http://127.0.0.1:4444 +- Chain ID: 33 +- Currency symbol: tRBTC +``` + +To learn more about Metatmask and how to add it to Rootstock programmatically, see [Metamask](/dev-tools/wallets/metamask/) and [How to add Metamask to Rootstock Programmatically](/resources/tutorials/rootstock-metamask/). + + +### Step 3: Set up RIF Relay contracts + +To set up RIF relay contract, clone the RIF Relay Contracts Repository: https://github.com/rsksmart/rif-relay-contracts, then follow the [RIF Relay Deployment](/developers/integrate/rif-relay/deployment/) guide to deploy an RIF Relay contract, enable revenue sharing, and whitelist the token by allowing it. + + + + Check allowed tokens + + ```bash + npx hardhat allowed-tokens --network regtest + ``` + Response: + ```bash + rif-relay-contracts % npx hardhat allowed-tokens --network regtest + deployVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + relayVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + customDeployVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + customRelayVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + nativeHolderDeployVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + nativeHolderRelayVerifier [ '0x6f217dEd6c86A57f1211F464302e6fA544045B4f' ] + ``` + + + + Mint token + + - To mint new units of the `UtilToken` into the Metamask wallet address: + - Go to the Metamask wallet, and copy the wallet address: + - Execute the command to mint the token, where: + - `--token-address` → this is the address for `UtilToken` + - `--amount` → quantity to be minted + - `--receiver` → wallet address + ```bash + npx hardhat mint \ + --token-address 0x6f217dEd6c86A57f1211F464302e6fA544045B4f \ + --amount 10000000000000000000 \ + --receiver \ + --network regtest + ``` + - Import the minted token into the wallet. + - To see the token in the wallet, click on “import tokens”, and then paste the token address. + + + + +### Step 4: Set up RIF Relay Server + +Clone the [RIF Relay Server Repository](https://github.com/rsksmart/rif-relay-server), then refer to [Run the RIF Relay Server](/developers/integrate/rif-relay/deployment#run-the-rif-relay-server) for a complete guide on setting up the RIF Relay server. + + +## RIF Relay Sample dApp + +This sample dApp shows you how to send transactions to the Rootstock blockchain using the [RIF Relay Sample dApp SDK](https://github.com/rsksmart/rif-relay-sample-dapp). You'll need to connect the dApp with MetaMask for signing transactions with the account managing your Smart Wallets. + +### Clone SDK repository and install dependencies + +```bash + # clone repository + git clone https://github.com/rsksmart/relaying-services-sdk-dapp + cd relaying-services-sdk-dapp + # install dependencies + npm install --force +``` +- Configure environment variables + +Create a new file named `.env` in the top directory, and add the following lines in it (with the contract addresses generated when we deployed the contracts) in the **Set up RIF Relay Contracts** section above: + +```bash + REACT_APP_CONTRACTS_RELAY_HUB=0x463F29B11503e198f6EbeC9903b4e5AaEddf6D29 + REACT_APP_CONTRACTS_DEPLOY_VERIFIER=0x14f6504A7ca4e574868cf8b49e85187d3Da9FA70 + REACT_APP_CONTRACTS_RELAY_VERIFIER=0xA66939ac57893C2E65425a5D66099Bc20C76D4CD + REACT_APP_CONTRACTS_SMART_WALLET_FACTORY=0x79bbC6403708C6578B0896bF1d1a91D2BB2AAa1c + REACT_APP_CONTRACTS_SMART_WALLET=0x987c1f13d417F7E04d852B44badc883E4E9782e1 + + REACT_APP_RIF_RELAY_CHAIN_ID=33 + REACT_APP_RIF_RELAY_GAS_PRICE_FACTOR_PERCENT=0 + REACT_APP_RIF_RELAY_LOOKUP_WINDOW_BLOCKS=1e5 + REACT_APP_RIF_RELAY_PREFERRED_RELAYS=http://localhost:8090 +<<<<<<< HEAD + REACT_APP_BLOCK_EXPLORER=https://explorer.testnet.rootstock.io +======= + REACT_APP_BLOCK_EXPLORER=https://explorer.testnet.rootstock.io/ +>>>>>>> main +``` + +### Run the dApp + +```bash + # run app in regtest environment + ENV_VALUE="regtest" npm run start +``` +![Run the dApp](/img/rif-relay/starter-kit/run-the-dapp.png) + +- Connect metamask wallet for signing + +![Connect Metamask Wallet](/img/rif-relay/starter-kit/connect-metamask-wallet.png) +- Create a new smart wallet + +![Create a new Smart Wallet](/img/rif-relay/starter-kit/create-smart-wallet.png) + +- Mint tokens to the wallet + - For commands to mint token, See step 6 in the Set up RIF Relay contracts section above. +![Mint Tokens](/img/rif-relay/starter-kit/mint-tokens.png) +- Transfer to different addresses, using TKN for transfer fees payment, instead of RBTC +![Transfer using TKN](/img/rif-relay/starter-kit/transfer-using-tkn.png) \ No newline at end of file diff --git a/docs/smart-wallets.md b/docs/smart-wallets.md new file mode 100644 index 00000000..4e9be7ba --- /dev/null +++ b/docs/smart-wallets.md @@ -0,0 +1,68 @@ +# RIF Relay Smart Wallets + +This guide is intended to explain more about the interaction and deployment of the Smart Wallets. We will be using additional testing contracts that were included in the project, like the `UtilToken(ERC20)`. All the utils scripts are executed from the account[0] from the regtest network. + +## Prerequisites + +* Follow the deployment process in [Deployment Guide](/developers/integrate/rif-relay/deployment). +* The definition of the smart wallet can be found in [Architecture](/developers/integrate/rif-relay/architecture/) + +## Ways to create smart wallets + +There are **two ways** to create a Smart Wallet: + +1. **Regular transaction:** The Requester (or another account on behalf of the Requester) calls the Proxy Factory asking to get a new Smart Wallet. Therefore the Proxy Factory creates a proxy to the SmartWallet code, delegating the ownership to the Requester. +2. **Sponsored:** It needs to go through the RIF Relay process, which is described in detail below. The requester asks a third party to pay for the Smart Wallet deployment, and the requester pays in tokens for that (or free if it is subsidized by the third-party, a.k.a, Sponsor). + +## Send funds + +In the [RIF Relay Contracts](https://github.com/rsksmart/rif-relay-contracts) there is a script that would help us to mint ERC20 tokens. + +We need to execute the following script: + +```shell +npx hardhat mint --token-address <0xabc123> --amount --receiver <0xabc123> --network regtest +``` +> The token contract needs to have a mint function. + +## Deploy a Smart Wallet + +To deploy a smart wallet we need to follow some steps that will be described below: + +1. We need to generate the smart wallet address. As we mentioned before, the Smart Wallet is a contract-based account, therefore, we can generate as many smart wallet addresses as we want without spending gas by calling the `getSmartWalletAddress` from the relay client library. + +> A Smart Wallet only needs to be deployed when we need to execute a transaction. The deployment process uses gas so, unless it's subsidized, we need to pay for it. + + +At this point we should have the Relay Client object created. + +```typescript + import type { + getSmartWalletAddress, + UserDefinedDeployRequest, + } from '@rsksmart/rif-relay-client'; + + const smartWalletAddress = await getSmartWalletAddress(, ); + + const relayTransactionOpts: UserDefinedDeployRequest = { + request: { + from: , + tokenContract: , + tokenAmount: , + index: , + }, + }; + + const transaction = await relayClient.relayTransaction( + relayTransactionOpts + ); + +``` +> Keep in mind that to pay any amount of token fees during the deployment, the smart wallet must receive funds first. + +Where variables are: + +* **EOA**: Externally Owned Account, the owner of the smart wallet. +* **INDEX**: The index that we would like to use to generate the smart wallet. +* **TOKEN_ADDRESS**: The token contract address that we want to use to pay for the fee. +* **AMOUNT_OF_TOKENS_IN_WEI**: The amount that we want to pay for the fee in wei. \ No newline at end of file diff --git a/docs/versions.md b/docs/versions.md new file mode 100644 index 00000000..6b20abf6 --- /dev/null +++ b/docs/versions.md @@ -0,0 +1,59 @@ +# RIF Relay Versions + +The first iteration of RIF Relay was based on the great work done by the [Gas Station Network team](https://www.opengsn.org/). + +## Version 0.1 + +RIF Relay V0.1 started as a fork of GSN with two goals in mind: + +- Be compatible with existing and future smart contracts without requiring such contracts to be adapted to work with RIF Relay. +- Be as cost effective as possible. + +## Version 0.2 + +### Overview + +RIF Relay V0.2 is a redesign of GSN. It reduces gas costs and simplifies the interaction between the different contracts that are part of the system. It achieves this by: + +- Securely deploying counterfactual Smart Wallet proxies for each user account: this eliminates the need for relying on `_msgSender()` and `_msgData()` functions, making existing and future contracts compatible with RIF Relay without any modification. +- Allowing relayers to receive tokens in a worker address under their control and decide what to do with funds later on. +- Reducing gas costs by optimizing the GSN architecture. + +Our main objective is to provide the Rootstock (RSK) ecosystem with the means to enable blockchain applications and end-users (wallet-apps) to pay for transaction fees using tokens (e.g. RIF tokens), and thereby remove the need to acquire RBTC in advance. + +It is important to recall that - as a security measure - V0.1 contracts deployed on Mainnet have limits on the staked amounts to operate; these limits were removed in V0.2. + +### Details + +* RelayHub contract no longer receives payments, the payment for the service (in tokens) is now sent directly to the worker relaying the transaction on behalf of the user. +* RelayHub contract now handles relay manager staking. +* Gas estimation improvements: + * Gas overhead removed from RelayHub; there are no more validations against hardcoded values. + * The gas and token gas fields from the request can now be left undefined, and in that case, they will automatically be estimated by the RIF Relay Client. + * The maximum gas estimation in the RIF Relay Server is more precise now. + * A new utility function is available to estimate the maximum gas a relay transaction would consume, based in a linear fit estimation. This can be used in applications that don't want to sign a payload each time they need an approximation of the cost of relaying the transaction. +* Paymaster verifications are done off-chain to optimize gas costs, thus the paymasters are now called Verifiers and they are not part of the on-chain relay flow nor do they handle payments at all. +* Gas cost optimization. +* Security issues. + + +## Version 1 + +### Overview + +Including a revenue-sharing mechanism to the RIF Relay service doesn't introduce a price penalty to the RIF Relay users. We modified the address used to receive the payment (in tokens) for a successful transaction relay (or deploy). + +In V0.2 implementation, the RelayRequest and the DeployRequest include a relayWorker attribute to identify which account paid for the gas. The RIF Relay SmartWallet pays directly to this account the number of tokens negotiated for the Relay (or Deploy) service. In V1 The relayWorker attribute was removed from the RelayRequest and DeployRequest. A new attribute called feesReceiver was implemented and configured in the RelayServer + +This change did not alter the current relay flow, keeping its cost as it is today, and also introduced the flexibility to implement any revenue-sharing strategy needed. + +* The feesReceiver could be the worker or MultSig contract. +* The SmartWallet will pay to the feesReceiver. The feesReceiver will hold the funds of each user payment. +* Upon payment from the SmartWallet, the feesReceiver will not perform any distribution logic to avoid increasing the cost of the relay service for the user. +* With this approach, no changes in the relay flow are required, and thus the introduction of a revenue-sharing mechanism will not impact the price of the relay service. +* The relevant participants will form part of the MultiSig contract. + * The MultiSig contract specify how much of the funds collected go to each participant (e.g., the relayServer operator, the wallet provider, and the liquidity provider could be the participants). + * At a later time, an off-chain process will trigger the distribution process from the contract. This process can invoke the distribution function once per week, month, or when the funds in the contract surpass a certain threshold. + * The participants can modify the sharing parameters (e.g., the percentages used for the distribution among the participants) if they agree on the particular changes. + * Multiple Revenue Sharing Strategies can exist, ideally one per group of participants. + diff --git a/docs/README.md b/docs[DEPRECATED]/README.md similarity index 100% rename from docs/README.md rename to docs[DEPRECATED]/README.md diff --git a/docs/basic_requirements.md b/docs[DEPRECATED]/basic_requirements.md similarity index 100% rename from docs/basic_requirements.md rename to docs[DEPRECATED]/basic_requirements.md diff --git a/docs/development_guide.md b/docs[DEPRECATED]/development_guide.md similarity index 100% rename from docs/development_guide.md rename to docs[DEPRECATED]/development_guide.md diff --git a/docs/enveloping_architecture.md b/docs[DEPRECATED]/enveloping_architecture.md similarity index 100% rename from docs/enveloping_architecture.md rename to docs[DEPRECATED]/enveloping_architecture.md diff --git a/docs/integration_guide.md b/docs[DEPRECATED]/integration_guide.md similarity index 100% rename from docs/integration_guide.md rename to docs[DEPRECATED]/integration_guide.md diff --git a/docs/launching_enveloping.md b/docs[DEPRECATED]/launching_enveloping.md similarity index 100% rename from docs/launching_enveloping.md rename to docs[DEPRECATED]/launching_enveloping.md diff --git a/docs/overhead_tx_costs.md b/docs[DEPRECATED]/overhead_tx_costs.md similarity index 100% rename from docs/overhead_tx_costs.md rename to docs[DEPRECATED]/overhead_tx_costs.md diff --git a/docs/pr_128_changelog.md b/docs[DEPRECATED]/pr_128_changelog.md similarity index 100% rename from docs/pr_128_changelog.md rename to docs[DEPRECATED]/pr_128_changelog.md