Sponsoring Transactions
Lens allows apps to offer a free user experience to their end-users through Sponsorships.
Lens Sponsorship enables developers to provide a fully configurable, gasless experience for their users. It leverages the ZKsync Paymaster.
After creating and funding a Sponsorship, it can be used to cover gas fees for Lens Protocol transactions, as well as any other transactions on the Lens Chain.
Create Sponsorship
To create a Sponsorship, follow these steps.
You MUST be authenticated as a Builder to create a Sponsorship.
First, create the Sponsorship Metadata object.
- TS/JS
- JSON Schema
Use the @lens-protocol/metadata package to construct a valid SponsorshipMetadata object:
Example
import { sponsorship } from "@lens-protocol/metadata";
const metadata = sponsorship({ name: "GasPal",});
Next, upload the Sponsorship Metadata object to a public URI.
import { storageClient } from "./storage-client";
const { uri } = await storageClient.uploadAsJson(metadata);
console.log(uri); // e.g., lens://4f91ca…
This example uses Grove storage to host the Metadata object. See the Lens Metadata Standards guide for more information on hosting Metadata objects.
Next, deploy the Lens Sponsorship smart contract.
By setting the allowLensAccess flag to true, you are allowing the Lens API to use the Sponsorship to sponsor Lens transactions for users of your Lens App.
- TypeScript
- GraphQL
Use the createSponsorship action to deploy the Lens Sponsorship smart contract.
deploy-sponsorship.ts
import { uri } from "@lens-protocol/client";import { createSponsorship } from "@lens-protocol/client/actions";
// …
const result = await createSponsorship(sessionClient, { metadataUri: uri("lens://4f91…"), // the URI from the previous step allowLensAccess: true,});
- TypeScript
- GraphQL
Then, handle the result using the adapter for the library of your choice:
See the Transaction Lifecycle guide for more information on how to determine the status of the transaction.
Fund Sponsorship
To sponsor transactions for your users, you must periodically fund your Lens Sponsorship.
This involves sending native GHO (GRASS on Testnet) to the Lens Sponsorship contract address.
You can accomplish this either manually through a wallet or programmatically using code.
Refer to the Lens Chain integration guide for more options on how to integrate with the Lens Chain.
Sponsor Lens Transactions
To start using Lens Sponsorship to sponsor Lens transactions for your users, follow these steps.
To simplify the development process on Testnet, if an app Sponsorship contract is not configured, all transactions are sponsored by Lens through a global Sponsorship contract.
First, configure your Lens App to use a Sponsorship you previously created.
- TypeScript
- GraphQL
Use the setAppSponsorship action to set the Sponsorship for your App.
set-app-sponsorship.ts
import { evmAddress } from "@lens-protocol/client";import { setAppSponsorship } from "@lens-protocol/client/actions";
// …
const result = await setAppSponsorship(sessionClient, { app: evmAddress("0x1234…"), sponsorship: evmAddress("0x5678…"),});
- TypeScript
- GraphQL
Then, handle the result using the adapter for the library of your choice and wait for it to be indexed.
And, ensure the transaction was successful:
Wait for Transaction
const result = await setAppSponsorship(sessionClient, { app: evmAddress("0x1234…"), sponsorship: evmAddress("0x5678…"),}) .andThen(handleOperationWith(signer)) .andThen(sessionClient.waitForTransaction);
if (result.isErr()) { return console.error(result.error);}
// The transaction was successful
Finally, implement the Authentication Workflow to be able to authorize end-users for your sponsorship. If this is not implemented, the Lens API will require end-users to cover transaction fees by returning a Self-Funded Transaction Request for any operation involving a transaction.
Since transactions on Testnet fall back to being sponsored by the Lens global Sponsorship if no app Sponsorship is configured, you might not notice any visible difference in the final user experience until deploying to Mainnet, where the full behavior is enforced.
Sponsor Any Transaction
To sponsor any transaction on the Lens Chain using funds from your Sponsorship, follow these steps.
First, generate a new private key for the address responsible for approving sponsorship requests (i.e., the signer).
Next, add the signer to your Sponsorship.
You MUST be authenticated as a Builder and be the owner or an admin for the Sponsorship you want to add the signer to.
- TypeScript
- GraphQL
Use the updateSponsorshipSigners action to add the signer to your Sponsorship.
Add Sponsorship Signer
import { evmAddress } from "@lens-protocol/client";import { updateSponsorshipSigners } from "@lens-protocol/client/actions";
// …
const result = await updateSponsorshipSigners(sessionClient, { sponsorship: evmAddress("0xe2f2a5C287993345a840db3B0845fbc70f5935a5"), toAdd: [ { address: evmAddress("0x8711d4d6B7536D…"), label: "My Backend System", }, ],});
- TypeScript
- GraphQL
Then, handle the result using the adapter for the library of your choice and wait for it to be indexed.
Finally, implement the logic to sponsor user's transaction that supports your use case.
- viem
- ethers
Here’s an example of a client-side application that sends a request to its backend to generate a sponsored transaction based on specific criteria.
The backend server listens for incoming requests, utilizes the SponsorshipApprovalSigner to approve the transaction, and sends the approved transaction back to the client.