Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Web Components for integrating Request Network. Usable in any framework.
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Request Network API provides an interface for creating and paying requests within your application.
At its core, the Request Network API empowers you to:
Create Requests: Define payment requests with information such as payee, payer (optional), amount, currency, and recurrence (optional).
Facilitate Payments: Return transaction calldata, ready to be signed by end-users and sent to the blockchain for secure and transparent value transfer.
Deliver Webhook Notifications: Receive instant updates on payment status changes, enabling your application to react dynamically to completed transactions.
For detailed information on all available endpoints and their parameters, please refer to the full Request Network API Reference
The following diagram illustrates the typical flow for creating and paying requests using the Request Network API:
Request Network is a protocol for creating payment requests and reconciling payments.
An app for creating and paying requests using the Request Network API.
EasyInvoice is a web application built with Next.js that allows users to create and manage invoices, and accept crypto payments via the Request Network API. It mimics Web2 apps in its functionalities, providing a user-friendly experience with Google login and real-time updates.
Google Login: Securely log in to your account using Google OAuth.
Invoice Creation: A simple form to create invoices.
Client name and email fields.
Items, amounts, and notes fields.
Invoice currency and payment currency options, supporting currency conversion via the Request Network API.
Currency Conversion: uses on-chain price feeds to calculate the exact payment currency amount based on the invoice currency at the moment of payment so you always receive the correct amount.
Dashboard: View key metrics and a table of your invoices.
Invoice Payment:
View invoice details and initiate payment using transaction calldata provided by the Request Network API.
Compatible with 50+ different crypto wallets.
Real-time Updates: The app receives webhooks from the Request Network API to update the invoice status in real-time.
Warning: Crosschain payments are currently only available in our staging environment at https://easyinvoice.stage.request.network and are not ready for production use. Use with caution.
Direct Payment: Send a payment without having to create a request first.
Login: Log in with your Google account to access the dashboard.
Create Invoice: Fill out the invoice form with the necessary details, including client information, amount, currency, and payee address.
If the invoice currency is USD, you must select a payment currency (Sepolia ETH or FAU) for conversion.
For non-conversion scenarios, the payment currency will be the same as the invoice currency.
Pay Invoice: Connect your wallet and initiate the payment. The app will guide you through the steps, including ERC20 approval and transaction confirmation.
Monitor Status: Track the payment status in real-time on the invoice details page and the dashboard.
This page details the endpoints for managing API keys and webhooks programmatically. These endpoints allow you to control access to the Request Network API, and receive real-time notifications about important events.
Key Features:
API Key Management: Create, list, toggle, and delete API keys to control access to your platform's resources. API keys are essential for authenticating your application and ensuring secure communication with the Request Network API.
Webhook Management: Configure and manage webhooks to receive real-time notifications about events within the Request Network. This enables your application to react instantly to payment confirmations, request updates, and other critical events.
Authentication Requirement:
Most of the endpoints described in this section require an active session_token
cookie. This cookie is automatically set in your browser after a successful login. Make sure you've logged in before attempting to use these endpoints.
For detailed information on all available endpoints and their parameters, please refer to the full
Pay requests using stablecoins from any supported network, without manual bridging or token swaps.
Crosschain payments allow users to pay a request using a stablecoin from a different blockchain network than the one specified on the request. For example, a payer can pay an request for USDC on Base using USDT from their Polygon wallet.
Flexibility: Payers can pay with their preferred currency.
Cost-Effective: Automated routing balances cost and speed.
Time-Saving: Payers don't need to swap or bridge tokens manually.
Simplified UX: Payment settlement requires only 1 or 2 signatures from the Payer.
Crosschain payments are supported on the following blockchain networks:
Polygon
Base
Optimism
Arbitrum
Ethereum
Warning: Crosschain payments work only with mainnet funds (real money). Test networks are not supported.
The following stablecoins are supported for crosschain payments on both the sending and receiving networks.
USDC
USDT
DAI
To enable crosschain payments, the request must be created with the following parameters:
amount
greater than 2 - executing crosschain payments under 2 stablecoins is not allowed, even though creating requests has no restrictions on amount
.
even though creating requests for under 2 stablecoins is a
The API automatically ranks available payment routes based on the following factors:
Transaction fees
Processing speed
Routes that offer the best combination of lower fees and faster processing times are ranked higher in the results.
The API may return samechain routes if the payer address has supported currencies on the same chain as the paymentCurrency
.
Example: paymentCurrency
is USDC on Polygon, and the payer has USDT on Polygon
Gassless transactions - the transaction fees are added on top of the request amount
No native token (ETH, POL, etc..) needed for gas
If the token does not support EIP-2612 Permit, the payer must sign and submit a standard ERC20 approval transaction.
It will be possible in the future to add additional custom fee to the payment, this is currently under development.
The payment proxy smart contracts enable the various payment types.
The most widely deployed payment proxy is the ERC20FeeProxy. The most frequently used payment proxy is the ERC20ConversionProxy.
These smart contracts facilitate storing IPFS content addressable hashes (CIDs) on-chain.
The REQ Token is on Ethereum Mainnet. The burn contracts facilitate locking xDAI on Gnosis, bridging xDAI to Ethereum, swapping xDAI for REQ, and burning the REQ.
Try it out
View Source
Talk to an expert Discover how Request Network API can enhance your app's features - with us.
Warning: Crosschain payments are currently only available in our staging environment at and are not ready for production use. Use with caution.
paymentCurrency
included in the and .
For more details about creating requests, please see the endpoint.
To display a list of possible routes for a given request and payer address, use the endpoint. It returns all of the possible routes based on the payer's token balances.
Once the route is selected, the payer needs to fetch the unsigned payment calldata or intents.
If the selected route is a crosschain payment, the endpoint returns an unsigned payment intent. It will also return an unsigned approval permit or unsigned approval calldata, depending on whether the paymentCurrency
supports . For crosschain payments, this endpoint is NOT approval aware - it will return an approval permit or approval calldata even if approval has already been granted.
If the selected route is a direct payment, the returns an unsigned payment calldata. It may also return an approval calldata. For direct payments, this endpoint IS approval aware - it will omit the approval calldata if sufficient approval has already been granted.
The intents and calldata returned by the endpoint in the previous step must be signed by the payer's wallet to authorize the crosschain payment. The process for signing the approval varies depending on whether the paymentCurrency
supports , indicated by the metadata
response parameter.
Finally, the signed payment intent (and possibly the signed approval permit) are sent back to execute the crosschain payment via the endpoint. It will handle all the necessary steps to complete the payment. A payment.complete
event will be sent to the platform's webhooks when the payment is completed.
For an explanation of what each smart contract does, see
Make sure to scroll horizontally to see all the payment proxy types!
Ethereum Mainnet
mainnet
1
Sepolia
sepolia
11155111
Goerli (deprecated)
goerli
5
Optimism
optimism
10
Arbitrum One
arbitrum-one
42161
Base
base
8453
zkSync Era
zksyncera
324
zkSync Goerli (deprecated)
zksynceratestnet
280
Gnosis
xdai
100
Polygon
matic
137
Mumbai
mumbai
80001
BSC
bsc
56
BSC Testnet
bsctest
97
Celo
celo
42220
Alfajores
alfajores
44787
Fantom
fantom
250
Tombchain
tombchain
6969
Core
core
1116
Avalanche
avalanche
43114
Fuse
fuse
122
Moonbeam
moonbeam
1284
Ronin
ronin
2020
Mantle
mantle
5000
Mantle Testnet
mantle-testnet
5001
NEAR
N/A
N/A
NEAR Testnet
N/A
N/A
Gnosis
100
Sepolia
11155111
Ethereum Mainnet (deprecated)
1
Goerli (deprecated)
5
Ethereum Mainnet
1
Gnosis
100
The Request Network Token List is a curated list of tokens supported by Request Network products. The token list follows a standardized format and includes essential information about each token, such as address, symbol, name, decimals, and chainId.
The token list is available at: https://requestnetwork.github.io/request-token-list/latest.json
You can fetch the token list directly in your application:
Each token in the list contains the following information:
We welcome community contributions! To add a new token to the list:
Fork the request-token-list repository on Github
Add your token information to tokens/token-list.json
Make sure your token meets our requirements (see CONTRIBUTING.md)
Run tests locally: npm test
Create a Pull Request
An app for managing Request Network API keys and webhooks.
The Request Network API Portal provides app developers with a platform to securely manage their API keys and webhook endpoints.
Create and Manage API Keys: Users can create new API keys for authentication.
Toggle and Delete API Keys: API keys can be toggled on and off, or deleted if no longer needed, enhancing control over API access.
Security Guidelines: API keys are sensitive and should never be shared publicly. In case of compromise, users are advised to create a new key, update their code, and delete the compromised key.
Multiple Keys: Allows the creation of multiple API keys for different environments or applications.
Create and Manage Webhooks: App developers can configure webhook endpoints to receive real-time notifications for payment events.
Security Guidelines: Each webhook request includes a signature in the `x-request-network-signature` header to ensure authenticity.
Signature Verification: The signature is a SHA-256 HMAC of the request body, signed using the webhook secret.
Example Verification Code:
Navigate to the "API Keys" section.
Click on "Create new key."
Store the key securely and never share it publicly.
Navigate to the "Webhooks" section.
Click on "Add webhook."
Enter the endpoint URL and ensure the endpoint is secure and can handle incoming JSON payloads.
Keep API keys and webhook secrets secure. Never expose them in public repositories or client-side code.
Verify all webhook signatures to ensure authenticity and integrity.
Use HTTPS for all endpoints to encrypt communication.
An explorer app for viewing requests, payments, and addresses in Request Network.
Request Scan is an explorer for viewing requests and payments in Request Network. It enables users to explore and scrutinize requests, payments, and addresses within the Request Network ecosystem.
Request Scan caters to a broad audience:
Accountants: Audit and verify financial data on the request network.
Developers: Easily access Request Network data for troubleshooting your applications.
Analysts: Gain deep insights into network activity and trends.
Researchers: Conduct in-depth studies on blockchain data.
Enthusiasts: Stay informed about the latest happenings on the Request Network.
Search Bar: Located at the top, allows you to search for specific requests or addresses.
Dashboard: Provides an overview of network statistics and recent activity.
Requests: View a list of recent requests with details like payee, payer, amount, and timestamp.
Payments: View a list of recent payments with details like blockchain transactions, amounts, fees, and timestamps.
Address: View information about individual addresses, including their requests and payments.
Request: View information about individual requests, including their details and table with actions and payments.
Request: Enter a request ID in the search bar to view its details.
Address: Enter an address to see its requests and payment history.
The typical lifecycle of a request is as follows:
The payer or payee signs the request which contains the payee, payer, currency, amount, payment details, and arbitrary content data.
The request can be optionally encrypted such that only the payee, payer, and approved 3rd parties can view the request contents.
The request is persisted in IPFS.
The IPFS Content-addressable ID (CID) is stored in a smart contract on Gnosis chain
The payee can optionally cancel the request or increase/decrease the expected amount.
The payer can optionally accept the request, indicating that they intend to pay it.
Both payee and payer can add 3rd party stakeholders if the request is encrypted.
The payer derives a paymentReference from the request contents.
The payer calls a function on the payment network smart contract, passing in the token address, to address, amount, and paymentReference.
An event is emitted containing the token address, to address, amount, and paymentReference.
The event is indexed by the payments subgraph
An app can retrieve the request contents from IPFS and calculate the balance based on events from the payments subgraph.
This page will introduce the primary operations provided by Request Network’s SDK while using the EthereumPrivateKeySignatureProvider
to sign requests with a private key that is managed outside of a wallet.
This approach works well for Node.js environments without access to a Web3 wallet.
To create an unencrypted ERC-20 request, first construct an EthereumPrivateKeySignatureProvider
with a private key.
Then, first construct a RequestNetwork
, passing in the:
Request Node URL. In this example, we use the Sepolia Request Node Gateway.
EthereumPrivateKeySignatureProvider
constructed in the previous step.
Prepare the Request creation parameters:
Then, call createRequest()
to create the request and waitForConfirmation()
to wait until the request is persisted in IPFS and the CID hash is stored on-chain.
Altogether it looks like this:
First, construct a RequestNetwork
object and connect it to a Request Node. In this example, we use the Sepolia Request Node Gateway:
Then, retrieve the request and get the request data. Take note of the current request balance, to be used later for payment detection.
Then, construct an ethers
v5 Provider
and Wallet
using a private key. These allow you to read and write to the chain, respectively.
Unfortunately, the Request Network SDK does not yet support ethers v6.
Coming soon. Probably involves publicClientToProvider()
and walletClientToSigner()
.
Then, check that the payer has sufficient funds using hasSufficientFunds()
Then, in the case of an ERC-20 request, check that the payer has granted sufficient approval using hasErc20Approval()
. If not, submit an approval transaction using approveErc20
. Wait for an appropriate number of block confirmations. On Sepolia or Ethereum, 2 block confirmations should suffice. Other chains may require more.
Finally, pay the request using payRequest()
Detect that the payment was successful by polling the request and waiting until the request balance is greater than or equal to the expected amount.
Altogether it looks like this:
First, construct a RequestNetwork
object and connect it to a Request Node. In this example, we use the Sepolia Request Node Gateway:
Then, call fromIdentity()
to get an array of Request
objects or fromRequestId()
to get a single Request
object. This function retrieves the Request
s stored in IPFS and queries on-chain events to determine the balances paid so far. Finally, call getData()
on each Request
to get the request contents.
Altogether it looks like this:
All of these steps are facilitated by the Request Network JavaScript SDK such that the developer needs only make a few function calls. See the to learn more.
All of the following examples can be found in this repository
The best way to access Request Network is using the Request Network SDK with a Request Node. In this way, the Request Node operator pays the protocol fee for creating requests and reduces the number of transactions signed by the end user resulting in a better user experience.
The Request Network SDK is split into multiple packages so that Builders can pick and choose the features they need.
These are the packages that we think would be most commonly used by Builders to build applications.
Create, update, and retrieve requests.
Sign requests using web3 wallets like Metamask
Sign requests using Ethereum private keys
Standards for data stored on Request, like invoice format
Decrypt encrypted requests using Ethereum private keys
Pay a request using a web3 wallet
Web server that allows easy access to the Request system
Tools for managing currency definitions
For a list of internal SDK packages, see Internal SDK Packages.
These packages offer pre-built components for quickly integrating certain Request Network features.
A form for creating invoices in Request Network
A dashboard for viewing and paying invoices in Request Network
A dialog box for granting third-party access to an encrypted invoice created via Request Finance
The Request Client library can be imported as ES6 or CommonJS modules.
These packages are published publicly but contain functions that are considered internal to the SDK Packages. It is less likely that a Builder would need to use these packages.
Extensions to the protocol
Indexing and batching of transactions
Storage of Request data on Ethereum and IPFS, with custom indexing
Serialize and deserialize object in the Request Network protocol
Payment detection, to compute the balance.
The Request business logic: properties and actions of requests
Sources and artifacts of the smart contracts
Storage of Request data on Ethereum and IPFS, indexed by TheGraph
Creates transactions to be sent to Data Access, managing encryption
Typescript types shared across @requestnetwork packages
Collection of tools shared between the @requestnetwork packages
A CLI tool to help inject Request Network functionality into projects
The Request Network Injector CLI simplifies the integration process by automatically injecting pre-built, customizable functions into your project. This tool allows new and experienced builders to quickly integrate the Request Network Protocol into their applications with minimal setup.
Automatic injection of essential Request Network functions
Support for both TypeScript and JavaScript projects
Customizable function selection
Automatic package installation
Support for various package managers (npm, yarn, pnpm, bun)
The CLI analyzes your project structure
You select the functions you want to inject
You choose your preferred language (TypeScript or JavaScript)
The tool injects the selected functions into your project
Necessary dependencies are automatically installed
The Request Network Foundation operates several Request Node "Gateways" that are free for anyone to use. These gateways offer endpoints for creating and retrieving requests. They also pay the protocol fee for creating requests, about USD $0.10 per request, paid in XDAI.
Examples to quickly integrate Request Network
The Request Network Templates are examples of how to integrate the Request Network Components into various web frameworks.
The Request Network Templates are distributed as "Template Repositories" in Github. The Github Docs explain how to Create a new repository from a template repository.
Instructions to pay a request from a Safe Multisig
The Request Network Templates and Example Apps support paying a request from a Safe multisig wallet.
When connecting your wallet, select WalletConnect.
Copy the WalletConnect Pairing Code.
Click the WalletConnect button on the Safe top-navigation bar and paste the Pairing Code into the resulting dialog.
The playground for adding crypto payments to any website, build using Payment Widget.
Next.js
Demo Page
Playground Page
ERC20 Payments
Native Token Payments
Fiat Price Conversion in the UI
Configure Logo and Colors
Inject your own custom currency list
Download Receipt as PDF
Ethereum
USDC, USDT, DAI, AXS, AUDIO, RAI, SYLO, LDO, UST, MNT, MIR, INJ, OCEAN, ANKR, RLY, REQ, ETH
Polygon
USDC, USDT, DAI, MATIC
Sepolia
FAU, ETH, USDT, USDC
BNB Smart Chain
DAI, BUSD
Gnosis
USDC
Avalanche
USDC, USDT, AVAX
Optimism
USDC, USDT, DAI, ETH
Moonbeam
USDC (multichain), USDC (wormhole)
Fantom
FTM
zkSync Era
ETH
Base
ETH
This page will introduce the primary operations provided by Request Network’s SDK while using the Web3SignatureProvider
to sign requests with a private key stored inside a wallet.
This approach works well for Browser environments with access to a web3 wallet.
To create an unencrypted ERC-20 request, first connect to an ethers
v5 Provider
and Signer
or wagmi
/ viem
WalletClient.
Unfortunately, the Request Network SDK does not yet support ethers v6.
Then, construct a Web3SignatureProvider
, passing in the ethers
Provider
or viem
WalletClient.
Then, construct a RequestNetwork
, passing in the:
Request Node URL. In this example, we use the Sepolia Request Node Gateway.
Web3SignatureProvider
constructed in the previous step.
Then, prepare the Request creation parameters:
Then, call createRequest()
to prepare a Request
object.
Finally, call request.waitForConfirmation()
to wait until:
The request contents are persisted in IPFS
The Content-addressable ID (CID) is stored on-chain
The resulting on-chain event is indexed by the storage subgraph.
First, construct a RequestNetwork
object and connect it to a Request Node. In this example, we use the Sepolia Request Node Gateway:
Then, retrieve the request and get the request data. Take note of the current request balance, to be used later for payment detection.
Then, construct an ethers
v5 Provider
and Signer
. These allow you to read and write to the chain, respectively.
Unfortunately, the Request Network SDK does not yet support ethers v6.
Very similar to wagmi, but without using hooks. Instead, call publicClientToProvider()
or walletClientToSigner()
Then, check that the payer has sufficient funds using hasSufficientFunds()
Then, in the case of an ERC-20 request, check that the payer has granted sufficient approval using hasErc20Approval()
. If not, submit an approval transaction using approveErc20
. Wait for an appropriate number of block confirmations. On Sepolia or Ethereum, 2 block confirmations should suffice. Other chains may require more.
Finally, pay the request using payRequest()
You can detect that the payment was successful by polling the request and waiting until the request balance is greater than or equal to the expected amount.
First, construct a RequestNetwork
object and connect it to a Request Node. In this example, we use the Sepolia Request Node Gateway:
Then, call fromIdentity()
to get an array of Request
objects or fromRequestId()
to get a single Request
object. This function retrieves the Request
s stored in IPFS and queries on-chain events to determine the balances paid so far. Finally, call getData()
on each Request
to get the request contents.
A form for creating invoices in Request Network
To install the component, use npm:
Configure the Create Invoice Form web component by creating a reference to it, setting its properties, and passing the reference as a prop.
Initialize the RequestNetwork
object using an Ethers Signer
or Viem WalletClient
.
Use the config object to pass additional configuration options. Please replace the builderId
with your own, arbitrarily chosen ID. This is used to track how many invoices your application creates.
Use a context provider to reinitialize the Request Network instance when the wallet changes.
A list of custom currencies to extend the default currency list.
Specify types to avoid TypeScript errors.
A dashboard for viewing and paying invoices in Request Network
To install the component, use npm:
Follow the instructions below to add the Invoice Dashboard to a React or Next.js app.
Configure the invoice dashboard web component by creating a reference to it, setting its properties, and passing the reference as a prop.
Initialize the RequestNetwork
object using an Ethers Signer
or Viem WalletClient
.
Use the config object to pass additional configuration options. Please replace the builderId
with your own, arbitrarily chosen ID. This is used to track how many invoices your application creates.
Use a context provider to reinitialize the Request Network instance when the wallet changes.
A list of custom currencies to extend the default currency list.
Specify types to avoid TypeScript errors.
After a request is created, it can be updated:
Feature exists. More docs coming soon...
A dialog box for granting third-party access to an encrypted invoice created via Request Finance
The Request Finance Add Stakeholder widget provides a dialog box for end-users to grant third-party access to one of their encrypted payment requests created via Request Finance. Then, under the hood, Request Finance calls request.addStakeholders()
to add the third party as a stakeholder to the encrypted payment request.
Try it out
Try it out
Demo Video
View Source
Gnosis Gateway
real
Gnosis Gateway (deprecated alias)
real
Sepolia Gateway
test
0.3.0
Very similar to wagmi, but without using hooks. Construct your own WalletClient
object.
Ethers.js Adapters copied from
The Create Invoice Form allows end-users to create an invoice using the Request Network. It is built using but compiled to a , making it usable in any web environment, regardless of the framework.
Follow the instructions below to add the Create Invoice Form to a React or Next.js app. For a video explaining how to integrate, see the
An Invoicing Template for creating, viewing, and paying requests in Request Network. Built using the and Web Components.
Invoices can be denominated in the following fiat currencies, in addition to the listed above.
The Invoice Dashboard component allows end-users to view and pay an invoice in Request Network. It is built using but compiled to a , making it usable in any web environment, regardless of the framework.
The add-stakeholder
component allows Builders to quickly integrate the widget into their applications.
The template comes in the form of a and a native component, provided by the package. The Web Component can be used anywhere including, but not limited to, React, Next.js, Vue, Svelte, or as a browser script.
The Payment Widget allows builders to accept crypto payments on their websites with minimal integration. It is built using but complied into a , making it usable in any web environment, regardless of the framework.
config
IConfig
Additional configuration parameters
config.builderId
string
Unique builder ID, arbitrarily chosen, used for metrics
config.dashboardLink
string
Path to dashboard page
config.logo
string
Path to logo file
config.colors.main
string
Hex color code for primary buttons and labels
config.colors.secondary
string
Hex color code for for borders and accents
requestNetwork
The RequestNetwork instance
wagmiConfig
WagmiConfig
Wallet connector config
currencies
Currency[]
A list of custom currencies
Next.js
Ethereum
ETH, USDC, USDT, DAI, REQ
Polygon
MATIC, USDC, USDT, DAI
BNB Chain
DAI, BUSD
Gnosis
USDC
Optimism
ETH, USDC, USDT, DAI
Base
ETH, USDC
Sepolia
ETH, USDC, USDT, FAU
config
IConfig
Additional configuration parameters
config.builderId
string
Unique builder ID, arbitrarily chosen, used for metrics
config.dashboardLink
string
Path to dashboard page
config.logo
string
Path to logo file
config.colors.main
string
Color used for primary buttons and labels
config.colors.secondary
string
Color used for borders and accents
requestNetwork
The RequestNetwork instance
wagmiConfig
WagmiConfig
Wallet connector config
currencies
Currency[]
A list of custom currencies
accept
accept a request, indicating that it will be paid
payer
cancel
cancel a request
payee, payer
reduceExpectedAmount
reduce the expected amount
payee
increaseExpectedAmount
increase the expected amount
payer
addStakeholders
grant 1 or more third parties access to view an encrypted request
payee, payer, third party
amountInUSD
number
The total of the purchase in US Dollars
sellerAddress
string
Address that would accept the payments
supportedCurrencies
string[]
An array of currency IDS that are supported by the seller
sellerInfo.logo
string
(Optional) Seller logo
sellerInfo
SellerInfo
(Optional) Information about the seller
sellerInfo.name
string
(Optional) Seller name
productInfo
ProductInfo
(Optional) Information about the product
productInfo.name
string
(Optional) Name of the product
productInfo.description
string
(Optional) Description of the product
productInfo.image
string
(Optional) Product image
persistRequest
boolean
(Optional) Defaults to true, when set to false the request data is not persisted to the blockchain
showRNBranding
boolean
(Optional) Defaults to true, when set to false the "Powered by Request Network" banner is hidden
builderId
string
(Optional) An ID added to request to identify request created by builder
onPaymentSuccess
(request) => void
(Optional) Event that returns the Request data once the payment is successful.
onError
(error) => void
(Optional) Event that returns the error when something goes wrong.
Get the status of a payment request
The payment reference of the request
0xb3581f0b0f74cc61
API key for authentication
Get the calldata needed to pay a request. Returns different transaction structures for native currency vs ERC20 token payments.
The payment reference of the request
0xb3581f0b0f74cc61
API key for authentication
Logout and clear session
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Active session cookie (automatically included after login)
session_token=<your-session-token>
No body
Get all API keys for your platform
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Active session cookie (automatically included after login)
session_token=<your-session-token>
Enable or disable an API key
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
API key ID
01JKZNG0N658N6A2R45MPEEP4F
Active session cookie (automatically included after login)
session_token=<your-session-token>
No body
Permanently delete an API key
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
API key ID
01JKZNG0N658N6A2R45MPEEP4F
Active session cookie (automatically included after login)
session_token=<your-session-token>
No body
Get all webhooks for your platform
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Active session cookie (automatically included after login)
session_token=<your-session-token>
Enable or disable a webhook
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Webhook ID
01JMMA4WWFT0VAPBAS0GYH70GQ
Active session cookie (automatically included after login)
session_token=<your-session-token>
No body
Permanently delete a webhook
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Webhook ID
01JMMA4WWFT0VAPBAS0GYH70GQ
Active session cookie (automatically included after login)
session_token=<your-session-token>
No body
In the Reference-based Payment Networks, Payments are linked to Requests via a paymentReference
which is derived from the requestId
and payment recipient address.
This paymentReference
consists of the last 8 bytes of a salted hash of the requestId
and payment recipient address, concatenated :
requestId
is the id of the request
salt
is a random number with at least 8 bytes of randomness. It must be unique to each request
address
is the payment address for payments, the refund address for refunds
lowercase()
transforms all characters to lowercase
hash()
is a keccak256 hash function
last8Bytes()
take the last 8 bytes
Use the PaymentReferenceCalculator to calculate the payment reference.
Request Network allows you to support any currency. Head out to the currency package to see how we identify and manage currencies in the CurrencyManager
. You don't need to add new currencies in this repository.
Instead, when instanciating the CurrencyManager
, you can feed it with a list of supported currencies for your dapp:
To implement new types of currencies (aside fiat, BTC, ETH, ERC20), head towards payment networks.
In a previous chapter, we used the signature providers @requestnetwork/web3-signature
and @requestnetwork/epk-signature
(this one is made for test purpose). But, if you are not using web3, you need to inject your own signature mechanism to the request client. This is fairly simple, you need to implement a class following this interface: (see on github)
For example, your own package to sign needs an ethereum address and return the signature as a hexadecimal string:
Your signature provider would look like:
Now you can inject it into the request client:
## Example 2
For example, your own package to sign needs an internal identifier and return the signature as a Buffer:
Your signature provider would look like:
Now you can inject it into the request client:
Create a new payment request
API key for authentication
The wallet address of the payer
The wallet address of the payee
The payable amount of the invoice, in human readable format
Invoice Currency ID, from the Request Network Token List e.g: USD
Payment currency ID, from the Request Network Token List e.g: ETH-sepolia-sepolia
The recurrence of the invoice
Initiate a payment without having to create a request first
API key for authentication
The wallet address of the payee
The payable amount of the invoice, in human readable format
Invoice Currency ID, from the Request Network Token List e.g: USD
Payment currency ID, from the Request Network Token List e.g: ETH-sepolia-sepolia
Create a new API key for your platform
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Active session cookie (automatically included after login)
session_token=<your-session-token>
API key label
Create a new webhook endpoint for receiving notifications
Requires session_token cookie. If you've logged in, this cookie is already set in your browser.
Active session cookie (automatically included after login)
session_token=<your-session-token>
Webhook URL
A "conversion" request is one that is denominated in one currency but paid in another currency. This is facilitated by on-chain price feeds provided by oracles. The typical use case is to denominate a request in fiat like USD and pay the request in stablecoins like USDC or DAI.
The content of an encrypted request can be shared to additional third parties using the addStakeholder
feature.
Calling request.addStakeholder()
allows any stakeholder of a request to add the public key of a third party as a stakeholder on a request. The third party can now read the content of the request.
Feature exists. Docs coming soon...
ERC20 Payments
Native Token Payments
Conversion Payments
rnf_invoice format 0.3.0
Configure Logo and Colors
Inject your own custom currency list
Download Invoice as PDF
0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C
0x5f821c20947ff9be22e823edc5b3c709b33121b3
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
0x7DfD5955a1Ed6Bf74ccF8e24FF53E0a9A7e9F477
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xe72Ecea44b6d8B2b3cf5171214D9730E86213cA2
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x3b4837C9F4A606b71e61FD56Db6241781194df92
0xcE80D17d38cfee8E5E6c682F7712bfb5A04Ae912
0xD5933C74414ce80D9d7082cc89FBAdcfF4751fAF
0xC5519f3fcECC8EC85caaF8836563dEe9a00080f9
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
0x88Ecc15fDC2985A7926171B938BB2Cd808A5ba40
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
0x26d4912fA5aC84F185843E19eeEdcc47f4Cc9F1a
0x67818703c92580c0e106e401F253E8A410A66f8B
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xaD61121DAfAAe495095Cd466022b519Cb7503a4E
0xc861aE0Cd70b73b0C8F1D62Fa669E6D1d7
D7e0aB
0x05e94CDdd14E0b18317AE21BAFAEC24156BdB7C9
0xB5E53C3d145Cbaa61C7028736A1fF0bC6817A4c5
0xf8cACE7EE4c03Eb4f225434B0709527938D365b4
0x7c285b9F2dA5E2c10feA25C00Ce1aCB107F85475
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
N/A
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
0x26d4912fA5aC84F185843E19eeEdcc47f4Cc9F1a
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0x1550A8C4F4E5afC67Ea07e8ac590fdcAdB4bBfb1
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x80D1EE67ffAf7047d3E6EbF7317cF0eAd63FFc78
N/A
0xf8cACE7EE4c03Eb4f225434B0709527938D365b4
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xA5186dec7dC1ec85B42A3cd2Dc8289e248530B07
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
0x4D417AA04DBb207201a794E5B7381B3cde815281
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x1892196E80C4c17ea5100Da765Ab48c1fE2Fb814
0xc31323ea7513799e1e112Dc15a05d5b600Cc357e
0xd9C3889eB8DA6ce449bfFE3cd194d08A436e96f2
0x090D3583e3f5953e2CC758b146f4Ae11f8224ad7
N/A
0x1aF3f22685AcdDc788B3730ed415912d8f654420
0x78384dB9674109A3Edf9F2814eFF4B6fc25D816A
0x8296D56321cf207925a7804E5A8E3F579838e6Ad
0xEdfD8386d5DE52072B4Ad8dC69BBD0bB89f9A1fb
0xFbBd0854048a8A75a8823c230e673F8331140483
N/A
0xAdc0001eA67Ab36D5321612c6b500572704fFF20
0x3dF89c727eaDF67eeD7b4d09EC4F2b41f8Dec2ca
0x6e28Cc56C2E64c9250f39Cb134686C87dB196532
N/A
0xE9A708db0D30409e39810C44cA240fd15cdA9b1a
N/A
N/A
0x0C41700ee1B363DB2ebC1a985f65cAf6eC4b1023
N/A
N/A
N/A
N/A
N/A
0x9Fd503e723e5EfcCde3183632b443fFF49E68715
N/A
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xf0f49873C50765239F6f9534Ba13c4fe16eD5f2E
0x3E3B04e1bF170522a5c5DDE628C4d365c0342239
0x3b4837C9F4A606b71e61FD56Db6241781194df92
N/A
0x4D417AA04DBb207201a794E5B7381B3cde815281
0x05D782aD6D6556179A6387Ff1D2fA104FD5c515a
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
0x937Db37ffb67083242fbC6AdD472146bF10E01ec
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xf0f49873C50765239F6f9534Ba13c4fe16eD5f2E
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x3b4837C9F4A606b71e61FD56Db6241781194df92
0xd6C04C5d0e561D94B15622e770045776D4ce3739
0x4D417AA04DBb207201a794E5B7381B3cde815281
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xbbd9c5D112343A4Aa2bc194245760CaeeaF118Be
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
0x4D417AA04DBb207201a794E5B7381B3cde815281
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
N/A
N/A
N/A
N/A
N/A
0xf0f49873C50765239F6f9534Ba13c4fe16eD5f2E
N/A
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
N/A
0xEEc4790306C43DC00cebbE4D0c36Fadf8634B533
0x2171a0dc12a9E5b1659feF2BB20E54c84Fa7dB0C
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xf0f49873C50765239F6f9534Ba13c4fe16eD5f2E
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
0x8d996a0591a0F9eB65301592C88303e07Ec481db
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x612cF8a29A9c8965a5fE512b7463165861c07EAa
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xf0f49873C50765239F6f9534Ba13c4fe16eD5f2E
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
N/A
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
N/A
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
0x88Ecc15fDC2985A7926171B938BB2Cd808A5ba40
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
N/A
0x02561967c48e87cfB079763F3BEf6424A5A166A7
N/A
N/A
N/A
N/A
N/A
N/A
N/A
0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
N/A
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0xA5186dec7dC1ec85B42A3cd2Dc8289e248530B07
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x1d6B06C6f7adFd9314BD4C58a6D306261113a1D4
N/A
0x4D417AA04DBb207201a794E5B7381B3cde815281
0x0818Ad7016138f0A40DFAe30F64a923c2A8F61bA
0xee07ef5B414955188d2A9fF50bdCE784A49031Fc
N/A
0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8
0x322F0037d272E980984F89E94Aae43BD0FC065E6
0x4BA012eae4d64da79Bd6bcdBa366803fCe701A4C
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
N/A
N/A
N/A
N/A
N/A
N/A
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
N/A
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
0x26d4912fA5aC84F185843E19eeEdcc47f4Cc9F1a
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
0x1550A8C4F4E5afC67Ea07e8ac590fdcAdB4bBfb1
0x7Ebf48a26253810629C191b56C3212Fd0D211c26
0x80D1EE67ffAf7047d3E6EbF7317cF0eAd63FFc78
N/A
N/A
N/A
0xAe23992483FeDA6E718a808Ce824f6864F13B64B
N/A
0xe9cbD1Aa5496628F4302426693Ad63006C56959F
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
0x26d4912fA5aC84F185843E19eeEdcc47f4Cc9F1a
0x3cF63891928B8CeebB81C95426600a18cd59C03f
0x626e6E3dac82205EA5FfB526092F4DCe525E46a9
N/A
N/A
N/A
N/A
N/A
N/A
0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE
0x88Ecc15fDC2985A7926171B938BB2Cd808A5ba40
0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687
0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e
N/A
N/A
N/A
N/A
N/A
N/A
N/A
0xf8cACE7EE4c03Eb4f225434B0709527938D365b4
N/A
pay.reqnetwork.near
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
pay.reqnetwork.testnet
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
0x268C146Afb4790902Ee26A6D2d3aff968623Ec80
0x2256938E8225a998C498bf86B43c1768EE14b90B
0x899ddc13d5DBc252916ba2D70928518f3C836ba1
0xd6c085A4D14e9e171f4aF58F7F48bd81173f167E
0xa9cEaA10c12dcB33BAbC2D779e37732311504652
0x24a66afda3666fb0202f439708ece45c8121a9bb
DaiBasedREQBurner
0x2CFa65DcB34311293c6a52F1D7BEB8f4E31E5117
RequestToken
0x8f8221afbb33998d8584a2b05749ba73c37a938a
Burner (Deprecated)
0x7b3C4D90e8AF6030d66c07F8F815f9505E379d6F
lockForREQBurn
0x2171a0dc12a9E5b1659feF2BB20E54c84Fa7dB0C
This document outlines how to encrypt and decrypt requests using Lit Protocol. Encryption and decryption are performed using the end-user's wallet signatures, ensuring only they can access the data. Neither Request Network nor Lit Protocol can access the data without consent from the user.
This allows the end-user to own their data without requiring them to know about or manage their public key, as is the case when they Encrypt with an Ethereum private key.
Encryption with Lit Protocol supports the Add Stakeholder feature for adding view access to a 3rd party other than the payee or payer.
The LitCipherProvider is suitable for both frontend and backend use.
This implementation utilizes a two-step encryption process to secure sensitive data within requests:
Symmetric Encryption: The data is first encrypted using a randomly generated symmetric key (e.g., AES-256). This provides efficient encryption for larger data payloads.
Asymmetric Encryption with Lit Protocol: The symmetric key is then encrypted using Lit Protocol's decentralized key management network. Only authorized parties (payer and payee) can access the symmetric key and decrypt the data.
Ease-of-use: Encrypt using a signature instead of a public key.
Efficiency: Symmetric encryption is efficient for large data, while Lit Protocol secures the key.
Decentralized Access Control: Lit Protocol ensures that only authorized parties can decrypt the data.
The system consists of three main components:
Request Network: Handles the creation, storage, and lifecycle of payment requests on the blockchain.
Lit Protocol: Provides a decentralized key management network and encryption capabilities.
Wallet Addresses: Used as the primary identifiers for access control in Lit Protocol.
Request Creation: The payer creates a request object using the Request Network SDK.
Symmetric Key Generation: A unique symmetric key is randomly generated.
Data Encryption: The payee and payer encrypt the sensitive data within the request using the generated symmetric key.
Encrypt Symmetric Key with Lit:
Define Access Control Conditions: The payee and payer define access control conditions using Lit Actions, specifying that only the Ethereum addresses of the payer and payee can decrypt the symmetric key.
Encrypt with Lit: The payee and payer encrypt the symmetric key using Lit's encryptString
function, leveraging their wallet to sign the encryption.
Store Encrypted Data: The payee and payer store the following on the Request Network:
Encrypted request data
Lit access control conditions
Encrypted symmetric key
Retrieve Request: The payer and payee retrieve the following request data from the Request Network:
Encrypted request data
Lit access control conditions
Encrypted symmetric key
Decrypt Symmetric Key with Lit: The payer and payee use Lit's decryptString
function with their wallet to decrypt the encrypted symmetric key. Lit Protocol verifies the payer's and payee's addresses against access control conditions. If authorized, the symmetric key is decrypted.
Decrypt Data: The payer and payee use the decrypted symmetric key to decrypt the sensitive data.
The wallet address must be included in the original encryption parameters
Session signatures must be valid
Decryption must be enabled
The Lit Protocol client must be connected
Request payments can be detected easily, thanks to the integration of The Graph.
Other methods are available to detect a payment by simply watching the Proxy Smart Contract used for payment. Payment transactions include a paymentReference
that links them to the request.
Get the payment routes for a request
The payment reference of the request
0xb3581f0b0f74cc61
The wallet address of the payer
0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7
API key for authentication
Get the calldata needed to pay a request. For cross-chain payments, returns a payment intent that needs to be signed. For same-chain payments, returns transaction calldata
The payment reference of the request
0xb3581f0b0f74cc61
The wallet address of the payer , required for cross chain payment, optional for regular payments
0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7
The source chain of the cross chain payment
The source token of the cross chain payment
API key for authentication
View on NPM
Demo Video
View Source
Try it out
Demo Video
Integration Video
View on NPM
View Source
Try it out
Demo Video
Integration Video
View on NPM
View Source
Try it out
Demo Video
Integration Video
View on NPM
View Source
Our indexes Request's proxy smart contracts and allow you to query payment data easily.
Send a payment intent
The payment intent ID
01JNZYZPK7B4YBPD44TM72NDNJ
API key for authentication
The signed payment intent data.
The EIP2612 gasless token approval data that allows Permit2 to access user tokens
No body
Manipulating private keys must be done with care. Losing them can lead to a loss of data, privacy or non-repudiation safety!
A request can be encrypted to make its details private to selected stakeholders. In this guide, we won't explain how encryption is managed under the hood. We will mention encryption or decryption of requests with payers and payees keys. Although in practice, we will use an intermediate symmetric key. See more details on github.
The transaction layer manages the encryption, see more details on the Request Protocol section.
To manipulate encrypted requests you need a CipherProvider (recommended) or DecryptionProvider (deprecated). Both of them require direct access to the private key. They're best suited for backends.
EthereumPrivateKeyCipherProvider: Provides both encryption and decryption utilities.
EthereumPrivateKeyDecryptionProvider (deprecated) provides only decryption utilities.
See on Github.
Then you can create an encrypted request:
Note: You must give at least one encryption key you can decrypt with the decryption provider. Otherwise, an error will be triggered after the creation.
EthereumPrivateKeyDecryptionProvider is deprecated in favor of EthereumPrivateKeyCipherProvider
Let's step back for a second: the requester sent a request that he encrypted with the payer's public key, as well as with his own, to retrieve it later. This is an essential and typical example, but a request can be encrypted with many keys to give access to its status and details.
If the decryption provider knows a private key matching one of the keys used at the creation, it can decrypt it. Like a clear request you can get it from its request id.
Like a clear request, you can update it if the decryption provider is instantiated with a matching private key.
The Request Network SDK supports Hinkal Private Payments using ERC-20 tokens. Hinkal is a middleware and suite of smart contracts on EVM-compatible chains that leverage zero-knowledge proofs and private addresses to facilitate compliant and private transactions.
Each public address has exactly one Hinkal private address.
The @requestnetwork/payment-processor
package provides functions to:
Pay a request from a Hinkal private address to a public address: such that the payment sender's public address never appears on-chain.
Deposit to a Hinkal private address from a public address: such that the payment recipient's public address never appears on-chain. Callers can choose to deposit to their own private address or someone else's private address.
Privacy: Obfuscates payer address when paying a request.
To use Hinkal Private Payments, install the necessary package:
To deposit funds to a Hinkal private address from a public address, where only the payment recipient's address is obfuscated, use the sendToHinkalShieldedAddressFromPublic()
function.
Deposit to own Hinkal shielded address: omit the recipientInfo
argument
Deposit to someone else's Hinkal shielded address: set recipientInfo
to the shielded address of the payment recipient.
As a result, any client-side application integrating the Hinkal SDK must adjust its Content-Security-Policy to allow the wasm-unsafe-eval
directive under the script-src
setting. This configuration ensures that the cryptographic processes can execute properly.
Paying a request where the payment recipient address is a Hinkal private address is not supported because the Request Network payment proxy smart contracts can only send funds to public addresses. Consider using instead.
Compliance: Ensures transactions adhere to regulatory requirements. See for details
See for a list of chains on which Hinkal Private Payments are supported.
To pay a request from a Hinkal private address to a public address, where only the payment sender's address is obfuscated, use the `payErc20FeeProxyRequestFromHinkalShieldedAddress()`
function. Ensure the payment sender's Hinkal private address has a positive balance using
Strongly consider using to keep the request contents private, including the payer and payee identity addresses, when paying requests from a Hinkal private address. Revealing the payer and payee identity addresses increases the likelihood of un-shielding the payment sender's address via on-chain analysis.
See for how to instantiate a RequestNetwork
and Signer
See for how to instantiate a Signer
The Hinkal SDK depends on , a powerful library that enables local zero-knowledge proving in browser and Node.js environments. Snarkjs leverages to perform complex cryptographic computations efficiently.
See for more details.
For more details about Hinkal Private Payments, refer to on GitHub.
The Request Network Escrow isn't a separate payment network. Rather, it builds on top of the ERC20_FEE_PROXY_CONTRACT
payment network.
Using the request-client.js
package, the payer
creates a request with the ERC20_FEE_PROXY_CONTRACT
payment network.
Using the payment-processor
package, payer
:
Approves the escrow contract using approveErc20ForEscrow()
Pays the escrow contract using payEscrow()
Waits until the work is complete
Pays the payee from the Escrow contract using payRequestFromEscrow()
These steps are shown by our unit tests:
The imports you will need:
In this example, we will use the Gnosis multisig. Here is its partial abi:
Pay a series of requests with a stream of ERC777 Super Tokens from Superfluid.
The first request of a series is very similar to payment-network-erc20-fee-proxy, it defines the salt
, paymentAddress
and requestId
to compute the paymentReference
used for the whole series.
Other requests must define a previousRequestId
and cannot redefine any of the payment properties (paymentAddress
, feeAddress
or salt
).
Multiple requests can be paid with the same stream, typically recurring requests of fixed amounts paid continuously. A group of requests payable with the same stream are called a request series, they must all have the same currency.
For additional details, see the payment-network-erc777-stream-0.1.0 specification
To create a streaming request, Create a request like normal, but set the paymentNetwork
parameter to the ERC777_STREAM
payment network.
See Github for tests showing usage.
This guide demonstrates how to integrate Request Network into a React Native application using Expo. Due to the differences between Node.js and React Native environments, several polyfills and configurations are necessary to make Request Network work properly. Following this guide will set up your Expo project to use Request Network, handle polyfills for missing modules, and ensure smooth integration. A full Github repository with Request Network support can be found here.
After creating a new Expo project, install the necessary dependencies:
1- Create a new file named index.js
in the root of your project
2- Add the following content to index.js
3- Create a file named cryptoPolyfill.js
in the root of your project
4- Add the following content to cryptoPolyfill.js
5- Create / Update metro.config.js
to use the custom polyfills
6- Update package.json
to set the main entry point to index.js
7- Ensure that app.json
file includes the correct entry point
We've created a custom crypto polyfill (cryptoPolyfill.js
) to provide the necessary cryptographic functions. This polyfill uses tweetnacl
and node-forge
libraries to implement various cryptographic operations.
Why tweetnacl
and node-forge
?
tweetnacl
: It's a fast, secure, and easy-to-use cryptography library. It provides a pure JavaScript implementation of the NaCl cryptography library, which is particularly useful for generating random bytes, essential for cryptographic operations.
node-forge
: It provides a comprehensive set of cryptographic tools and utilities. It implements various cryptographic algorithms and protocols that are not natively available in React Native. It's used in our polyfill for operations like hashing, cipher creation, and PBKDF2 key derivation.
Using these libraries allows us to implement a more complete set of cryptographic functions that closely mimic the Node.js crypto module, which is not available in React Native.
Ensure you're using compatible versions of React Native and Expo.
The crypto polyfill may not cover all use cases. Test thoroughly and adjust as needed.
Be cautious when handling private keys. Never expose them in your code or version control.
The example code uses environment variables for private keys. Ensure you set these up correctly and securely.
Constructor
The Request Network client
The following command creates a new Request Client instance and configures it to :
Connect to the Gnosis Request Node Gateway maintained by the Request Network Foundation.
Use the web3-signature package to create requests using a web3 wallet like Metamask.
To create mock storage requests, where the request is stored in memory on the local machine and cleared as soon as the script is finished running, set the useMockStorage
argument to true
when instantiating the RequestNetwork
object.
The Request Network client.
nodeConnectionConfig
Axios configurations
signatureProvider
Required to sign and create requests
decryptionProvider
Required to retrieve encrypted requests
httpConfig
Options for HTTP transport (timeout, delay, retry, etc.)
paymentOptions
Payment detection options
useMockStorage
boolean
Store ephemeral requests in local memory
currencies
CurrencyInput[]
Custom currency list
currencyManager
ICurrencyManager
Custom currency manager (will override currencies
). A Currency manager handles a list of currencies and provides utility to retrieve and change format
baseUrl
string
Request Node URL
Many other properties...
Sign using a private key inside of a wallet
Sign using a private key outside of a wallet
Decrypt using a private key outside of a wallet
requestClientVersionHeader
string
Name of the header containing the client version
httpRequestMaxRetry
number
Maximum number of retries to attempt when http requests to the Node fail
httpRequestRetryDelay
number
Delay between retry in ms
httpRequestExponentialBackoffDelay
number
Exponential backoff delay in ms when requests to the Node fail
httpRequestMaxExponentialBackoffDelay
number
Maximum exponential backoff delay in ms when requests to the Node fail
getConfirmationMaxRetry
number
Maximum number of retries to get the confirmation of a persistTransaction
getConfirmationRetryDelay
number
Delay between retry in ms to get the confirmation of a persistTransaction
getConfirmationExponentialBackoffDelay
number
Exponential backoff delay in ms to get the confirmation of a persistTransaction
getConfirmationMaxExponentialBackoffDelay
number
Maximum exponential backoff delay in ms to get the confirmation of a persistTransaction
getConfirmationDeferDelay
number
Delay to wait in ms before trying for the first time to get the confirmation of a persistTransaction
bitcoinDetectionProvider
IBitcoinDetectionProvider
Override default bitcoin payment detection
explorerApiKeys
Map<ChainName, string>
Override explorer API keys
getSubgraphClient
function(ChainName)
Override subgraph payment detection
getRpcProvider
function(ChainName)
Override RPC node provider
Create an unencrypted request
_createEncryptedRequest()
Create an encrypted request. Docs coming soon...
Compute a request ID without actually creating a request
Retrieve a request from a requestId
Retrieve an array of requests from an Identity
Retrieve an array of requests from a topic
Retrieve an array of requests from an Identity
identity
Identity type and value
updatedBetween
Start time and end time
Object
Options
Promise<Request[]>
from
number (Unix timestamp)
Start time
to
number (Unix timestamp)
End time
disablePaymentDetection
boolean
Disable payment detection
disableEvents
boolean
Disable events
parameters
Object used to create a new request
signerIdentity
Identity of the signer
Refresh the request data and balance
requestAndMeta
IReturnGetRequestFromId
The value returned by getRequestFromId()
Promise<IRequestDataWithEvents>
Promise<>
Promise<>
signerIdentity
The value returned by getRequestFromId()
refundInformation
any
Depends on the payment network
Retrieve an array of requests from a topic
topic
string
Topic string
updatedBetween
Start time and end time
Object
Options
Promise<Request[]>
from
number (Unix timestamp)
Start time
to
number (Unix timestamp)
End time
disablePaymentDetection
boolean
Disables payment detection
disableEvents
boolean
Disabled events
An object used to interact with requests. Returned by createRequest() and _createEncryptedRequest()
requestId
string
The ID of the request. Hash derived from the request contents. Stored alongside the request contents so can be used to look up a request.
Wait for request to be persisted and indexed
Unwrap the request contents
Refresh the request data and balance
Cancel a request
Accept a request
Increase the expected amount
Reduce the expected amount
Others...
Other features exist. Docs coming soon...
signerIdentity
The value returned by getRequestFromId()
refundInformation
any
Depends on the payment network
In-memory requests allow for creating and managing requests without immediately persisting them to storage. This enables faster payment workflows and deferred persistence.
Faster payment flow: In-memory requests are helpful when payment is the priority, such as in e-commerce cases. In this scenario, the request is a receipt rather than an invoice.
Deferred Persistence: With in-memory requests, a request can be created on the front end with a user's signature and passed on to the backend for persistence.
The flow of creating and paying an in-memory request is similar to a regular request with the following key differences:
Create an in-memory request by passing the argument skipPeristence: true
when instantiating the RequestNetwork
instance.
An in-memory request is not persisted immediately like normal requests. Instead, it is stored in memory on the device where it was created. It can be persisted at a later time using the persistTransaction()
function.
An in-memory request has the inMemoryInfo
property.
Avoid calling getData()
on an in-memory request because it will fail silently by returning an empty EventEmitter
object.
Retrieving an in-memory request with requestClient.fromRequestId()
will fail because the request has not been persisted yet so it is not possible to read it from the Request Node.
Promise<>
deltaAmount
number | string
The amount by which to reduce the expected amount
signerIdentity
The value returned by getRequestFromId()
paymentInformation
any
Depends on the payment network
Compute the payment reference, the last 8 bytes of a salted hash of the request ID.
The payment reference is the parameter that ties the request to events emitted by on-chain payments via Request Network payment smart contracts.
requestId
string
The ID of the request
salt
string
The salt of the request
address
string
Payment recipient address
string
An identity object that is used to uniquely identify a stakeholder in a request. Today, a stakeholder's IIdentity
is expressed as an Ethereum address, but it is conceivable that future implementations may include alternative identity formats, perhaps W3C DIDs.
Examples of IIdentity
are: payee, payer, signer, creator, and any 3rd party that can view an encrypted request's contents.
The payee
identity and payer
identity are NOT necessarily the same as the payment recipient (paymentAddress
in the PaymentNetworkCreateParameters) or the payment sender (from
address in the payment-subgraph). Conceptually, the payee
and payer
identities are used only for notifications and access control, NOT payment routing.
ETHEREUM_ADDRESS
'ethereumAddress'
Externally owned account (EOA)
ETHEREUM_SMART_CONTRACT
'ethereumSmartContract'
Smart contract account. Don't use this.
It is not possible to create or update a request using an IIdentity
of this type. This type was added to support creating/updating requests using multisig wallets via EIP-1271 but this feature has not yet been implemented.
type
Identity type
value
string
Identity address
Promise<>
Promise<>
The request contents. Returned by , and many other methods.
deltaAmount
number | string
The amount by which to increase the expected amount
signerIdentity
The value returned by getRequestFromId()
refundInformation
any
Depends on the payment network
on()
Event subscriber
emit()
Event emitter
currency
string
The currency in which the request is denominated.
meta
IReturnMeta
Metadata from the layer below (transaction manager), including ignored actions, if any.
balance
The balance object
contentData
object
Arbitrary content data. Consider using rnf_invoice v0.0.3 from @requestnetwork/data-format package.
currencyInfo
Additional info about the currency in which the request is denominated: type, value, and network
pending
IPendingRequest
Shows recently submitted request contents that have not yet been persisted and indexed. Call waitForConfirmation().
version
string
The Request Network protocol version
requestId
string
The ID of the request
creator
Identity of the request creator
state
The state of the request
expectedAmount
number | string
The requested amount
payee
Identity of the payee. Not necessarily payment recipient address.
payer
Identity of the payer. Not necessarily payment sender address.
extensions
IExtensionStates
The state of the extensions
extensionsData
any[]
Extensions raw data
events
IEvent[]
Historical list of actions that have occurred on the request (create, accept, cancel, etc.)
timestamp
number (Unix timestamp)
Timestamp when request is created. User provided, so this is an agreement between payee and payer.
nonce
number
Optional nonce to differentiate identical requests.
PENDING
'pending'
CREATED
'created'
ACCEPTED
'accepted'
CANCELED
'canceled'
balance
string
The sum of all payments and refunds related to this request. If this is >= expectedAmount, then the request is paid in full.
events
Array of payment events
error
IBalanceError
Error occured while retrieiving payment events and calculating the balance
escrowEvents
EscrowNetworkEvent[]
Array of escrow events
amount
string
The amount of the detected payment
parameters
TEventParameters
Depends on the Payment Network ID
type
Currency type
value
string
Depends on type.
ERC20 contract address '0x123'
Fiat symbol 'USD'
Native symbol 'ETH'
network
ChainName
The chain on which the currency exists
ETH
'ETH'
Native (ETH, XDAI, etc.)
BTC
'BTC'
Bitcoin
ISO4217
'ISO4217'
Fiat (USD, EUR, etc.)
ERC20
'ERC20'
Non-native fungible currency (USDC, REQ, etc.)
ERC777
'ERC777'
Streamable fungible currency (USDCx, REQx, etc.)
Retrieve a request from a request ID
requestId
string
The ID of the request
Object
Options
Promise<Request>
disablePaymentDetection
boolean
Disable payment detection
disableEvents
boolean
Disable events
The Single Request Forwarder is a smart contract solution that enables integration with Request Network's payment system without modifying existing smart contracts.
Universal Compatibility: Works with any system that can make standard crypto transfers.
No Code Changes: Integrate with Request Network without modifying existing smart contracts.
Exchange Friendly: Enable payments from centralized exchanges.
Request: Create a request in the Request Network protocol
Deploy: Deploy a unique Single Request Forwarder for your request
Pay: The Payer sends funds to the Single Request Forwarder
Complete: The Single Request Forwarder forwards the payment to the Payee and emits an event to enable payment detection.
To deploy a Single Request Forwarder, call deploySingleRequestForwarder()
which takes in the following arguments:
requestData
: the data of the created request
signer
: An Ethers v5 Signer to sign the deployment transaction
The deploySingleRequestForwarder()
function automatically deploys the correct type of Single Request Forwarder based on the Request data passed into the function; either an Ethereum Single Request Forwarder or ERC20 Single Request Forwarder
It returns
Single Request Forwarder Address
To pay a request through a Single Request Forwarder using the Request Network SDK, call payRequestWithSingleRequestForwarder()
which takes in the following arguments:
singleRequestForwarderAddress
: the address of the SRP deployed in the previous step.
signer
: A wallet signer who is making the transfer of funds.
amount
: Amount of funds that need to be transferred.
Once we have the Single Request Forwarder address, we can pay by directly transferring the money to the address itself. The Single Request Forwarder will automatically process the payment. For ERC20 payments, the process of paying with a Single Request Forwarder happens in two steps:
Transferring the tokens to the Single Request Forwarder
Make a zero-value transaction to the Single Request Forwarder (i.e. Send 0 ETH to the contract)
Single Use: Each Single Request Forwarder deployment processes payments for a specific request.
Immutable Parameters: Payment details cannot be modified after deployment.
Fund Recovery: Built-in mechanisms to send stuck funds to the payment receiver.
request
The request object
signerOrProvider
ethers.providers.Web3Provider | ethers.Signer = getProvider()
amount
ethers.BigNumberish
The amount to pay. Defaults to the expected amount of the request.
overrides
Omit<ethers.providers.TransactionRequest, 'to' | 'data' | 'value'>
Override transaction settings like baseFee and maxPriorityFee
paymentSettings
Settings for conversion payments
Promise<ethers.ContractTransaction>
This is what ethers returns after submitting a transaction.
currency
ICurrency
The currency in which the payment is made, not the currency in which the request is denominated.
maxToSpend
ethers.BigNumberish
The maximum input currency to spend on conversion payments. Protects the user from rapidly changing exchange rates.
currencyManager
ICurrencyManager
A Currency manager handles a list of currencies and provides utility to retrieve and change format
Function
Pay a request
Constructor
An ethers v5 Provider. See for explanation how to wrap a viem WalletClient to look like an ethers v5 Provider.
Constructor
Sign using a private key inside of a wallet
web3Provider
ethers.Provider
An ethers v5 Provider or viem WalletClient
Decrypt using a private key outside of a wallet
decryptionParameters
Decryption method and private key
method
Decryption method
key
string
Private key
ECIES
'ecies'
Elliptic Curve Integrated Encryption Scheme (ECIES). An asymmetric key cipher.
AES256_CBC
'aes256-cbc'
Advanced Encryption Standard (AES). A symmetric key cipher with keys of length 256 in CBC mode.
AES256_GCM
'aes256-gcm'
Advanced Encryption Standard (AES). A symmetric key cipher with keys of length 256 in GCM mode.
The Request Network SDK is the set of software packages for interacting with the Request Network. The packages can be installed via npm and allow developers to:
Create new requests
Update requests
Pay requests
Retrieve requests
Detecting payments
The Request Node is a software bundle that provides a gateway to the various layers of the Request Network Protocol:
IPFS persists the request content
Smart contracts persist the unique IPFS CID on-chain
The Graph indexes smart contract events
This Request Node acts as a relay server which helps reduce friction and costs for the end user. The user signs the request contents, but the node funds the fees required to persist the contents in the various protocol layers.
The Request Network Foundation operates several Request Nodes which builders can use to quickly test the protocol. However, for production, we advise you to run your own node which can be installed via either npm or docker.
Shown below is a diagram that depicts how the SDK and Node interact with the protocol.
Sign using a private key outside of a wallet
signatureParameter
Signing method and private key
method
Signing method
privateKey
string
Private key
ECDSA
'ecdsa'
"Vanilla" ECDSA
ECDSA_ETHEREUM
'ecdsa-ethereum'
Ethereum ECDSA with the prefix "\x19Ethereum Signed Message:\n"
Rules for how a payment should be processed and detected
A payment network is a set of rules defining how a payment should be processed and detected for a Request. It specifies:
Information required at request creation to enable payment detection
The payment method
The process for determining the balance (amount paid)
They forward the payment to the payment recipient's address.
They emit an event containing the payment amount and the payment reference.
The payment reference is a unique identifier derived from the Request ID and payment recipient address. This derivation happens off-chain, not in the smart contract itself.
It's important to note that the payment recipient's address can be different from the payee's identity address that typically signs to create the request.
The payment proxy smart contracts do not perform error checking. It is the responsibility of the application using the Request Network to craft the payment transaction with the correct amount and payment reference.
A payment subgraph indexes events from the payment proxy smart contracts, enabling efficient payment detection and balance calculation for each request.
Please note that Reference-based payment networks inherit from the declarative payment network. This means that all reference-based requests can also be paid using declarative payments, providing flexibility in payment methods.
This payment network is used for direct ERC20 token payments.
Example of creating a request with an ERC20 Fee Proxy Contract payment network:
This payment network is used for direct ETH (or native token) payments on Ethereum and EVM-compatible chains.
Example of creating a request with an ETH Fee Proxy Contract payment network:
This payment network allows for native token payments with an optional fee mechanism. It's suitable for ETH payments on Ethereum mainnet, or native token payments on other EVM-compatible chains like Polygon's MATIC or Binance Smart Chain's BNB.
This payment network allows for "ERC20 Conversion Payments", where the payment currency is an ERC20 token that is different from the request currency. This is most commonly used to denominate the request in fiat like USD but settle the payment in ERC20 tokens like USDC or USDT. This is useful for accounting because most people use fiat currency as their unit of account.
Key features:
Supports payments in any ERC20 token for requests created in various currencies
Uses on-chain oracles for real-time currency conversion
Includes a fee mechanism similar to the ERC20 Fee Proxy Contract
Example of creating a request with an Any-to-ERC20 Proxy Contract payment network:
In this example, the request is created in USD, but can be paid using DAI (or any other specified ERC20 token). The conversion rate is determined at the time of payment using on-chain oracles.
This payment network allows for "Native Conversion Payments", where the payment currency is ETH (or native token) for requests denominated in other currencies, usually fiat. This is most commonly used to denominate the request in fiat like USD but settle the payment in native tokens like ETH on Ethereum or POL on Polygon PoS. This is useful for accounting because most people use fiat currency as their unit of account.
Key features:
Supports payments in ETH (or native token) for requests created in various currencies
Uses on-chain oracles for real-time currency conversion
Includes a fee mechanism similar to the ETH Fee Proxy Contract
Example of creating a request with an Any-to-ETH Proxy Contract payment network:
In this example, the request is created in USD but can be paid using ETH. The conversion rate is determined at the time of payment using on-chain oracles.
ERC20 Transferable Receivable allows requests to be minted as NFTs that can be transferred or sold. When the payment is processed, the owner of the NFT receives the payment.
Example of creating an ERC20 Transferable Receivable request:
The declarative payment network allows for manual declaration of payments and refunds. It's particularly useful for currencies or payment methods not directly supported by Request Network like traditional finance payment rails, unsupported web3 payment protocols, and unsupported chains like Solana or Tron.
Example of creating a request with a declarative payment network:
The Meta Payment Network allows you to specify multiple potential payment networks for a single request. The payment can be settled by any one of the sub-payment networks.
ERC777 Streaming Payment routes payments through the ERC20 Fee Proxy payment network, allowing for continuous, streaming payments.
Example of creating an ERC777 Streaming Payment request:
These networks require a unique payment recipient address for each request. The balance is computed from all inbound transfers to this address. This method is not recommended due to its limitations and potential for errors.
This network used the call data
field of Ethereum transactions to tag and detect payments. It has been deprecated in favor of the other reference-based payment networks that use payment proxy smart contracts.
These payment networks have been superseded by the ERC20 Fee Proxy and ETH Fee Proxy networks respectively. The only difference is that the ERC20 Proxy and Ethereum Proxy don't include the service fee mechanism. For most use cases, it's recommended to use the Fee Proxy versions with the fee set to 0 if no fee is required.
Advanced payment types are built on top of payment networks and provide additional functionality or flexibility.
The Advanced Payment Types are *not* Payment Networks. You cannot create a request with one of these payment types in the paymentNetwork
property.
Here are some of the advanced payment types available:
Batch payments allow you to pay multiple requests in the same transaction. This is supported for the following payment networks:
ERC20 Fee Proxy
ETH Fee Proxy
Any-to-ERC20 Proxy "ERC20 Conversion Payments"
Any-to-ETH Proxy "ETH Conversion Payments"
ERC20 Proxy networks
Swap-to-Pay payments execute a swap immediately before routing the payment through the ERC20 Fee Proxy payment network.
Swap-to-Conversion is the combination of Conversion and Swap-to-Pay.
Swap-to-Conversion executes a swap in Uniswap V2 immediately before routing the payment through the Any-to-ERC20 Payment Network.
ERC20 Escrow Payment allows for escrow functionality in payments.
The Request Network Escrow lacks arbitration and is susceptible to deadlock in the case of a dispute.
Conversion is different from Swap-to-pay.
In a conversion payment, the request is denominated in currency A, the payer sends currency B and the payee receives currency B.
In a Swap-to-pay payment, the request is denominated in currency A, the payer sends currency B and the payee receives currency A.
They can be combined into Swap-to-Conversion.
In a swap-to-conversion payment, the request is denominated in currency A, the payer sends currency B and the payee receives currency C.
Create an unencrypted request
Request is an open database for any type of payment request - from business invoices to reimbursements between friends. It aims to support products at any scale from startups to large organizations, from the private to the public sector.
The Request Protocol is the core of Request. It's the bottom layer that defines and handles the data of a request and persists it to a distributed ledger to make Request open, trustless, secure, and resilient.
This section is aimed at helping you understand how the protocol is structured, how it works and meets its requirements. It is particularly useful if you want to propose changes or implement them yourself.
The Request Protocol has one fundamental purpose: to persist, on a distributed ledger, data representing requests and to be able to retrieve these data efficiently.
To achieve this, the Request Protocol follows the layered architecture pattern. Each layer is responsible for a specific task and a specific level of abstraction. This layered architecture is highly extensible and hopefully easy to understand.
The protocol is composed of four layers:
Request logic
Transaction
Data Access
Storage
This layered architecture allows package reusability and makes the protocol more upgradeable. For example, our current implementation uses Ethereum and IPFS. Still, suppose Arweave turns out to be a better solution for storing data in a decentralized database than IPFS. In that case, we can create a new storage layer that uses Arweave and make the data-access layer using this new package instead.
The following pages present the first implementation of the protocol used for the released version of Request V2 on mainnet.
Reference-based payment networks use a to link payments to the corresponding Request. They process payments via payment proxy smart contracts deployed across a wide variety of supported chains. These contracts serve two key functions:
For details on how to use the ERC20 Fee Proxy, see the or
For details on how to use the ETH Fee Proxy, see
Conversion is different from Swap-to-Pay. For details see
For details on how to use the Any-to-ERC20 Conversion Proxy Contract, see
Conversion is different from Swap-to-Pay. For details see
For details on how to use the Any-to-ETH Proxy Contract, see
For details on how to use ERC20 Transferable Receivables, see
For details on how to use Declarative Payments, See
For details on how to use Meta Payment Network, see
For details on how to use the ERC777 Stream Payment Network, see
See for additional details.
Swap-to-Pay is different from Conversion. For details see
See for additional details
See for additional details.
Swap-to-Pay is different from Conversion. For details see
See for additional details.
For more detailed information on specific payment networks or to contribute new implementations, please refer to our or join our .
Promise<>
Identical to
Equal to OR
The protocol follows a defined interface; each layer has to implement a specific interface. The interfaces for each layer can be found in the Types package of Request Network repository: .
parameters
Parameters to create a request
options
Options to create a request
requestInfo
Core request contents
signer
Identity of the creator and signer of the request. Must be either the payee or payer.
paymentNetwork
Payment method
topics
string[]
List of hashes, usually one for each of the request stakeholders
contentData
Object
Additional arbitrary request contents
disablePaymentDetection
boolean
Disable payment detection
disableEvents
boolean
Diable event callbacks
skipRefresh
boolean
Disable the request refresh after creation. Warning: the balance
will be null.
currency
string | ICurrency
The currency in which the request is denominated. Not necessarily the currency in which the payment will occur.
expectedAmount
number | string
The requested amount in machine-readable integer units.
payee
Identity of the payee. Required if payer not set
payer
Identity of the payer. Required if payee not set
extensionsData
any[]
Raw extensionsData. Not recommended. Prefer contentData
and paymentNetwork
instead.
timestamp
number (Unix timestamp)
Timestamp when request is created. User provided, so this is an agreement between payee and payer.
nonce
number
Optional nonce to differentiate identical requests created at the same timestamp.
id
Payment network ID
parameters
Payment network parameters. Contents depend on id
type
Currency type
value
string
Depends on type.
ERC20 contract address '0x123'
Fiat symbol 'USD'
Native symbol 'ETH'
network
ChainName
The chain on which the currency exists
ETH
'ETH'
Native (ETH, XDAI, etc.)
BTC
'BTC'
Bitcoin
ISO4217
'ISO4217'
Fiat (USD, EUR, etc.)
ERC20
'ERC20'
Non-native fungible currency (USDC, REQ, etc.)
ERC777
'ERC777'
Streamable fungible currency (USDCx, REQx, etc.)
ANY_DECLARATIVE
'pn-any-declarative'
Payer declares payment sent. Payee declares payment received.
ANY_TO_ERC20_PROXY
'pn-any-to-erc20-proxy'
Swap to ERC20 before sending to payee
ANY_TO_ETH_PROXY
'pn-any-to-eth-proxy'
Swap to native token before sending to payee. Only works on EVM-compatible chains.
ANY_TO_NATIVE_TOKEN
'pn-any-to-native-token'
Swap to native token before sending to payee. Only works on NEAR.
BITCOIN_ADDRESS_BASED
'pn-bitcoin-address-based'
Payee generates a new Bitcoin address. Use block explorer to detect all payments to that address.
ERC20_ADDRESS_BASED
'pn-erc20-address-based'
Payee generates a new Ethereum address. Use block explorer to detect all payments to that address.
ERC20_FEE_PROXY_CONTRACT
'pn-erc20-fee-proxy-contract'
Send ERC20 via smart contract with an optional fee.
ERC20_PROXY_CONTRACT
'pn-erc20-proxy-contract'
Send ERC20 via smart contract
ERC20_TRANSFERABLE_RECEIVABLE
'pn-erc20-transferable-receivable'
Mint a Request as an NFT. The holder receives the payment.
ERC777_STREAM
'pn-erc777-stream'
Superfluid stream
ETH_FEE_PROXY_CONTRACT
'pn-eth-fee-proxy-contract'
Send native token via smart contract with an optional fee.
ETH_INPUT_DATA
'pn-eth-input-data'
Send native token with paymentReference in the call data.
NATIVE_TOKEN
'pn-native-token'
Send native token via smart contract with an optional fee on NEAR.
TESTNET_BITCOIN_ADDRESS_BASED
'pn-testnet-bitcoin-address-based'
Payee generates a new Bitcoin testnet address. Use block explorer to detect all payments to that address.
paymentInfo
any
refundInfo
any
payeeDelegate
Identity that can update the request on behalf of the payee
payerDelegate
Identity that can update the request on behalf of the payer
salt
string
A random number with at least 8 bytes of randomness. It must be unique to each request
paymentAddress
string
The payment recipient address
refundAddress
string
The refund recipient address
salt
string
paymentNetworkName
ChainName
The chain name on which the payment will occur
feeAddress
string
The address to which fees will be sent
feeAmount
string
The fee amount in machine-readable integer units
maxRateTimespan
number
The maximum acceptable time span between the payment and the conversion rate timestamp
network
ChainName
The network of the tokens accepted for payments
acceptedTokens
string[]
A list of token addresses accepted for payments and refunds
network
EvmChainName
the network of the tokens accepted for payments
expectedFlowRate
string
expectedStartDate
string
previousRequestId
string
originalRequestId
string
recurrenceNumber
string
Storage defines where the data are stored. How to store these data and how to retrieve them.
The currently used package, named ethereum-storage
, uses IPFS to store the data immutably and uses the Ethereum network to persist the IPFS hash of the data and make them permanently available to everyone.
https://github.com/RequestNetwork/requestNetwork/tree/master/packages/ethereum-storage
The storage of data implementation is:
Open: Anyone should be able to access the data (though it can be encrypted)
Decentralized: The database is trustless; we don’t have to refer to a third party to trust the data
Resilient: The database should always be available, nobody should be able to shutdown it alone
The interplanetary file system (IPFS) is a decentralized network to store and share files: https://ipfs.io
One of the advantages of IPFS as a storage solution is that it is content addressable. When a file is deleted, if someone reuploads the file, anybody will be able to access it with the same path. For a specific block of data, we will get a specific hash; the hash is persisted on Ethereum to ensure requests immutability.
We use Ethereum to store IPFS hashes. The hashes are stored as event logs of a specific smart contract to stay at a minimal cost.
The Ethereum smart contracts are also used to enforce the fee cost of storing a block to Request. The user will store the file's size in addition to the hash. A fee related to this hash will be paid in Ether when storing the hash.
For our solution, we use additional smart contracts for fee verification. Using external smart contracts allows us to implement different fee rules in the future. More information can be found in the ethereum-storage repository.
The RequestHashStorage smart contract address can be found on GitHub
Data-Access is the layer that organizes the data in the correct format before having them stored in the storage layer. This layer is similar as the persistence layer in the classical layered architecture pattern.
https://github.com/RequestNetwork/requestNetwork/tree/master/packages/data-access
Heavy communication with the Storage layer can be costly. For example, for a solution using Ethereum, every Ethereum transactions cost some gas.
Data-Access layer will gather transactions and batch them into blocks. This solution allows for less communication with the Storage layer. In this case, it will allow consuming less gas for Ethereum transactions.
Data-Access is also responsible for other side tasks:
Indexing transactions to allow retrieval
Accessing transactions through a local cache
Synchronizing with the storage
The storage phase is only complete when indexing has completed. Because this indexing is an Ethereum transaction, you cannot know how long it will take.
It is because when a block is created or read from the storage, the transactions inside it will be indexed and kept in a local cache. When a user wants to get information about a request, Data-Access will directly fetch them from this local cache.
Data-Access stays synchronized with the storage layer. For example, it pulls for new blocks, added by other users, in the storage every 10 seconds.
The Request Network protocol persists request contents on IPFS. When privacy is required, the SDK supports the creation and subsequent reading of encrypted requests.
This is achieved by combining public key (asymmetric) & AES (symmetric) encryption.
The "request contents" are encrypted with a random AES key. This key is then encrypted with the public key of each stakeholder of the request. The stakeholders are the users and platforms who require access to the request contents. The encrypted request contents and the encrypted AES keys are then persisted to IPFS.
The user retrieves the encrypted request content and the encrypted AES keys. They decrypt the AES key using their private key. Then they decrypt the request content using the AES key.
The privacy and encryption mechanism used by Request Network has many similarities to HTTPS. If you're not familiar with HTTPS, we recommend reading HTTPS explained with carrier pigeons
This page is missing the RequestToken, DAIbasedREQBurner, lockForREQBurn, ChainlinkConversionPath contracts
Request Network smart contracts are available here.
There are three types of contracts
Storage - These store Content Identifiers (CIDs) for Requests stored in IPFS.
Payments - These process various payment types, also known as Payment Networks, and are deployed across many Supported Chains.
REQ Token and Burn Mechanism - These lock, bridge, and burn REQ tokens each time a Request is stored.
Declares data hashes and collects the fees.
After a request has been sent to IPFS, the hash is declared to the whole request network system through the RequestHashStorage.
Anyone can submit hashes.
Manages the fees for the creation of a request.
This contract is the entry point to retrieve all the hashes of the request network system.
Performs an ERC20 token transfer with a payment reference and a transfer to a second address for the payment of a fee.
Performs an ERC20 token transfer with a payment reference and a transfer to a second address.
This contract performs an Ethereum transfer with a Fee sent to a third address and stores a reference.
This contract performs an Ethereum transfer sent to a third address and stores a reference.
This contract allows users to lock funds in an escrow and perform payments in ERC20. It contains a refund and emergency feature to unlock funds if needed.
This contract makes multiple conversion payments with a payment references, in one transaction.
This contract makes multiple payments with payment references, in one transaction.
This contract makes multiple payments with references, in one transaction, without conversion.
This contract swaps ERC20 tokens before paying a request such that the payer sends currency A, but payee receives currency B.
This contract uses a chainlink price feed to pay a request denominated in one currency (usually a fiat currency like USD) but paid in an on-chain currency. This variant supports ERC20 payments.
This contract uses a chainlink price feed to pay a request denominated in one currency (usually a fiat currency like USD) but paid in an on-chain currency. This variant supports native currency payments.
This contract combines "conversion" and "swap-to-pay". It executes an ERC20 swap before paying a request denominated in one currency (usually a fiat currency like USD) but paid in an on-chain currency. This variant supports ERC20 payments.
This contract allows minting requests as NFTs thus allowing them to be transferred. The owner of the request NFT receives the payment.
A contract that allows payment through the ERC20FeeProxy without having to make a function call.
A contract that allows payment through EthereumFeeProxy without having to make a function call.
A factory smart contract responsible for deploying ERC20SingleRequestProxy and EthereumSingleRequestProxy contracts.
Simplicity is one of the most important characteristics we want to achieve in the Protocol. This is why the actions available in Request Logic are the minimal set of actions needed for any kind of request for payment. In the same way, the basic request state is universally common to any request, every request has a payee (a recipient), a currency (what requested), an expected amount (how much requested) and a basic state (accepted, canceled). To enable more advanced features for the users, we conceived Advanced Logic.
Advanced Logic is a package that allows the user to define extensions that can be added to the request. An extension is an isolated context inside the request that contains his actions and his state. For example, the extension content-data
allows the user to add metadata to a request (e.g. the additional data needed for an invoice). The Advanced Logic layer is also where the payment networks allowing payment detection are implemented.
Similar to Request Logic, a specific extension can define different actions related to it. There is the Create action of the extension and, eventually different update actions. The extension is initialized at the same time as the request, and any action of the Request Logic can add extension data. There is a specific action, AddExtensionData
, in Request Logic, only intended to add extension data to the request with no other side-effect.
The specification for each extension can be found at this link: https://github.com/RequestNetwork/requestNetwork/tree/master/packages/advanced-logic/specs
The transaction layer is responsible for converting actions into a channel of transactions and vice versa. It also optionally encrypts and decrypts those transactions such that only stakeholders of the request can read them.
https://github.com/RequestNetwork/requestNetwork/tree/master/packages/transaction-manager
Transactions can be stored in the clear, unencrypted, meaning that anyone can read the request. Transactions can also be encrypted, such that only stakeholders of the request can read them. Any number of stakeholders can be included in the creation of an encrypted request. Request uses an encryption scheme nearly identical to HTTPS. It uses a symmetric key (usually referred to as the "channel key") to encrypt and decrypt the transaction channel content, and asymmetric keys to encrypt and decrypt copies of the symmetric key.
A unique channel key that is shared with all the stakeholders
A set of public and private key pairs, each pair controlled by a single stakeholder
The channel key uses Advanced Encryption Standard (AES), a symmetric encryption technology; this means the same key is used to encrypt and decrypt.
The public and private key pairs use Elliptic Curve Integrated Encryption Scheme (ECIES), an asymmetric encryption technology where the public key encrypts and the private key decrypts.
Every transaction of the same request is encrypted with the same channel key. The encrypted transactions form the channel (hence the name channel key).
The channel key is encrypted with each stakeholder's public key. This way, every stakeholder can decrypt the channel key and in turn, decrypt the transactions in the channel.
This design using both symmetric and asymmetric encryption allows the transaction data once and only the channel key needs to be duplicated, once for each stakeholder.
See the details of encrypted request creation in Encrypt with an Ethereum private key
This layer is responsible for the business logic of Request. This is where we define the data structure of a request.
This layer has three responsibilities:
It defines the properties of the requests and the actions performed on them.
It's responsible for the signature of the actions performed to ensure the request stakeholder identities.
It manages extensions that can be created to extend the features of the Request Protocol through the Advanced Logic package.
https://github.com/RequestNetwork/requestNetwork/tree/master/packages/request-logic
Actions are the essential elements that compose a request. From this layer's point of view, a request is simply a list of different actions.
The payee creates the request requesting 1 ETH to the payer
The payer accepts the request
The payer increases the expected amount of the request by 1 ETH (the expected amount of the request can only be increased by the payer and decreased by the payee)
Given the list of these actions, we can interpret the state of the request. The example above describes a request that has been accepted by the payer where he will have to pay 2 ETH to the payee.
Note that the hash of the action determines the request Id. Therefore, this action doesn't specify the request Id since it doesn't exist yet. The update actions (accept
and increaseExpectedAmount
) specify the request Id in their data.
There are two kinds of action:
Create: This action is not related to an existing request, it will create a new one
Update: All other actions, it will update the state of an existing request
In addition to providing the structure to form an action composing a request, the request logic layer is also responsible for signing the action.
To abstract the signing process from the layer (and eventually be able to use it in other packages), the signing process is done through external packages named signature providers.
The protocol repository currently contains two signature provider packages:
Both packages use the Elliptic Curve Digital Signature Algorithm (ECDSA) used in Ethereum. web3-signature will connect to Metamask to ask users to sign requests. epk-signature uses private keys that are stored in the clear and managed manually.
The web3-signature
provider should be used to create a fully-decentralized solution where the users manage their own private keys. The epk-signature
provider is used to manage the private keys on behalf of the users. It's never a good idea to let users handle plain private keys.
This page presents the flow of data that occurs when some actions are performed in the protocol.
The next schemas show the data flow that happens when a user performs an accept
action on a request.
The next schemas show the data flow when the user wants to read the content of a request.
In this case, the user calls this function of Request Logic: getRequestFromId(0xaaa)
that reads the request with the request id: 0xaaa
There is a permanent data flow between Data Access and Storage layers.
For performance purposes, Data Access will periodically synchronize with the current state of Storage. When a new, not synchronized block is detected, the block content will be dispatched into the Data Access cache.
Some actions from the Transaction layer can be invalid; this is the role of Request Logic to filter them to give the consistent state of the request to the user.
For example, only the payer of the request can increase the expected amount of it. If the action increaseExpectedAmount
is signed by the payee therefore, the action is ignored.
Request uses IPFS to store transaction data in a decentralized way. Transactions are actions done on a request, for example: create, accept, reject...
When files are stored in IPFS, they are kept locally on the IPFS node, and are accessible by any node connected to the network. IPFS creates a unique hash used as an identifier to access a file. We store this hash on the Request smart contract to have a trustless list of transactions.
By creating a dedicated IPFS network for Request, our network is isolated from the rest of the IPFS network. All the Request IPFS nodes will only communicate with other Request Nodes. By keeping the network small, we can make sure most nodes are connected between themselves, and asking for files can be done directly to a node instead of through a traversal.
This is a big advantage for us because our nodes' end goal is different from that of a normal IPFS node: all the IPFS nodes used by a Request Node should have all the files on the network. This makes the DHT pointless, and the most critical factor in discovery time becomes how many nodes every node is connected to.
These are the main reason why we created the Request IPFS network.
IPFS has a feature called private network. It allows IPFS nodes that share a private key to communicate only among themselves and keep their files private from the open IPFS network. We use this feature to create an IPFS network separate from the open one, but we keep this key public. This way, we have a separate public network from the open network.
We also changed some default IPFS configurations on our network, to improve performance and responsiveness. The main change we did is disabling the DHT, so instead of traversing the network to find a file, the nodes will only ask to their neighbor nodes for those files. Since on our network every node is supposed to have every transaction file, those responses tend to be a lot faster (on most of our test cases the response time went from seconds to a few hundred milliseconds).
We distribute a Docker image of our configured IPFS node. To run it, you can use the command:
There are two easy ways to connect an IPFS node to the Request Network:
If you want to set up your IPFS node yourself, here is the information you would need:
The swarm key
you should put this file at your IPFS path (usually in $IPFS_PATH)
swarm.key file content:
The configurations
The main IPFS network has tens of thousands of nodes and many files. All of the Request transactions are a tiny fraction of the IPFS network. To find a transaction file, the Request Node IPFS has to on the network. Content retrieval is currently relatively slow on IPFS.
Use the docker image to run your IPFS. It comes pre-configured and you just need to run it.
script available from the or the .
Smart Contract Addresses
Smart Contract Source