[Testnet] Open Action | Cross-chain Zora Mint (v2)
Mint Zora NFTs on Base, with Bonsai on Polygon
Overview
This is a technical guide on how to integrate our ZoraLzMintActionV2 open action. More details about the open action can be found here: Cross-chain Zora Mint (v2)
Our ZoraLzMintActionV2 action module is deployed and verified on Polygon
Our contract which receives the messages is ZoraLzCreatorV2 - deployed and verified on Base.
Initialize with the open action
To initialize a publication with the ZoraLzMintActionV2 module, you must provide the details for a Zora NFT where
the chain is Base
the currency is Bonsai (Base)
the sale is active
Process the open action
To process a publication with the ZoraLzMintActionV2 module, you must
Get the total sale price for the mint
Have the actor approve the $BONSAI token transfer to the module
Encode the data needed to process the act
Send the act transaction
Prepare the act transaction
// 1. Fetch module metadataimport { testnet, LensClient } from"@lens-protocol/client";import { constants } from"viem";constZORA_LZ_MINT_ACTION_V2="0xA5F19D5953B7777537014653e6219983cE82001c";constBONSAI="0x3d2bD0e15829AA5C362a4144FdF4A1112fa29B5c";constlensClient=newLensClient({ environment: testnet });constdata=awaitlensClient.modules.fetchMetadata({ implementation:ZORA_LZ_MINT_ACTION_V2 });const { metadata } = data;// 2. Get the total sale priceconstpointedProfileId=697; constpointedPubId=3; constquantity=1;constactionModule=getActionModule(ZORA_LZ_MINT_ACTION_V2); // ethers ContractconsttotalSalePrice=awaitactionModule.getTotalSalePrice(pointedProfileId, pointedPubId, qty);// 3. Approve the token transferconsttx=awaitgetTokenContract(BONSAI).approve(ZORA_LZ_MINT_ACTION_V2, totalSalePrice);awaittx.wait();// 4. Encode act dataconstparams= { quantity, clientAddress:constants.AddressZero,// client address to earn protocol fee comment:"minted with $BONSAI"// user-provided comment to surface on Zora UI};constactionModuleData=encodeData(JSON.parse(metadata.processCalldataABI), [params.quantity,params.clientAddress,params.comment]);
Send the act transaction (gasless)
There's a lot of steps involved here, so we'll defer to the Lens docs - but here is the general code.
import { WalletClient } from"viem";import { OnchainReferrer, RelaySuccessFragment, LensClient } from"@lens-protocol/client";import { omit } from"lodash/object";// NOTE: this assume the given `actionModule` has `metadata.sponsoredApproved` = true// NOTE: this assumes that the passed in `lensClient` is authenticated (see: https://docs.lens.xyz/docs/login)// NOTE: this assumes the app is whitelisted to use gaslessexportconstactWithSignedTypedata=async ( lensClient:LensClient, walletClient:WalletClient, publicationId:string, actionModule:`0x${string}`, actionModuleData:string, referrers?:OnchainReferrer[] // profile to earn mint referral fees):Promise<any> => {try {// get typed dataconsttypedDataResult=awaitlensClient.publication.actions.createActOnTypedData({ actOn: { unknownOpenAction: { address: actionModule, data: actionModuleData } }, for: publicationId, referrers: referrers || [] });const { id,typedData } =typedDataResult.unwrap();// sign itconst [account] =awaitwalletClient.getAddresses();constsignedTypedData=awaitwalletClient.signTypedData({ account, domain:omit(typedData.domain,"__typename"), types:omit(typedData.types,"__typename"), primaryType:"Act", message:omit(typedData.value,"__typename"), });// broadcast onchain, gaslessconstbroadcastResult=awaitlensClient.transaction.broadcastOnchain({ id, signature: signedTypedData });constbroadcastResultValue=broadcastResult.unwrap();if (broadcastResultValue.__typename ==="RelayError") thrownewError("RelayError");// return the tx hash to link to layerzero scanreturn (broadcastResultValue asRelaySuccessFragment).txHash; } catch (error) {console.log(error); }}
Remember that the open action is to pay for mints in Bonsai on Polygon - even though the Zora NFT is on Base and priced in Base Bonsai.
This function assumes your app domain is whitelisted to use gasless
This function assumes that lensClient is authenticated with a profile
A note on mint referral rewards. The function above shows how to pass in referrers data - which when processed by our open action - will include the referrers[0].profileId profile owner as the recipient for Zora Mint Referral rewards.