This project combines Chainlink Functions with Lens Publication Actions to demonstrate how one can generate discount codes for events on Eventbrite using Collect module.
- Git
- Current LTS Node.js version
- Foundry
- Fund your wallet with some LINK
- Connect your wallet and get a Lens profile from this URL. Make sure your wallet is connected to Polygon Mumbai and that you have Matic in your wallet. Click on the Login button, then click on "Create Testnet Account" and choose your lens profile name. Then logout and log back in with your wallet to see your testnet handle.
- Install smart contract packages
cd contracts && npm install
- Compile contracts
forge build
- Install UI packages
cd ../app && npm install
If dependency clashes arise please run npm install --force
- Start the server
npm run dev
Using Chainlink Functions and Lens Publication Actions, we are going to develop a system for generating discount codes for events (like Smartcon or Raave for example) hosted on Eventbrite.
The event organizer will need to create a new event on Eventbrite, following these instructions.
To develop and use this project, you will need to obtain a free Eventbrite OAUTH token.
Once you generate an Eventbrite OAUTH token, you can visit the following web page to validate it works as expected https://www.eventbriteapi.com/v3/users/me/?token=<YOUR_OAUTH_TOKEN_GOES_HERE>
Next, you will need to get your
- Organization ID, by visiting
https://www.eventbriteapi.com/v3/users/me/organizations/?token=<YOUR_OAUTH_TOKEN_GOES_HERE>
- Event ID, by visiting
https://www.eventbriteapi.com/v3/organizations/<ORGANIZATION_ID_GOES_HERE>/events/?token=<YOUR_OAUTH_TOKEN_GOES_HERE>
The core logic is stored in the DiscountPublicationAction.sol
smart contract which implements IPublicationActionModule
and FunctionsClient
interfaces. On Lens collect, it will make a Chainlink Functions request to execute the JavaScript code from the source.js
file, which will resolve User's address to a Lens handle and generate the Eventbrite discount code for the provided event. The DiscountPublicationAction.sol
smart contract will then store the returned discount code.
For setting up environment variables we are going to use the @chainlink/env-enc
package for extra security. It encrypts sensitive data instead of storing them as plain text in the .env
file, by creating a new, .env.enc
file. Although it's not recommended to push this file online, if that accidentally happens your secrets will still be encrypted.
- Change into the
./contracts
directory to set up its dependencies. Make sure commands in this USAGE SECTION are run from inside this directory. Start withnpm install
if you've not done that yet.
cd contracts
- Set a password for encrypting and decrypting the environment variable file. You can change it later by typing the same command.
npx env-enc set-pw
- Now set the
OAUTH_KEY
,PRIVATE_KEY
andPOLYGON_MUMBAI_RPC_URL
environment variables by typing:
npx env-enc set
After you are done, the .env.enc
file will be automatically generated.
If you want to validate your inputs you can always run the following command:
npx env-enc view
- Run local simulation
check the
./contracts/test/DiscountPublicationAction.t.sol
file for@Dev TODOs
and update. Then run:
forge test -vvv --ffi
To deploy DiscountPublicationAction.sol
smart contract, prepare the following constructor arguments:
hub
- The address of a Lens' LensHub smart contractmoduleRegistry
- The address of a Lens' ModuleGlobals smart contractrouter
- The address of a Chainlink Functions Router smart contractsubscriptionId
- The ID of your Chainlink Functions subscription which you can create at Functions Subscription Manager following steps from the Official DocumentationcallbackGasLimit
- The maximum gas that Chainlink Functions can use when transmitting the response to your contract. We recommend going with 300000 for now.donIdBytes32
- The ID of a Chainlink Functions DON to be invoked. The docs list the Don Id as a string or a bytes32 hex. Copy the bytes32 hex, or you want to convert programmatically yourself, runcast --format-bytes32-string "fun-polygon-mumbai-1"
or via etherjs withnode getDonIdBytes.js fun-polygon-mumbai-1
.
Then run the forge create
command:
forge create --rpc-url <your_rpc_url> \
--private-key <your_private_key> \
--constructor-args <hub> <moduleRegistry> <router> <subscriptionId> <callbackGasLimit> <donIdBytes32> \
--etherscan-api-key <your_polygonscan_api_key> \
--verify \
--legacy \
src/DiscountPublicationAction.sol:DiscountPublicationAction
Make a note of your deployed contract.
Navigate to your Chainlink Functions subscription at Functions Subscription Manager and add this newly deployed smart contract as your subscription's consumer by clicking the Add Consumer
button and providing the address of a smart contract.
Then Head to the Lens V2 ModuleGlobals Contract on Mumbai and from the Contracts
tab, click on Write as Proxy
. Connect your wallet to the page, and then call registerModule
with the following arguments:
moduleAddress
: the Open Action with Functions contract you just deployedmoduleType
: 1 (Enum for Open Action) (ref)
Finally, we want to encrypt the secrets that will be injected by the Chainlink DON into the ./contracts/source.js
script.
Make sure you're in the ./contracts
director and run node generateSecrets.js
. This will take the secrets that you've set in the .env.enc
file, and encrypt them with the DON public key so that it can only be Decrypted by Chainlink DON Nodes. These decrypted secrets get uploaded and stored in the DON and then injected at run time into the script in ./contracts/source.js
. Please inspect ./contracts/generateSecrets.js
to understand more.
When the secrets have been successfully uploaded your console print info that looks like the following:
❯ node generateSecrets.js
secp256k1 unavailable, reverting to browser version
Version: 1699842119
Slot ID: 0
Make a note of the Version and Slot ID. You will need to update the webapp code with this.
Navigate to the app
folder and create a .env
file there and double check it is gitignored
.
Then add the following values to your .env
:
VITE_ORG_ID
VITE_EVENT_ID
You would have obtained these secrets when running the setup steps for your Open Actions With Functions Smart Contract.
Run npm install
from inside your project root. If dependency clashes arise please run `npm install --force``
Then run `npm dev`` to start the server.
- For all these steps, please note the
TODO @dev
instructions in the file.
To begin, make sure you login on the front end app, using the wallet that you created your Lens / Hey profile with.
-
Once your profile is created go to
useProfile.tsx
in./src/profiles
. Update theTODO @dev
comment there with your profile handle and that should trigger the web app to render your profile if you navigate tolocalhost/profiles/useProfile
. -
Then open the
./app/src/publications/UseOpenAction.tsx
file. Update theTODO @dev
comments. You'll need the values from when you uploaded your app secrets to the DON. -
Once you've saved the file with your updates, navigate to
http://localhost:PORT/publications/useOpenAction
and enter the Open Action With Functions Smart Contract contract address that you had deployed. Create your publication by clicking the CREATE SAMPLE POST button. Note you will have to sign 2 transactions - one to upload your post to Arweave and the other to initialize your Open Actions with Functions smart contract.
If you open your browser dev tools, you can see the logs that contain info about the post upload to Arweave and other inputs that will be sent to the blockchain in subsequent steps.
-
When your Open Action is published and finalized on the blockchain, you will see a button to interact with the Open Action that is mounted to your publication. To check your publication on the Hey app you can navigate to
https://testnet.hey.xyz/u/<<YOUR_LENS_V2_PROFILE_ID>>
in a new tab to see your posts. -
Click on the GET DISCOUNT CODE button and sign the transactions. If you look at your chrome dev tools you will see the giant bytecode that contains the data that is submitted to
processPublicationAction
in your Functions-enabled publication contract. -
You can wait about 30 seconds or so for the UI to update with the event URL and the discount code applied. Alternatively got to the Mumbai blockexplorer at
https://mumbai.polygonscan.com/address/YOUR_CONTRACT_ADDRESS
, click on "READ" and take a look at the requestID and then thes_lastResponse
field. If that is0x
then there has been an error (and no discount URL will show up on the front end). You can check the error on the block explorer by clicking ons_lastError
. The bytes hex shown there can be decoded into its string using this converter tool.
If successful the UI will look like this:
This tutorial offers educational examples of how to use a Chainlink system, product, or service and is provided to demonstrate how to interact with Chainlink’s systems, products, and services to integrate them into your own. This template is provided “AS IS” and “AS AVAILABLE” without warranties of any kind, it has not been audited, and it may be missing key checks or error handling to make the usage of the system, product, or service more clear. Do not use the code in this example in a production environment without completing your own audits and application of best practices. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs that are generated due to errors in code.