Paymasters with Trampoline - Part II: Verifying Paymasters

In the previous instalment of our blog series, titled "Paymasters with Trampoline - Part I: Token Paymasters", we delved into the fundamentals of paymasters and their role in automating gas fee payments. We also provided a comprehensive step-by-step guide on how to set up a token paymaster using Trampoline.

Continuing our exploration of paymasters, in this blog post, we will delve into the concept of verifying paymasters. For this purpose, we will utilize the verifying paymaster services offered by Stackup & Alchemy.

What exactly is a verifying paymaster, you ask?

A verifying paymaster comes into play when an off-chain service assumes the responsibility of determining whether or not to pay the network fees for a transaction. Once the off-chain service has made this determination, it signs the userOp with a signature that the corresponding verifying paymaster contract can verify and accept on-chain.

There are several reasons why an off-chain service might opt for a sponsoring paymaster, including:

  • Establishing partnerships with web3 application and wallet developers who seek to simplify user onboarding for newcomers in the web3 space.

  • Providing incentives for platform-specific user behaviours.

  • Minting an NFT without incurring gas fees.

  • Deploying a wallet without expending gas, and numerous other use cases.

Verifying paymasters also empowers developers to sponsor gas based on off-chain activities such as interactions in Discord and other off-chain actions. Since these activities cannot be directly verified on-chain, creating a comprehensive on-chain paymaster becomes challenging. In such scenarios, developers can opt to create a verifying paymaster, wherein they can validate all relevant off-chain activities and, upon successful verification, sign the userOp with their verifying paymaster to sponsor the gas.

How do verifying paymasters work?

A verifying paymaster serves as an off-chain service that accepts signatures from entities authorized by the corresponding on-chain Verifying Paymaster contract.

Here's a breakdown of the underlying code:

During initialization, the paymaster incorporates a verifyingSigner, representing the authorized signer whose signatures will be accepted by the Verifying Paymaster. Stackup and Alchemy, among other service providers, configure this aspect using their private keys, allowing them to sign transactions on behalf of developers and offer paymaster services. The relevant code snippet highlighting this process can be observed below:

https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/VerifyingPaymaster.sol#L29
https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/VerifyingPaymaster.sol#L29

To ensure the security of the userOp and prevent replay attacks, it is essential to implement replay protection both within the same chain and across different chains. Without replay protection, if a signature is easily replayable, it would allow unauthorized individuals to drain the paymaster. To mitigate this risk, the contract incorporates a hash generation mechanism that requires the off-chain signing of both the userOp and chain ID information. Additionally, the contract includes a validUntil field, which can be utilized to defend against replay attacks if the provided timestamps have expired. Below is the code snippet illustrating the process of generating a hash for signing:

https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/VerifyingPaymaster.sol#L41
https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/VerifyingPaymaster.sol#L41

Once the hash is generated, the next step involves on-chain verification of the signature provided by the authorized signer's private key. It is crucial to note that the private key responsible for signing the hash cannot be stored on the client side due to security concerns. In the following example, we will demonstrate how to utilize services like Stackup or Alchemy, which offer API keys that enable them to sign the userOp on behalf of the user. To ensure the safety of these API keys, it is imperative to protect them diligently. Unauthorized access to these keys could result in unauthorized gas fee payments and lead to substantial financial liabilities. To help you maintain the security of your API keys, we have outlined a structure below, which can be implemented on a server-side environment.

Architecture to use Verifying Paymaster
Architecture to use Verifying Paymaster

Setting up a verifying paymaster

In this blog post, we will explore the process of setting up a verifying paymaster using services such as Stackup and Alchemy. Instead of deploying our own paymaster contract, we will leverage these trusted services to handle the paymaster functionality.

To begin, let's outline the steps involved:

  1. Create a server: To facilitate the interaction between our application and the paymaster services, we need to set up a server. This server will act as an intermediary to keep our API keys secret and make RPC requests to retrieve the paymaster and relevant data.

  2. Implement an RPC call to the server: Within our extension, we need to incorporate an RPC call that connects to our server. This call will be responsible for fetching the paymaster and associated data from our servers. By making this request to our server, we ensure that sensitive information such as secret private API keys are securely stored and managed on the server side.

  3. Server integration with paymaster services: On the server side, we utilize the secret private API key to make the necessary calls to the dedicated paymaster services, such as Stackup or Alchemy. These services will handle the logic of generating the paymaster and data field, ensuring the integrity and security of the process. The server then returns the retrieved paymaster and data to the client application to be signed and sent on-chain.

