From 36c0849497f0f3257ebbc7379882f5363c590211 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?txb=C3=AC?= <46839250+0xTxbi@users.noreply.github.com>
Date: Wed, 19 Feb 2025 22:46:34 +0100
Subject: [PATCH] feature(airdrops): Foundational setup (#15545)
* add package.json
* add .gitignore
* set up eslint
* set up providers
* set up next config
* set up public resources
* set up nextjs
* clean up
* set up tailwind
* update monorepo
* update yarn.lock
* update yarn.lock
---
airdrops/.gitignore | 37 ++++++++++++++
airdrops/app/globals.css | 7 +++
airdrops/app/layout.tsx | 35 +++++++++++++
airdrops/app/page.tsx | 3 ++
airdrops/components/providers.tsx | 18 +++++++
airdrops/eslint.config.js | 13 +++++
airdrops/next.config.js | 9 ++++
airdrops/package.json | 55 +++++++++++++++++++++
airdrops/postcss.config.js | 6 +++
airdrops/public/favicon.ico | Bin 0 -> 7406 bytes
airdrops/public/fonts/inter-400.woff | Bin 0 -> 43980 bytes
airdrops/public/fonts/inter-700.woff | Bin 0 -> 47744 bytes
airdrops/public/images/svg/unlock-logo.svg | 8 +++
airdrops/public/robots.txt | 2 +
airdrops/tailwind.config.js | 10 ++++
airdrops/tsconfig.json | 28 +++++++++++
package.json | 3 +-
yarn.lock | 38 ++++++++++++++
18 files changed, 271 insertions(+), 1 deletion(-)
create mode 100644 airdrops/.gitignore
create mode 100644 airdrops/app/globals.css
create mode 100644 airdrops/app/layout.tsx
create mode 100644 airdrops/app/page.tsx
create mode 100644 airdrops/components/providers.tsx
create mode 100755 airdrops/eslint.config.js
create mode 100644 airdrops/next.config.js
create mode 100644 airdrops/package.json
create mode 100644 airdrops/postcss.config.js
create mode 100644 airdrops/public/favicon.ico
create mode 100644 airdrops/public/fonts/inter-400.woff
create mode 100644 airdrops/public/fonts/inter-700.woff
create mode 100644 airdrops/public/images/svg/unlock-logo.svg
create mode 100644 airdrops/public/robots.txt
create mode 100644 airdrops/tailwind.config.js
create mode 100644 airdrops/tsconfig.json
diff --git a/airdrops/.gitignore b/airdrops/.gitignore
new file mode 100644
index 00000000000..7ef847c931f
--- /dev/null
+++ b/airdrops/.gitignore
@@ -0,0 +1,37 @@
+# dependencies
+/node_modules
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# next builds
+/src/.next
+.next
+/out
+.next/cache/**
+next-env.d.ts
+scripts/paywallURL.ts
+scripts/index.html
+
+# Sentry
+.sentryclirc
+.vercel
+
+certificates
+
+# tsbuild logs
+tsconfig.tsbuildinfo
\ No newline at end of file
diff --git a/airdrops/app/globals.css b/airdrops/app/globals.css
new file mode 100644
index 00000000000..7bae7731ead
--- /dev/null
+++ b/airdrops/app/globals.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ @apply bg-ui-secondary-200;
+}
diff --git a/airdrops/app/layout.tsx b/airdrops/app/layout.tsx
new file mode 100644
index 00000000000..9c3c50fb6cf
--- /dev/null
+++ b/airdrops/app/layout.tsx
@@ -0,0 +1,35 @@
+import { Inter } from 'next/font/google'
+import './globals.css'
+import { Metadata } from 'next'
+import Providers from '../components/providers'
+
+const inter = Inter({
+ subsets: ['latin'],
+ style: ['normal'],
+ display: 'swap',
+ weight: ['400', '500', '600', '700'],
+})
+
+export const metadata: Metadata = {
+ icons: {
+ icon: '/favicon.ico',
+ },
+}
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+
+
+
+
+
+
+
+ )
+}
diff --git a/airdrops/app/page.tsx b/airdrops/app/page.tsx
new file mode 100644
index 00000000000..8a5d3176b7b
--- /dev/null
+++ b/airdrops/app/page.tsx
@@ -0,0 +1,3 @@
+export default function Home() {
+ return
Unlock Airdrops
+}
diff --git a/airdrops/components/providers.tsx b/airdrops/components/providers.tsx
new file mode 100644
index 00000000000..b36166abbf9
--- /dev/null
+++ b/airdrops/components/providers.tsx
@@ -0,0 +1,18 @@
+'use client'
+
+import { PrivyProvider } from '@privy-io/react-auth'
+
+const Providers = ({ children }) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export default Providers
diff --git a/airdrops/eslint.config.js b/airdrops/eslint.config.js
new file mode 100755
index 00000000000..d7368cace16
--- /dev/null
+++ b/airdrops/eslint.config.js
@@ -0,0 +1,13 @@
+const unlockConfig = require('@unlock-protocol/eslint-config/next')
+module.exports = [
+ ...unlockConfig,
+ {
+ ignores: ['src/**/*.typegen.ts', 'tsconfig.json'],
+ },
+ {
+ rules: {
+ 'react/no-children-prop': 'off',
+ 'no-constant-binary-expression': 'warn',
+ },
+ },
+]
diff --git a/airdrops/next.config.js b/airdrops/next.config.js
new file mode 100644
index 00000000000..8ff106bd994
--- /dev/null
+++ b/airdrops/next.config.js
@@ -0,0 +1,9 @@
+/** @type {import('next').NextConfig} */
+const config = {
+ images: {
+ unoptimized: true,
+ },
+ output: 'standalone',
+}
+
+module.exports = config
diff --git a/airdrops/package.json b/airdrops/package.json
new file mode 100644
index 00000000000..068e6ba4aa9
--- /dev/null
+++ b/airdrops/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "@unlock-protocol/airdrops",
+ "version": "0.1.0",
+ "private": true,
+ "peerDependencies": {
+ "react": "18.3.1",
+ "react-dom": "18.3.1"
+ },
+ "dependencies": {
+ "@headlessui/react": "2.1.9",
+ "@privy-io/react-auth": "2.2.1",
+ "@sentry/nextjs": "8.54.0",
+ "@tanstack/react-query": "5.59.19",
+ "@tw-classed/react": "1.7.0",
+ "@unlock-protocol/core": "workspace:./packages/core",
+ "@unlock-protocol/crypto-icon": "workspace:./packages/crypto-icon",
+ "@unlock-protocol/eslint-config": "workspace:./packages/eslint-config",
+ "@unlock-protocol/networks": "workspace:./packages/networks",
+ "@unlock-protocol/ui": "workspace:./packages/ui",
+ "@unlock-protocol/unlock-js": "workspace:./packages/unlock-js",
+ "@vercel/og": "0.6.5",
+ "@vercel/speed-insights": "1.0.14",
+ "dayjs": "1.11.13",
+ "embla-carousel-react": "8.5.2",
+ "eslint": "9.11.1",
+ "next": "14.2.21",
+ "react-hot-toast": "2.4.1",
+ "tailwind-merge": "3.0.1",
+ "typescript": "5.6.3"
+ },
+ "devDependencies": {
+ "@types/react": "18.3.18",
+ "@unlock-protocol/tsconfig": "workspace:./packages/tsconfig",
+ "@vitejs/plugin-react": "4.3.4",
+ "autoprefixer": "10.4.20",
+ "jsdom": "26.0.0",
+ "postcss": "8.4.49",
+ "tailwindcss": "3.4.17",
+ "vitest": "2.1.9"
+ },
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build --no-lint",
+ "deploy": "yarn build && next export -o out",
+ "start": "yarn build && NODE_ENV=production next start",
+ "test": "UNLOCK_ENV=test vitest run --coverage --environment=jsdom",
+ "lint": "eslint",
+ "ci": "yarn test && yarn lint && yarn build"
+ },
+ "browserslist": [
+ "defaults",
+ "not IE 11",
+ "maintained node versions"
+ ]
+}
diff --git a/airdrops/postcss.config.js b/airdrops/postcss.config.js
new file mode 100644
index 00000000000..33ad091d26d
--- /dev/null
+++ b/airdrops/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/airdrops/public/favicon.ico b/airdrops/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..3c136c0b2e10c292a7aef83e28cc6773ca35fd61
GIT binary patch
literal 7406
zcmeI02UL_-7RUcgp({lY&=Kh>XD{Q8bKo6gwg+q9Pr^-s{HLHi>R5
ziDeTtt0-a@>(z4-}Km)U>KRN(>}h0nNyUnqVj;){cuoRmOjH-aS9~xe}$69=@tXIi=(0
zE@I8Lo%l!L6;!;fgjlSLZ|S-BfI+xg_5|y9?187RANCzPft!zi!j?VzaQfP9)T?g-
ze_0R?o;U+XXBU{6o8!SxZ*b&v5mGXjqFe8N*!9&nIDWPW4Xvyp5{Yo~Vlgt7uYs4Z
zKQ`^!i;{{Lu(h+tm`PJ``^gJLMGwcFXRmOV(!A76oV#%!%QkF9`m$B{^5}QSS-k;%
z0fA%}gQUgjm`lmQ$r<;5e2oPex%B=@xHfNroqzut7w$Yn*)KFtN-QfQIu{!`58%z
z(y$;s2QJOr5ZSX2_0tf+p=}@#2++KxJ7UL9gon2;((_m0digVaf4KxEre-*F>MRDw
z#A3(3gJ@u3fuL5QD1BLpGD=4aE~5N(B_2__e7^!#HjQ9SDYRV}eyFU3uC6XN?))65
zF5iHigCpvjn4sYLZ6v2
z+q)lUuHT_{cX04z0S-}`G$Rp3x60@oy~V<;JnTAf1efkTf|a!mL}D>UD8|uwx=d$D
zjO!1d;nbxPWUg3?EK1&fQuH4jjs3?@p=0Mr%wLiP^9B|Ol!xM*)8`RHd7b<*DQ>GbKml@@Ih6}$yJS;t2J7=j%i5}tKDH`3B>HO1bS=5OU4OyMSQ)_n0Ib7GEt(H#Rn^G^I
z*^dm?o?Q4wrkiP|8KT-+CJV6{&gvrDY1_-zGu^U!wb^g&&g!-}RkI)Tk?fVq_?~<`
z+Xl*&?$)z`mSIfSw6~q%YVAD}wDh)}HhcuDo0>
zs+OcO9Xe05buia@gEDA~tIxK6J6npFKVw+$;DXNZJ4?~Ve03i(s*FP+c2@zB0}=>Ij3?d6vK)%N}U
z_JTZ*p#cF&y4vSlCYzfS5D<{7eKs}6LcmWYVXL|)Q`9{cg;o|
zIB|wEssr(nUz<5PQLQ^u#Ax^_nd
zCB~;I#Hox)S8e%}bLrL6CmJSY9D17=l(8sd&>+r*mLL@rp=kpSu=L*1mZ*=
zV#KG!&|g5IoI(s+kMpLzqZ7g-yWwo{9h@t1?)a>m@}xAjSaplx`sYcgCVhPO5FH2vzq
z^wPa@xO@2^EpH{~&>Iy`i4{-M{=PtXmu|TG{1u#BTseOpIbF#4ld)$_)?}R7f%x+7
z^VcZ6`2fo437j*RZ``InZFTvdbOogUQz5(%y!V9)QEZcbGlLh%6t$TM2BeQ^Vdv62
z)3tRw>)&=Fm>=N4od6&qDNItc3xRRRN$++bXvpjuJqWy)Q1#MbjVAapS303-Y_%~c
z26rW`Q~Tixg}r%l0?^+`rfnd0Bi+b>Vx|*!HznKLY9kP|C6!RsL_C>{vqH7oXA?i_
zNAu=Vscha1ph24U2<^!yH|#5_Y9ezUO}=lF57$R()eFY<@u&7tO8VoH=r#X@?uNPJ
z;#4D0q-V@Yr1z6|&t=N^EXmFiPsvwRN5gYXJ(9gzV`ica#DM#OFXas$EaSa
zX87MOXl>|6d1QVH`@h&x()cM_z6mKclD%>bk2SM9z3|38x*y;0II}E7PWSdvx~EFP
z?!&B=YcX$0CgKy4cpNx7b~L6X&PPG7*i`<}(?nUBEY+bo{DV$*iSO`ObQt1PB_@oqWA>%SzM(cBO4^zq}d
z=eUXS$XmCW-?Q`6vUp6N#h{tb#Nx2*PM@2a!DGymXU#!aL>C@oUb}rKq=CVhos!D$
zV0Kq0r)MH#*=io&A2cimYq#&>KGLXh6Zrkkd2RJmZQHhO+jcUsZ5uPOZQJG~nItd2|NoqO&UtISd*AK#RoAN8
zRo%N)RlUF3?($+{03g73shR{Jd?O&Agm3y^oPW6gy@-p5ihT>%eDi*NV+=heJr8jO
zd1U|qm<9mAfd&99x+jIo5X6;Lg#Z9N4gdgN762e+P^0E&lUJr^0sv?uzI9c%0$fAB6qs?80Zzj@3W-!hQ@0SM+c
zo@U=X0|3C92mqLbayJNrvM@C?0RVDCzGc|{0onmWQHyWpH?RAfCin&tyeDKY3tJbD
zZ{8*V09p+Iz%}O-`|sJ<8-L3ceSbgjR{#J)$NVUB)z;ACyWh%x+Qa!rA7mH^+|JO}
z^qZIeJ$|_FaicMiC<-{(JG*?(U;VcX@;`E)%z$4GPNv_wRfFFMsG9uw-ZPC7`c
z4hld3-Obqwu@+^b!=<{uhLvvbk`_XGb9ZP9<359OW4hTIB}YK?zY`;sBUtjOaaqt?
zD|vSkqaT#qfLMee*~?2#KnJv=6{qY
z2E(dpU=dWd%q(5-p)DlU5~6NNQnQAwSpi?Kta+4~IgQ<(J6$YUAu!8g@mWSOGggeL
zB^K}h@Yz4bRMyB=WFmSBv@$4N#v3jgFm50^zF#PSWiAhuwKR@Xbuu(0jpc(?iuYtV
zK1!!wYBrYaX-NMvo=NS@%qJVXj_66&A~K~ak&XJ$luhWg&i=g^7a~FOwazl}*s^A*
zr*NPv4LwBul&tKtp5DYT=~QuK7R)wm+Q?(|v1Qsw-(cHB@5rG;HnKCV>f%opW&W%0
zH|xk#IrmDemdf=$TxW1@+ZOUBJr<9>x0zz*ZieXgvl*`R9Zp`GXwlmN_*c_Y+{;k+
z0Y$IgSFIEsO~-8d$w%^hGE}$DEUl2|14gsIAYV!BD~i65VSjPR3$iz5?_gH)ev%r=
zN9CWSE|R`d>_d{n$1(gx6}kGg_t#*kd*b_cE#XiFOrH`BU9d*o{y5?I<{AH&6R;7*dkHsIfAhcc0>uM&{Sn4j`
zbHVHNg=Nutu-^LTLmgW5!jdYILU*70A7Xm*k&lpF37h&}q#c^jmRy
z6S69CNQ%zIY++LEe`Z;oW>WQ~;7>qM`gzjG+DiE0PcN{9Drxrl$@0a-%#~WIL*&AA
zZ*oNix*BAYG7QhJQH+lyJgjlJ!FL7pjFWbSLU@Sh_H#cFsCz`v?;rX6&>yRMweq9v
z3(%jg+jD+(HDT-v+!6MDxm$S^`$S86b(IjO{K7>g0as0k5Y=uL=HWtM=0b$_LZW^%
z1lW|5$z_Y{U<4*Q7_$ujigqMHWR^rSGsa7507P3nm5@MBNV2IRfnC(&ajr&8S%h7Y
z;CB@i0nqoE{y37>3L@4Lo3>}99H=P;Zb*_|4}z5U4|t$l-EriKkn_Z{&!XNW{r14e
zH-O|L7xa;=ykqqfg!DJ$7yHr4AUYVuA%m)BIOI|gm6lG(G6(J~;y#B9Eh0aM3@wU3
z2N69;zz7*FssP#`GKs?6pi+%|(GW9qE4|7v$vF?tj&Hg{_v?TS2@Eh}C2Pn%88bu@
znsV`+Kk0)(q1>u|Oxp#^X*+OOJUKau5q8kUgcnj^(DOyvdlg1^$H=;KgIH}Q#$1GH
zSv;&d=SwJ3H>`SAbnsa~klJEiS+lS|e>&7og+iuXxnEtA+G^&k&D^S1yB$?ikgDY?
zo?|u;kRYjx^j6j=1G%;+;@CYZ9p@F?=8<(aX`nbN7OmN@l-7`qT5W==A7axfvI*P2
z;m9Uq4$ho0WOK~$({s{XFk5!4jCmq#e|D#D!s_0ImwmO#{xpwo_BqV34&mMzUo0$v
zJ9vUte~MKl!ClNy#bVE1T5B$ot+@n(_iV__W*W_AOwC5t{%!WB?P}W9YOdequei&>
z>C67w%i-&kCJ66)+TJPmwX6Y-Y+{b2B92VsKX^MQ5PuVZU`!Cmosh_#vCMCgrw?hS
zk8!4tc&1N)=?;nLj*;j{CrovwQFX>tb-w#{pj}}MDS$ENATB@jvfJgmJ^{izG{oCe
z#5-`z-IdJUx6Iws+*XS2S2
zVd3k{F^QXF!90V+JjbVHA@UD2GY`P@8=p`{G21asXWNcsTj9Nza-80S84C8k6_Q5=
zjOt?aD(X=s_wo%P%NL*P+lDcRa(IV?czcZRc}RRyO*}Ku5sdWusb_qTrtafw#I-D)
zJ~cFzktHY+h>4{H{OBo*hu+QULMfS&dphp(H0S>Nvv~lej$-!aYKY
zT|6?)J#*1Dn3ttURZ_2o_1(&{d5hEHrXQm#WUBNqppsg;b9pZFtWecUJMXqQlDz^T
zH0jK#HO8oVccpvxtt%sk{?%iEP!vUJ2-ji>-jk((a3)3F@^}TTt)>0O|6FbijGyG@
zN{H?{MURyd)2UhQ8QSg1?|7f$Qz>;!{$O{8
zwmvCe7_2%l}uB(48WbB}koahN;Y1}VI5+~zg4>?WJ(Amc{
z;_MT1-CY5LZI<<$Mv7Q4uJvl#O?wDrU%=htV@xwcD4t#>{h>)(gb!d9Rp&rtM=M;2@g`0?);*arh@N0)KTw&iJDvkdIot2@0wqdn~_>H3p-lq@Uhj4SCs
zL=EdyCK#BOm|Qv4oncX1Sx2Lr{AIJHB52qX(Dm)E8%?$}S6G$d+(Xg!tt6?n7Q$K|
z^T~TwW2V-EXxE}@&Sdf58eumYaW@v?aaR*_Rx@;0Q@2)goSqHjdxzRy>1r$M+in@)
zP9WnBDdLVXdPiPff%r-M!`ujhC61{>|E~?DN%3DD`tHE@_B;rWgmBLganG0$&meNo
zs4~wmb5Cj7XCvoU1L@X%P`N`AxnmT$BNjPx2Fz)VqL-;-eP2)Yt@VRiYB`UZTdpvM
z6hjzu(A1cJZ14XvoswDwx5~bwt(PGe)LdeJK&IP#2+@hBid(jy={bvf)vwH#9<(p|
zE-&9k{c|v%H_MNtrtmB7M3SRrw`@$kxQ9_GbWALoYNJMC
zPvQdF&DV{k@0Yc2_E<-?Kgs-C$k*sHdP#96%@ZthZwCCtQ`)P&ia4g>aPs72?T1^c
z>rSm#_#p6u+sz#x{w*Q?9b?`tW!@cU%O5l2V0&xmWxnKuRyT))_|wVESKFr1vF!U9
zE3@})xTby=GX~_Z{{M8n=_R>+84Kl}{W4|~Rg-G+rdTheH?veFvy8sY2Uw&PlL^tD
z{h6CK45ckbtHnj{_P3{Rd$uJ^Ihd0sXiXUdI>(H8U{bdh1;i-}-z_I=PMX0vXN>ru
zk-QLYgN3CW5Y3|~NFWZSD1>(|7V*JaNDxa=7BR|NNHJ$7vm?{1e+>K&wfb4!5hAoM
zh(xzax~Fn^5UlwKrSSx}MfnT7eu@%~+{h)>Ig-jrHhEL6C+_Lxk9D%1DUBWMn7>{5
zhuaj3TZ?{#C{Z0s)YS2%OtI)W`c|&cD_BlVBZQ{$nWK5Z@L`hP=y}$+oTe`G;?rG=nCkb37_4&I}QHR(pyw+F>;HRWzC!{@Fi=5Ao_s;BO1;6A$io$C{A|A5;&
zp?5jOcRAsAIRk_lh%;`8GmVHdrie2Y|A+Ad^Opd)Bh82-k9mpExy|&R5Zyl0
z^^Et;3j+KDWc)ow`~#@`J&ODT%*;K`KYsrniT(kq?jEb|0i5|yYU`)9-+;YmxVvZk
z%WDAqYef932(@bK-1T3ETy)q7^A0gT1lTD4h`1&{pH)IG!cR??!YAgI-l}A3T4dS6
zN-b#f%W0pAACrt^D?z+2w!6A->bV!mT!z9VM7_+WS836`_IRz7j
zAl1bCpGP+IEnk%8*!p5=(9x4Bfrv;JC=^9eCep7qZxh}S7hC_v%bQoNF$F&ZPu<
z>r7DIYc9U$Hq>DXL%U!yrm6o&Kb1L4s%7;nm}5zmyTMeC_V07j>5_g4CHfLsF_0c~
zK0(avik9pNQlsw9&T;x~>eiW`kz?uUQutTtWQK2VH