An open API service indexing awesome lists of open source software.

https://github.com/unlock-protocol/hackathon-demo


https://github.com/unlock-protocol/hackathon-demo

Last synced: about 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# Install deps:

```bash
yarn add wagmi@0.12.0 ethers@5 @unlock-protocol/paywall @unlock-protocol/networks @unlock-protocol/contracts
```

# Update App.js to include wagmi config

This is not Unlock specific:

Add a constant to `constants.ts` for the network we will use.

```js
export const NETWORK = 5 // also called chain id
```

```jsx
import { WagmiConfig, createClient} from 'wagmi'
import { AppProps } from 'next/app'
import '../styles/index.css'
import { ethers } from 'ethers'
import { NETWORK } from '../lib/constants'

// Create a WAGMI client
const wagmiClient = createClient({
// Unlock provides some RPC providers but you can use your own!
provider: new ethers.providers.JsonRpcProvider(`https://rpc.unlock-protocol.com/${NETWORK}`, NETWORK),
})

export default function MyApp({ Component, pageProps }: AppProps) {
return


}

```

# Add a `TokenGate` component:

This component is in fact pretty simple:

- It wraps any component that needs to be token-gated
- It checks the "status" of the user (has a membership or not), if the user is connected
- If the user is not connected, it renders a subcomponent to prompt the user to connect
- If the user is connected and they do NOT have a membership NFT, it renders a `Checkout` sub-component that promps them to purchase a membership!
- If the user is connected AND they have a membership, it renders he children!

```tsx
import { useAccount, useConnect, useContractRead } from "wagmi"
import {InjectedConnector} from "wagmi/connectors/injected"
import { PublicLockV13 } from "@unlock-protocol/contracts"
import { LOCK, NETWORK } from "../lib/constants"
import { ethers } from "ethers"
import { Paywall } from "@unlock-protocol/paywall"
import networks from '@unlock-protocol/networks'

export const TokenGate = ({children}) => {
const {isConnected, address} = useAccount()

const {data: isMember, isError, isLoading} = useContractRead({
address: LOCK,
abi: PublicLockV13.abi,
functionName: 'balanceOf',
chainId: NETWORK,
enabled: !!address,
args: [address],
watch: true,
select: (data: ethers.BigNumber) => {
return data.gt(0)
}
})

if (isLoading) {
return

Loading...

}

if (isError) {
return
There was an error checking your membership status. Please reload the page!

}

// User not connected
if (!isConnected) {
return
}

// User does not have membership
if (!isMember) {
return
}

// All good: user is connected and they have a membership!
return children
}

/**
* Connect subcomponent!
* @returns
*/
const Connect = () => {
const {connect} = useConnect({
connector: new InjectedConnector()
})
return

To view this post you need to be be a member!


connect()} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Sign-In


}

/**
* Checkout subcomponent!
* @returns
*/
const Checkout = () => {
const {connector} = useAccount()
const checkout = () => {
const paywall = new Paywall(networks)
const provider = connector!.provider
paywall.connect(provider)
paywall.loadCheckoutModal({
locks: {
[LOCK]: {
network: NETWORK,
}
},
pessimistic: true,
})
}

return (

You currently don't have a membership...


checkout()} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Purchase one now!


)
}

```

# Wrap the components that renders the content

We just replace `post-body.tsx` with this:

```tsx

import { TokenGate } from './token-gate'
import markdownStyles from './markdown-styles.module.css'

type Props = {
content: string
}

const PostBody = ({ content }: Props) => {
return (






)
}

export default PostBody

```

# That's it!

Please jump in [Unlock's Discord](https://discord.unlock-protocol.com/) if you have any question!