Create a server

To view the code snippet that demonstrates the server setup, you can refer to the following link.

After creating the server using Express, you can run it directly from the root of your project using the command: npx nodemon server/index.ts. This command will start the server and allow it to listen to incoming requests.

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-786114c6ebf98e577ec30dac884800bb7c9ce800b5323710ed03b916e1d33b68R7 
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-786114c6ebf98e577ec30dac884800bb7c9ce800b5323710ed03b916e1d33b68R7 

Within the server, a POST route /api/v1/paymaster/ has been created. This route will handle the requests from your extension to fetch the paymasterAndData, which requires the parameters userOperation and entryPoint.

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R148
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R148

As we will be making an RPC call to our server from our extension, we have developed a custom RPC method called local_getPaymasterAndData to facilitate this process. You can find the extension code snippet for this method below:

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R7
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R7

In the custom RPC method we created, we will include logic to forward the userOp received in the request to the paymaster service URL obtained from either Stackup or Alchemy. This will allow us to fetch the paymaster and associated data. Here's an updated version of the code:

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R103
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R103

Given that both Stackup and Alchemy have different request parameters, we will examine each of them individually in the following sections. This approach allows us to ensure compatibility with the specific requirements of each service.

How to setup Stackup’s verifying paymaster

To set up Stackup's verifying paymaster, follow the steps below:

  1. Generate an API key from Stackup:

  2. Visit Stackup's website.

  3. Create a new instance.

  4. Navigate to the Paymaster section and copy the URL with the API key.

  5. Once you have obtained the URL with the API key, refer to Stackup's documentation for the required RPC call. According to the documentation, you need to make an RPC call pm_sponsorUserOperation with parameters such as userOp, entryPoint, and paymaster-specific data.

  6. Paymaster-specific above can be of two types, depending on if you want to sponsor the gas completely or if you want the user to be able to pay gas via ERC20 tokens. As you may see in the code example below we are sending type =” payg”, that means that this call will be sponsored using our Stackup account and a bill will be generated at the month's end that we will have to clear. We could have also used a config like:{ "type": "erc20token", "token": "USDC_ADDRESS" | "TEST_TOKEN_ADDRESS" }The above config will allow users to pay gas via ERC20 tokens that you supply in the token address. Do note that currently Stackup only supports USDC on the mainnet and tokens on the testnet and no other ERC20 tokens are supported.

Here's an example of how to make the RPC call to Stackup's paymaster:

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R9
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R9

How to setup Alchemy paymaster

To set up Alchemy's paymaster, follow the steps below:

  1. Generate an API key from Alchemy

  2. Go to https://dashboard.alchemy.com/

  3. Create a new APP (Here we are creating for Sepolia)

  4. Go to Gas Manager

  5. Create a new Policy

  6. The new policy requires an app - select the app you created in step 1.b.

  7. Follow the instructions and at the end you will get a Policy ID.

  8. Once you have the Policy ID and App ID, you can make a call to Alchemy's endpoint alchemy_requestGasAndPaymasterAndData to retrieve the paymaster and associated data. Refer to Alchemy's documentation for detailed information on this endpoint.

Here's an example of making an RPC call to obtain the paymaster data and other gas parameters using Alchemy's endpoint:

https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R48
https://github.com/eth-infinitism/trampoline/pull/20/files#diff-a063e361b4700c847d46e6e6384d6b8c8b6f20ea277f3f5c43cbf4d28737de11R48

In the provided code, the PAYMASTER_SERVICE_URL is set as https://{network}.g.alchemy.com/v2/{apiKey}, where {network} refers to the specific blockchain network being used (e.g., mainnet, rinkeby) and {apiKey} represents the API key obtained from Alchemy for your App.

Additionally, the POLICY_ID corresponds to the value obtained from step 1.f of the Alchemy setup process.

By utilizing the PAYMASTER_SERVICE_URL and POLICY_ID in the code, you can effectively connect to the Alchemy paymaster service and retrieve the necessary paymaster data, which can then be sent back to the client to be signed and sent to the blockchain.

Congratulations! You have now learned how to utilize the verifying paymaster services provided by Stackup and Alchemy. These services offer convenient and secure options for automating and managing gas fee payments, streamlining the development process for web3 applications.

Subscribe to erc4337
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.