Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Unlock integration #132

Open
wants to merge 30 commits into
base: integrations
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c88bc8a
feat: create lock initial form
trbutler4 Jul 13, 2023
469ef6e
feat: only show create lock form if wallet connected
trbutler4 Jul 13, 2023
4711325
feat: added unlock provider
trbutler4 Jul 13, 2023
f736a43
feat: able to deploy locks on goerli
trbutler4 Jul 13, 2023
ac3f121
feat: moved unlock contract interaction to hook
trbutler4 Jul 14, 2023
f2fa35e
fix: cleanup up linting warnings
trbutler4 Jul 14, 2023
25c41a4
feat: added graph api key
trbutler4 Jul 17, 2023
6acca27
feat: graphclient integrated, pulling rough data to initial component
trbutler4 Jul 19, 2023
306608b
feat: lock name displayed on user locks component
trbutler4 Jul 19, 2023
6f91360
feat: query based on connected wallet
trbutler4 Jul 19, 2023
9a9af0f
feat: lock previews redirect to lock id
trbutler4 Jul 19, 2023
8a08331
feat: extract id from url
trbutler4 Jul 19, 2023
ff962ec
feat: barebones lock stats
trbutler4 Jul 19, 2023
ff4101d
feat: rough user keys component
trbutler4 Jul 19, 2023
2bf58da
feat: moved unlock subgraph query functions into hook
trbutler4 Jul 20, 2023
dfa553c
feat: change query endpoint based on connected chain
trbutler4 Jul 20, 2023
f45926e
feat: added lock stats to unlock subgraph hook
trbutler4 Jul 20, 2023
8281d8f
refactor: changed lock deploy logic
trbutler4 Jul 20, 2023
51b45db
feat: lock checkout on lock page
trbutler4 Jul 20, 2023
024160a
feat: added example paywall page
trbutler4 Jul 22, 2023
8261029
feat: formatting, general finalization stuff
trbutler4 Jul 25, 2023
d4fd96e
feat: created readme description
trbutler4 Jul 26, 2023
52f7323
feat: added paywall example button, last minute design tweaks
trbutler4 Jul 26, 2023
db05f49
fix: reran pnpm install
trbutler4 Aug 7, 2023
f75a508
chore: fix conflicts
marthendalnunes Aug 14, 2023
6bde521
feat: redid design and general tweaks
trbutler4 Aug 16, 2023
a304896
feat: handled typescipt rules
trbutler4 Aug 16, 2023
6034ae7
Merge branch 'feat/unlock-integration' into integrations
marthendalnunes Aug 21, 2023
19d52dd
Merge pull request #139 from trbutler4/integrations
marthendalnunes Aug 21, 2023
87f213c
chore: merge changes
marthendalnunes Aug 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,690 changes: 1,690 additions & 0 deletions .graphclient/index.ts

Large diffs are not rendered by default.

1,229 changes: 1,229 additions & 0 deletions .graphclient/schema.graphql

Large diffs are not rendered by default.

13,615 changes: 13,615 additions & 0 deletions .graphclient/sources/unlock/introspectionSchema.ts

Large diffs are not rendered by default.

1,229 changes: 1,229 additions & 0 deletions .graphclient/sources/unlock/schema.graphql

Large diffs are not rendered by default.

1,070 changes: 1,070 additions & 0 deletions .graphclient/sources/unlock/types.ts

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions .graphclientrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sources:
- name: unlock
handler:
graphql:
endpoint: 'https://api.thegraph.com/subgraphs/name/unlock-protocol/{context.network:goerli-v2}'

