{"id":19107411,"url":"https://github.com/smartcontractkit/functions-lens-eventbrite","last_synced_at":"2025-04-30T18:46:44.319Z","repository":{"id":197992269,"uuid":"697058088","full_name":"smartcontractkit/functions-lens-eventbrite","owner":"smartcontractkit","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-19T08:52:15.000Z","size":2137,"stargazers_count":12,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-19T08:10:32.630Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartcontractkit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-27T01:06:30.000Z","updated_at":"2024-02-03T03:03:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"d8ada159-7731-431a-8087-dcf24ee3d3a7","html_url":"https://github.com/smartcontractkit/functions-lens-eventbrite","commit_stats":null,"previous_names":["smartcontractkit/functions-lens-eventbrite"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Ffunctions-lens-eventbrite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Ffunctions-lens-eventbrite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Ffunctions-lens-eventbrite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Ffunctions-lens-eventbrite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartcontractkit","download_url":"https://codeload.github.com/smartcontractkit/functions-lens-eventbrite/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251765367,"owners_count":21640178,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T04:12:33.535Z","updated_at":"2025-04-30T18:46:44.281Z","avatar_url":"https://github.com/smartcontractkit.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Functions Lens Eventbrite\n\nThis project combines [Chainlink Functions](https://docs.chain.link/chainlink-functions) with [Lens Publication Actions](https://docs.lens.xyz/v2/docs/publication-actions-aka-open-actions) to demonstrate how one can generate discount codes for events on Eventbrite using Collect module.\n\n## Prerequisites\n\n- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)\n- [Current LTS Node.js version](https://nodejs.org/en/about/releases/)\n- [Foundry](https://book.getfoundry.sh/getting-started/installation)\n- Fund your wallet with some [LINK](faucets.chain.link)\n- Connect your wallet and get a Lens profile from [this URL](https://testnet.hey.xyz/). Make sure your wallet is connected to Polygon Mumbai and that you have[ Matic in your wallet](https://faucet.polygon.technology/).  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.\n\n![lens-profile](./img/hey-lens-app-testnet.png)\n\n\n## Getting Started\n\n1. Install smart contract packages\n\n```\ncd contracts \u0026\u0026 npm install\n```\n\n2. Compile contracts\n\n```\nforge build\n```\n\n3. Install UI packages\n\n```\ncd ../app \u0026\u0026 npm install\n```\n\nIf dependency clashes arise please run `npm install --force`\n\n4. Start the server\n\n```\nnpm run dev\n```\n\n## What are we building?\n\nUsing 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.\n\nThe event organizer will need to create a new event on Eventbrite, following [these instructions](https://www.eventbrite.com/help/en-us/articles/551351/how-to-create-an-event).\n\n![event](./img/event.png)\n\nTo develop and use this project, you will need to obtain a [free Eventbrite OAUTH token](https://www.eventbrite.com/help/en-us/articles/849962/generate-an-api-key/).\n\nOnce 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=\u003cYOUR_OAUTH_TOKEN_GOES_HERE\u003e`\n\nNext, you will need to get your\n\n- **Organization ID**, by visiting `https://www.eventbriteapi.com/v3/users/me/organizations/?token=\u003cYOUR_OAUTH_TOKEN_GOES_HERE\u003e`\n- **Event ID**, by visiting `https://www.eventbriteapi.com/v3/organizations/\u003cORGANIZATION_ID_GOES_HERE\u003e/events/?token=\u003cYOUR_OAUTH_TOKEN_GOES_HERE\u003e`\n\nThe core logic is stored in the [`DiscountPublicationAction.sol`](./src/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`](./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`](./src/DiscountPublicationAction.sol) smart contract will then store the returned discount code.\n\n![discount](./img/promoCodes.png)\n\n## Usage\n\nFor setting up environment variables we are going to use the [`@chainlink/env-enc`](https://www.npmjs.com/package/@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.\n\n1. Change into the `./contracts` directory to set up its dependencies. Make sure commands in [this USAGE SECTION](#usage) are run from inside this directory. Start with `npm install` if you've not done that yet.\n\n```shell\ncd contracts\n```\n\n2. Set a password for encrypting and decrypting the environment variable file. You can change it later by typing the same command.\n\n```shell\nnpx env-enc set-pw\n```\n\n2. Now set the `OAUTH_KEY`, `PRIVATE_KEY` and `POLYGON_MUMBAI_RPC_URL` environment variables by typing:\n\n```shell\nnpx env-enc set\n```\n\nAfter you are done, the `.env.enc` file will be automatically generated.\n\nIf you want to validate your inputs you can always run the following command:\n\n```shell\nnpx env-enc view\n```\n\n3. Run local simulation\ncheck the `./contracts/test/DiscountPublicationAction.t.sol` file for `@Dev TODOs` and update. Then run: \n\n```\nforge test -vvv --ffi\n```\n\n![test](./img/test.png)\n\n## Deployment\n\nTo deploy [`DiscountPublicationAction.sol`](./src/DiscountPublicationAction.sol) smart contract, prepare the following constructor arguments:\n\n- `hub` - The address of a Lens' [LensHub](https://docs.lens.xyz/docs/deployed-contract-addresses#mumbai-testnet-addresses) smart contract\n- `moduleRegistry` - The address of a Lens' [ModuleGlobals](https://docs.lens.xyz/docs/deployed-contract-addresses#mumbai-testnet-addresses) smart contract\n- `router` - The address of a Chainlink [Functions Router](https://docs.chain.link/chainlink-functions/supported-networks) smart contract\n- `subscriptionId` - The ID of your Chainlink Functions subscription which you can create at [Functions Subscription Manager](https://functions.chain.link/) following steps from the [Official Documentation](https://docs.chain.link/chainlink-functions/resources/subscriptions)\n- `callbackGasLimit` - The [maximum gas](https://docs.chain.link/chainlink-functions/api-reference/functions-client) that Chainlink Functions can use when transmitting the response to your contract.  We recommend going with 300000 for now.\n- `donIdBytes32` - The ID of a Chainlink Functions [DON to be invoked](https://docs.chain.link/chainlink-functions/supported-networks). The docs list the Don Id as a string or a bytes32 hex. Copy the bytes32 hex, or you want to convert programmatically yourself, run `cast --format-bytes32-string \"fun-polygon-mumbai-1\"` or via etherjs with `node getDonIdBytes.js fun-polygon-mumbai-1`.\n\nThen run the `forge create` command:\n\n```\nforge create --rpc-url \u003cyour_rpc_url\u003e \\\n    --private-key \u003cyour_private_key\u003e \\\n    --constructor-args \u003chub\u003e \u003cmoduleRegistry\u003e \u003crouter\u003e \u003csubscriptionId\u003e \u003ccallbackGasLimit\u003e \u003cdonIdBytes32\u003e \\\n    --etherscan-api-key \u003cyour_polygonscan_api_key\u003e \\\n    --verify \\\n    --legacy \\\n    src/DiscountPublicationAction.sol:DiscountPublicationAction\n```\n\nMake a note of your deployed contract.\n\nNavigate to your Chainlink Functions subscription at [Functions Subscription Manager](https://functions.chain.link/) 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.\n\nThen Head to the [Lens V2 ModuleGlobals Contract on Mumbai](https://mumbai.polygonscan.com/address/0x8834aE494ADD3C56d274Fe88243526DBAB15dEF8) and from the `Contracts` tab, click on `Write as Proxy`. Connect your wallet to the page, and then call `registerModule` with the following arguments:\n\n- `moduleAddress` : the Open Action with Functions contract you just deployed\n- `moduleType`: 1 (Enum for Open Action) ([ref](https://docs.lens.xyz/v2/docs/publishing-a-module))\n\nFinally, we want to encrypt the secrets that will be injected by the Chainlink DON into the `./contracts/source.js` script.\n\nMake 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.\n\nWhen the secrets have been successfully uploaded your console print info that looks like the following:\n\n```\n❯ node generateSecrets.js\nsecp256k1 unavailable, reverting to browser version\nVersion: 1699842119\nSlot ID: 0\n```\n\nMake a note of the Version and Slot ID. You will need to update the webapp code with this.\n\n## Web App and its Environment Variables\n\nNavigate to the `app` folder and create a `.env` file there and double check it is `gitignored`.\n\nThen add the following values to your `.env`:\n\n```\nVITE_ORG_ID\nVITE_EVENT_ID\n```\n\nYou would have obtained these secrets when running the setup steps for your Open Actions With Functions Smart Contract.\n\nRun `npm install` from inside your project root. If dependency clashes arise please run `npm install --force``\n\nThen run `npm dev`` to start the server.\n\n## Front end interaction steps\n\n1. For all these steps, please note the `TODO @dev` instructions in the file.\n\nTo begin, make sure you login on the front end app, using the wallet that you created your Lens / Hey profile with.\n\n2. Once your profile is created go to `useProfile.tsx` in `./src/profiles`. Update the `TODO @dev` comment there with your profile handle and that should trigger the web app to render your profile if you navigate to `localhost/profiles/useProfile`.\n\n3. Then open the `./app/src/publications/UseOpenAction.tsx` file. Update the `TODO @dev` comments. You'll need the values from when you uploaded your app secrets to the DON. \n\n4. 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.\n\nIf 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.\n\n5. 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/\u003c\u003cYOUR_LENS_V2_PROFILE_ID\u003e\u003e` in a new tab to see your posts.\n\n6. 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.\n\n7. 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 the `s_lastResponse` field. If that is `0x` 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 on `s_lastError`. The bytes hex shown there can be decoded into its string using [this converter tool](https://codebeautify.org/hex-string-converter).\n\nIf successful the UI will look like this:\n![event](./img/success.png)\n\n## Disclaimer\n\nThis 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Ffunctions-lens-eventbrite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartcontractkit%2Ffunctions-lens-eventbrite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Ffunctions-lens-eventbrite/lists"}