React Hooks
This is the documentation for the Liteflow's hooks. This package contains a set of React Hooks that facilitates the creation of your own NFT Marketplace.
Before installation
To use the @nft/hooks
package you will need an app with React version 17
.
Installation
npm i @nft/hooks
Quick Start
This quick start showcase examples using Next.js (opens in a new tab).
1. Include your favorite web3 provider
Your application is relying on a web3 wallet. Please refer to your preferred web3 provider for the setup. Our example is using RainbowKit and Wagmi but here are a few providers tested and supported:
2. Wrap app with LiteflowProvider
, AccountProvider
and a Web3 provider.
-
Wrap your app with a Web3 provider (in this case
RainbowKitProvider
andWagmiConfig
) and their configurations. -
Inside the Web3 provider, wrap your app with the
LiteflowProvider
and pass your Liteflow API endpoint to itsendpoint
property (similar tohttps://api.acme.com/graphql
). -
Inside the
LiteflowProvider
wrap the rest of the app with theAccountProvider
provider.
import { LiteflowProvider, useAuthenticate } from '@nft/hooks'
import {
ConnectButton,
getDefaultWallets,
RainbowKitProvider,
} from '@rainbow-me/rainbowkit'
import '@rainbow-me/rainbowkit/styles.css'
import { AppProps } from 'next/app'
import { PropsWithChildren } from 'react'
import {
chain,
configureChains,
createClient,
useAccount,
useDisconnect,
WagmiConfig,
} from 'wagmi'
import { publicProvider } from 'wagmi/providers/public'
const { chains, provider } = configureChains(
[chain.polygonMumbai], // Change to the chain used by your marketplace
[publicProvider()],
)
const { connectors } = getDefaultWallets({ appName: 'Test', chains })
const wagmiClient = createClient({
autoConnect: true,
connectors,
provider,
})
function AccountProvider(props: PropsWithChildren) {
const [authenticate, { setAuthenticationToken, resetAuthenticationToken }] =
useAuthenticate()
const { disconnect } = useDisconnect()
useAccount({
async onConnect({ address, connector }) {
// check if user is already authenticated, not only if its wallet is connected
if (
localStorage.getItem('authorization.address') === address &&
localStorage.getItem(`authorization.${address}`)
) {
// since the user is already authenticated we can autoconnect
setAuthenticationToken(localStorage.getItem(`authorization.${address}`))
// TODO: should check the expiration date of the jwt token to make sure it's still valid
return
}
// authenticate user
const signer = await connector.getSigner()
authenticate(signer)
.then(({ jwtToken }) => {
localStorage.setItem('authorization.address', address)
localStorage.setItem(`authorization.${address}`, jwtToken)
console.log('user authenticated')
})
.catch((error) => {
console.error(error)
// disconnect wallet on error
disconnect()
})
},
onDisconnect() {
// remove authorization and authentication data
const address = localStorage.getItem('authorization.address')
localStorage.removeItem(`authorization.${address}`)
localStorage.removeItem('authorization.address')
resetAuthenticationToken()
},
})
return <>{props.children}</>
}
function MyApp({ Component, pageProps }: AppProps): JSX.Element {
return (
<WagmiConfig client={wagmiClient}>
<RainbowKitProvider chains={chains} coolMode>
<LiteflowProvider endpoint="https://api.acme.com/graphql">
<AccountProvider>
<ConnectButton />
<Component {...pageProps} />
</AccountProvider>
</LiteflowProvider>
</RainbowKitProvider>
</WagmiConfig>
)
}
export default MyApp
3. You're all set!
Every component inside your App has now access to Liteflow's hooks.
import { Signer, TypedDataSigner } from '@ethersproject/abstract-signer'
import { useCreateOffer } from '@nft/hooks'
import { BigNumber } from 'ethers'
import { useCallback } from 'react'
import { useSigner } from 'wagmi'
export default function Home() {
const { data: signer } = useSigner()
const [_create] = useCreateOffer(
signer as (Signer & TypedDataSigner) | undefined,
)
const assetId =
'80001-0x7c68c3c59ceb245733a2fdeb47f5f7d6dbcc65b3-60249402084937876423066029128237587855293854847399126863606291191289075471730'
const create = useCallback(async () => {
const amount = parseFloat(prompt('amount in USDC'))
const id = await _create({
type: 'BUY',
assetId,
currencyId: '80001-0x0fa8781a83e46826621b3bc094ea2a0212e71b23', // USDC on Polygon Mumbai
expiredAt: new Date(Date.now() + 1000 * 60 * 60),
quantity: BigNumber.from(1),
unitPrice: BigNumber.from(amount * 1e6),
})
alert(id)
}, [_create])
return <>{signer && <a onClick={create}>Create offer</a>}</>
}
Check out the minimal app repo (opens in a new tab) to see this example in a working app.
Want to learn more about the hooks? Check out the hooks docs.