documents:
- ./integrations/unlock/queries/user-locks-query.graphql
- ./integrations/unlock/queries/lock-stats-query.graphql
- ./integrations/unlock/queries/user-keys-query.graphql
12 changes: 12 additions & 0 deletions app/(general)/integration/unlock/[lockId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ButtonKeyCheckout from '@/integrations/unlock/components/button-key-checkout'
import LockStats from '@/integrations/unlock/components/lock-stats'

export default function UnlockLockPage({ params }: { params: { lockId: string } }) {
return (
<div className="flex flex-col items-center justify-center">
<h1 className="text-4xl font-bold">Lock Stats</h1>
<LockStats lockId={params.lockId} />
<ButtonKeyCheckout lockId={params.lockId} />
</div>
)
}
58 changes: 58 additions & 0 deletions app/(general)/integration/unlock/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'
import { ReactNode } from 'react'

import { motion } from 'framer-motion'
import Image from 'next/image'
import Balancer from 'react-wrap-balancer'

import { IsDarkTheme } from '@/components/shared/is-dark-theme'
import { IsLightTheme } from '@/components/shared/is-light-theme'
import { LinkComponent } from '@/components/shared/link-component'
import { FADE_DOWN_ANIMATION_VARIANTS } from '@/config/design'
import { turboIntegrations } from '@/data/turbo-integrations'

const integrationData = turboIntegrations.unlock

export default function UnlockLayoutIntegration({ children }: { children: ReactNode }) {
return (
<>
<div className="flex-center flex-col items-center justify-center text-center">
<motion.div
animate="show"
className="max-w-3xl px-5 text-center xl:px-0"
initial="hidden"
viewport={{ once: true }}
whileInView="show"
variants={{
hidden: {},
show: {
transition: {
staggerChildren: 0.15,
},
},
}}>
<IsLightTheme>
<Image alt="Starter logo" className="mx-auto" height={100} src={integrationData.imgDark} width={100} />
</IsLightTheme>
<IsDarkTheme>
<Image alt="Starter logo" className="mx-auto" height={100} src={integrationData.imgLight} width={100} />
</IsDarkTheme>
<motion.h1
className="text-gradient-sand my-8 text-center text-4xl font-bold tracking-[-0.02em] drop-shadow-sm md:text-8xl md:leading-[6rem]"
variants={FADE_DOWN_ANIMATION_VARIANTS}>
{integrationData.name}
</motion.h1>
<motion.p className="my-4 text-xl" variants={FADE_DOWN_ANIMATION_VARIANTS}>
<Balancer>{integrationData.description}</Balancer>
</motion.p>
<motion.div className="my-4 text-xl" variants={FADE_DOWN_ANIMATION_VARIANTS}>
<LinkComponent href={integrationData.url}>
<button className="btn btn-primary">Documentation</button>
</LinkComponent>
</motion.div>
</motion.div>
</div>
<section>{children}</section>
</>
)
}
31 changes: 31 additions & 0 deletions app/(general)/integration/unlock/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { WalletConnect } from '@/components/blockchain/wallet-connect'
import { IsWalletConnected } from '@/components/shared/is-wallet-connected'
import { IsWalletDisconnected } from '@/components/shared/is-wallet-disconnected'
import { Button } from '@/components/ui/button'
import FormDeployLock from '@/integrations/unlock/components/form-deploy-lock'
import UserKeys from '@/integrations/unlock/components/user-keys'
import UserLocks from '@/integrations/unlock/components/user-locks'

export default function UnlockIntegration() {
return (
<div>
<div className="flex items-center justify-center">
<a href="/integration/unlock/paywall">
<Button>Paywall Example</Button>
</a>
</div>
<IsWalletConnected>
<h1 className="p-4 text-center text-4xl font-bold">Create a Lock</h1>
<FormDeployLock />
<h1 className="p-4 text-center text-4xl font-bold">Created Locks</h1>
<UserLocks />
<h1 className="p-4 text-center text-4xl font-bold">Owned Keys</h1>
<UserKeys />
</IsWalletConnected>

<IsWalletDisconnected>
<WalletConnect />
</IsWalletDisconnected>
</div>
)
}
11 changes: 11 additions & 0 deletions app/(general)/integration/unlock/paywall/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client'

import PaywallDemo from '@/integrations/unlock/components/paywall-demo'

export default function PaywallPage() {
return (
<div>
<PaywallDemo />
</div>
)
}
4 changes: 2 additions & 2 deletions components/layout/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import { siteConfig } from '@/config/site'
import useScroll from '@/lib/hooks/use-scroll'
import { cn } from '@/lib/utils'

import { NavigationMenuGeneral } from './navigation-menu-general'
import { UserDropdown } from './user-dropdown'
import BranchButtonLoginOrAccount from '../../integrations/siwe/components/branch-button-login-or-account'
import { IsDarkTheme } from '../shared/is-dark-theme'
import { IsDesktop } from '../shared/is-desktop'
import { IsLightTheme } from '../shared/is-light-theme'
import { IsMobile } from '../shared/is-mobile'
import { LinkComponent } from '../shared/link-component'
import { ThemeToggle } from '../shared/theme-toggle'
import { NavigationMenuGeneral } from './navigation-menu-general'
import { UserDropdown } from './user-dropdown'

export function Header({ className, ...props }: HTMLAttributes<HTMLElement>) {
const scrolled = useScroll(50)
Expand Down
9 changes: 8 additions & 1 deletion data/turbo-integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export const turboIntegrations = {
imgLight: '/integrations/connext.png',
imgDark: '/integrations/connext.png',
},

gelato: {
name: 'Gelato',
href: '/integration/gelato',
Expand All @@ -112,6 +111,14 @@ export const turboIntegrations = {
imgLight: '/integrations/moralis.png',
imgDark: '/integrations/moralis.png',
},
unlock: {
name: 'Unlock Protocol',
href: '/integration/unlock',
url: 'https://docs.unlock-protocol.com/?_ga=2.100163804.370043445.1690238160-1370418924.1685652724',
description: 'Smart contracts built specifically for memberships and subscriptions',
imgLight: '/logo-gradient.png',
imgDark: '/logo-dark.png',
},
starter: {
name: 'Starter Template',
href: '/integration/starter',
Expand Down
2 changes: 1 addition & 1 deletion integrations/connext/components/form-connext-xtransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Switch } from '@/components/ui/switch'
import { FADE_DOWN_ANIMATION_VARIANTS } from '@/config/design'

import { Spinner } from './spinner'
import { useApproveIfNeeded } from '../hooks/use-approve-if-needed'
import { useEstimatedAmount } from '../hooks/use-estimated-amount'
import { useEstimatedRelayerFee } from '../hooks/use-estimated-relayer-fee'
Expand All @@ -27,6 +26,7 @@ import { mainnetAssets, testnetAssets } from '../utils/assets'
import { mainnetChains, testnetChains } from '../utils/chains'
import { arbitrumDomainId, arbitrumGoerliId, optimismDomainId, optimismGoerliDomainId } from '../utils/constants'
import { Asset } from '../utils/types'
import { Spinner } from './spinner'

interface FormConnextXTransferProps {
isMainnet: boolean
Expand Down
2 changes: 1 addition & 1 deletion integrations/connext/components/latest-transfers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { useAccount } from 'wagmi'

import { LinkComponent } from '@/components/shared/link-component'

import { Transfer } from './transfer'
import { useLatestTransfers } from '../hooks/use-latest-transfers'
import { Transfer } from './transfer'

interface LatestTransfersProps {
isMainnet: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { FaCopy } from 'react-icons/fa'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { useToast } from '@/lib/hooks/use-toast'

import { getComponent } from '../../utils/get-element-component'
import { issueProofOfHackFormControls } from './controls'
import { useDiscoIssueForm } from './hook'
import { getComponent } from '../../utils/get-element-component'

export function FormCredentialIssuanceProofOfHack() {
const { onSubmit, form, isLoading, isError, isSuccess, error, data } = useDiscoIssueForm()
Expand Down
2 changes: 1 addition & 1 deletion integrations/erc20/components/erc20-write-mint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { TransactionStatus } from '@/components/blockchain/transaction-status'
import { IsWalletConnected } from '@/components/shared/is-wallet-connected'
import { IsWalletDisconnected } from '@/components/shared/is-wallet-disconnected'

import ERC20EventMint from './erc20-event-mint'
import { useErc20MintableMint, usePrepareErc20MintableMint } from '../generated/erc20-wagmi'
import ERC20EventMint from './erc20-event-mint'

interface ERC20WriteMintProps {
address: Address
Expand Down
2 changes: 1 addition & 1 deletion integrations/erc20/components/erc20-write-transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { WalletConnect } from '@/components/blockchain/wallet-connect'
import { IsWalletConnected } from '@/components/shared/is-wallet-connected'
import { IsWalletDisconnected } from '@/components/shared/is-wallet-disconnected'

import ERC20EventTransfer from './erc20-event-transfer'
import { useErc20Transfer, usePrepareErc20Transfer } from '../generated/erc20-wagmi'
import ERC20EventTransfer from './erc20-event-transfer'

interface ERC20WriteTransferProps {
address: Address
Expand Down
2 changes: 1 addition & 1 deletion integrations/gelato/components/active-tasks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { BsSearch } from 'react-icons/bs'

import { Input } from '@/components/ui/input'

import { ActiveTaskPreview } from './active-task-preview'
import { useActiveTasks } from '../hooks'
import { ActiveTaskPreview } from './active-task-preview'

export function ActiveTasks() {
const [search, setSearch] = useState('')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { useFormContext } from 'react-hook-form'
import { FiChevronLeft } from 'react-icons/fi'
import { isAddress } from 'viem'

import { CreateTaskForm } from './create-task'
import { useAbi } from '../../hooks'
import { isValidAbi } from '../../utils/helpers'
import { ValidationError } from '../errors/validation-error'
import { CreateTaskForm } from './create-task'

export type ContractInputProps = {
contractFieldName: 'contractAddress' | 'resolverContractAddress'
Expand Down
6 changes: 3 additions & 3 deletions integrations/gelato/components/create-task/create-task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { useNetwork } from 'wagmi'

import { useEthersSigner } from '@/lib/hooks/web3/use-ethers-signer'

import { useNewTask } from '../../hooks'
import { useMsgSender } from '../../hooks/use-msg-sender'
import { getFunctionSignature, getTotalInterval, getTransactionUrl, sortInputsByOrder } from '../../utils/helpers'
import { ContractInput } from './contract-input'
import { ExecutionValues } from './execution-values'
import { FunctionInput } from './function-input'
Expand All @@ -19,9 +22,6 @@ import { PaymentInput } from './payment-input'
import { ResolverInput } from './resolver-input'
import { RestrictionInfo } from './restriction-info'
import { TaskNameInput } from './task-name-input'
import { useNewTask } from '../../hooks'
import { useMsgSender } from '../../hooks/use-msg-sender'
import { getFunctionSignature, getTotalInterval, getTransactionUrl, sortInputsByOrder } from '../../utils/helpers'

export type CreateTaskForm = {
contractAddress: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { useFormContext } from 'react-hook-form'

import { cn } from '@/lib/utils'

import { CreateTaskForm } from './create-task'
import { getAbiFunctions, validateInput } from '../../utils/helpers'
import { ValidationError } from '../errors/validation-error'
import { CreateTaskForm } from './create-task'

export type ExecutionValuesProps = {
inputFieldName: 'predefinedInputs' | 'resolverInputs'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useFormContext } from 'react-hook-form'

import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'

import { CreateTaskForm } from './create-task'
import { getAbiFunctions } from '../../utils/helpers'
import { CreateTaskForm } from './create-task'

export type FunctionInputProps = {
abiFieldName: 'abi' | 'resolverAbi'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { useFormContext } from 'react-hook-form'
import { Switch } from '@/components/ui/switch'
import { cn } from '@/lib/utils'

import { CreateTaskForm } from './create-task'
import { getTotalInterval } from '../../utils/helpers'
import { ValidationError } from '../errors/validation-error'
import { CreateTaskForm } from './create-task'

export function IntervalInput() {
const [date, setDate] = useState(Date.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { useFormContext } from 'react-hook-form'

import { cn } from '@/lib/utils'

import { CreateTaskForm } from './create-task'
import { GELATO_CONSTANTS } from '../../utils/constants'
import { CreateTaskForm } from './create-task'

export function PaymentInput() {
const { watch, setValue } = useFormContext<CreateTaskForm>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GELATO_CONSTANTS } from '../../utils/constants'
import { ContractInput } from './contract-input'
import { ExecutionValues } from './execution-values'
import { FunctionInput } from './function-input'
import { GELATO_CONSTANTS } from '../../utils/constants'

export function ResolverInput() {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import CopyToClipboard from 'react-copy-to-clipboard'
import { useFormContext } from 'react-hook-form'
import { FaCopy } from 'react-icons/fa'

import { CreateTaskForm } from './create-task'
import { getFunctionSignature, truncateEthAddress } from '../../utils/helpers'
import { CreateTaskForm } from './create-task'

export function RestrictionInfo({ dedicatedMsgSender }: { dedicatedMsgSender?: string }) {
const [copied, setCopied] = useState(false)
Expand Down
2 changes: 1 addition & 1 deletion integrations/gelato/components/rename-task.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useForm } from 'react-hook-form'
import { FaSpinner } from 'react-icons/fa'

import { ValidationError } from './errors/validation-error'
import { useRenameTask } from '../hooks'
import { ValidationError } from './errors/validation-error'

type RenameTaskForm = {
name: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InputValues } from './input-values'
import { getTaskFunctionData } from '../../utils/helpers'
import { InputValues } from './input-values'

export type ResolverValuesProps = {
functionData: ReturnType<typeof getTaskFunctionData>
Expand Down
10 changes: 5 additions & 5 deletions integrations/gelato/components/task-view/task-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import { FaEdit, FaExternalLinkAlt, FaTimesCircle } from 'react-icons/fa'
import { FiChevronLeft } from 'react-icons/fi'
import { useNetwork } from 'wagmi'

import { useAbi, useTask } from '../../hooks'
import { useTaskResolver } from '../../hooks/use-task-resolver'
import { formatFee, getAddressUrl, getTaskFunctionData, truncateEthAddress } from '../../utils/helpers'
import { decodeModuleArgs } from '../../utils/resolverDecoder'
import { RenameTask } from '../rename-task'
import { ExecutingAddress } from './executing-address'
import { FunctionData } from './function-data'
import { InputValues } from './input-values'
import { IntervalValues } from './interval-values'
import { PaymentInfo } from './payment-info'
import { ResolverValues } from './resolver-values'
import { useAbi, useTask } from '../../hooks'
import { useTaskResolver } from '../../hooks/use-task-resolver'
import { formatFee, getAddressUrl, getTaskFunctionData, truncateEthAddress } from '../../utils/helpers'
import { decodeModuleArgs } from '../../utils/resolverDecoder'
import { RenameTask } from '../rename-task'

export type TasKViewProps = {
taskId: string
Expand Down
2 changes: 1 addition & 1 deletion integrations/gelato/hooks/use-active-tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { useQuery } from '@tanstack/react-query'
import { request } from 'graphql-request'
import { useAccount, useNetwork } from 'wagmi'

import { useGelatoAutomateSdk } from './use-automate-sdk'
import { GetAllTaskDataDocument, GetAllTaskDataQuery, GetAllTaskDataQueryVariables } from '../graphql/graphql/generated/graphql'
import { GELATO_CONSTANTS } from '../utils/constants'
import { getGqlEndpoint } from '../utils/helpers'
import { FetchActiveTasksProps } from '../utils/types'
import { useGelatoAutomateSdk } from './use-automate-sdk'

const fetchActiveTasks = ({ address, gqlEndpoint }: FetchActiveTasksProps) => {
return request<GetAllTaskDataQuery, GetAllTaskDataQueryVariables>({
Expand Down
2 changes: 1 addition & 1 deletion integrations/gelato/hooks/use-cancel-task.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMutation } from '@tanstack/react-query'

import { useGelatoAutomateSdk } from './use-automate-sdk'
import { UseCancelTaskProps } from '../utils/types'
import { useGelatoAutomateSdk } from './use-automate-sdk'

export const useCancelTask = () => {
const { automateSdk } = useGelatoAutomateSdk()
Expand Down
2 changes: 1 addition & 1 deletion integrations/gelato/hooks/use-new-task.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMutation } from '@tanstack/react-query'

import { useGelatoAutomateSdk } from './use-automate-sdk'
import { UseNewTaskProps } from '../utils/types'
import { useGelatoAutomateSdk } from './use-automate-sdk'

export const useNewTask = () => {
const { automateSdk } = useGelatoAutomateSdk()
Expand Down
Loading