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. Lens Sponsorship is an implementation of ZKsync Paymaster.
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.
To start using Lens Sponsorship to sponsor transactions for your users, you need to:
Deploy a Sponsorship contract
Associate it with your Lens App
Implement the Authentication Workflow to authorize end-users
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 transactions for users of your 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,});
And, handle the result using the adapter for the library of your choice:
Before proceeding, ensure the transaction was successful:
Wait for Transaction
const result = await createSponsorship(sessionClient, { metadataUri: uri("lens://4f91…"), // the URI from the previous step allowLensAccess: true,}) .andThen(handleOperationWith(signer)) .andThen(sessionClient.waitForTransaction);
if (result.isErr()) { return console.error(result.error);}
// The transaction was successful
Next, configure your Lens App to use the Sponsorship.
- 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…"),});
And, handle the result using the adapter for the library of your choice:
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.
Next, you can learn how to fund and manage your Sponsorship.