Skip to content

Commit

Permalink
WIP - Etherlink Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
ashutoshpw committed Jul 24, 2024
1 parent 9a74515 commit 8c3d997
Show file tree
Hide file tree
Showing 26 changed files with 220 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/modules/common/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const BackButtonText = styled(Grid)({
alignItems: "baseline"
})

export const ConnectWalletButton = ({ connect }: { connect: () => Promise<TezosToolkit> }) => (
export const ConnectWalletButton = ({ connect }: { connect: () => Promise<TezosToolkit | string> }) => (
<SmallButton variant="outlined" onClick={() => connect()}>
Connect Wallet
</SmallButton>
Expand Down
68 changes: 51 additions & 17 deletions src/modules/creator/steps/Template.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useContext, useEffect, useState } from "react"
import { Grid, styled, Typography, Box, useMediaQuery, useTheme, makeStyles } from "@material-ui/core"
import { Grid, styled, Typography, Box, useMediaQuery, useTheme, makeStyles, Tooltip } from "@material-ui/core"
import { useHistory } from "react-router"

import { ReactComponent as LiteIcon } from "assets/img/lite-dao.svg"
Expand All @@ -8,6 +8,7 @@ import { ReactComponent as FullIcon } from "assets/img/full-dao.svg"
import { ActionTypes, CreatorContext, DAOTemplate } from "modules/creator/state"
import { TitleBlock } from "modules/common/TitleBlock"
import { useRouteMatch } from "react-router-dom"
import { useTezos } from "services/beacon/hooks/useTezos"

const LambdaCustomBox = styled(Grid)(({ theme }) => ({
"height": 273,
Expand All @@ -32,6 +33,28 @@ const LambdaCustomBox = styled(Grid)(({ theme }) => ({
}
}))

const LambdaCustomBoxFullDao = ({ style, update, isMobileSmall, isEtherLink, selectedTemplate }: any) => (
<LambdaCustomBox
item
container
direction="column"
justifyContent="flex-start"
alignItems="center"
xs={isMobileSmall ? 12 : 5}
onClick={() => {
if (isEtherLink) return
update("lambda")
}}
title={"Hello World"}
className={selectedTemplate === "lambda" ? style.selected : ""}
style={{ opacity: isEtherLink ? 0.4 : 1 }}
>
<FullIcon style={{ marginBottom: 16 }} />
<BoxTitle color="textSecondary">Full DAO</BoxTitle>
<BoxDescription color="textSecondary">Contract interaction. Transfer assets based on vote outcomes.</BoxDescription>
</LambdaCustomBox>
)

const styles = makeStyles({
selected: {
border: "3px solid rgba(129, 254, 183, 0.4)",
Expand Down Expand Up @@ -71,12 +94,16 @@ export const Template = (): JSX.Element => {

const theme = useTheme()
const style = styles()
const { network } = useTezos()
const isEtherLink = network?.startsWith("etherlink")

const isMobileSmall = useMediaQuery(theme.breakpoints.down("xs"))

const [selectedTemplate, setTemplate] = useState<DAOTemplate>(template)
const [error, setError] = useState<boolean>(false)

console.log({ selectedTemplate })

useEffect(() => {
dispatch({
type: ActionTypes.UPDATE_NAVIGATION_BAR,
Expand Down Expand Up @@ -104,6 +131,10 @@ export const Template = (): JSX.Element => {
})
}, [dispatch, history, match.path, match.url, selectedTemplate])

useEffect(() => {
if (isEtherLink && selectedTemplate === "lambda") setTemplate("lite")
}, [isEtherLink, selectedTemplate])

const update = (templateValue: DAOTemplate) => {
setError(false)
setTemplate(templateValue)
Expand All @@ -113,22 +144,25 @@ export const Template = (): JSX.Element => {
<Box>
<TitleBlock title={"DAO Creator"} description={"Create an organization by picking a template below."} />
<Grid container justifyContent={isMobileSmall ? "center" : "space-between"} direction="row">
<LambdaCustomBox
item
container
direction="column"
justifyContent="flex-start"
alignItems="center"
xs={isMobileSmall ? 12 : 5}
onClick={() => update("lambda")}
className={selectedTemplate === "lambda" ? style.selected : ""}
>
<FullIcon style={{ marginBottom: 16 }} />
<BoxTitle color="textSecondary">Full DAO</BoxTitle>
<BoxDescription color="textSecondary">
Contract interaction. Transfer assets based on vote outcomes.
</BoxDescription>
</LambdaCustomBox>{" "}
{isEtherLink ? (
<Tooltip title="Full DAO is available on Tezos Networks">
<LambdaCustomBoxFullDao
style={style}
update={update}
isMobileSmall={isMobileSmall}
isEtherLink={isEtherLink}
selectedTemplate={selectedTemplate}
/>
</Tooltip>
) : (
<LambdaCustomBoxFullDao
style={style}
update={update}
isMobileSmall={isMobileSmall}
isEtherLink={isEtherLink}
selectedTemplate={selectedTemplate}
/>
)}{" "}
<LambdaCustomBox
item
container
Expand Down
35 changes: 26 additions & 9 deletions src/modules/lite/creator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import { Field, Form, Formik, FormikErrors, getIn } from "formik"
import { TextField as FormikTextField } from "formik-material-ui"
import { Community } from "models/Community"
import { useHistory } from "react-router"
import { validateContractAddress } from "@taquito/utils"

import { useTokenMetadata } from "services/contracts/baseDAO/hooks/useTokenMetadata"
import { useNotification } from "modules/common/hooks/useNotification"
import { useTezos } from "services/beacon/hooks/useTezos"
import { getSignature } from "services/utils/utils"
import { getSignature, validateTokenAddress } from "services/utils/utils"
import { Navbar } from "modules/common/Toolbar"
import { SmallButton } from "modules/common/SmallButton"
import { saveLiteCommunity } from "services/services/lite/lite-services"
Expand Down Expand Up @@ -199,11 +199,6 @@ const CheckboxContainer = styled(Grid)(({ theme }) => ({
flexBasis: "5%"
}))

const validateTokenAddress = (network: Network, tokenAddress: string) => {
if (!network.startsWith("etherlink")) return validateContractAddress(tokenAddress)
return true
}

const validateForm = (network: Network, values: Community) => {
const errors: FormikErrors<Community> = {}

Expand All @@ -216,6 +211,7 @@ const validateForm = (network: Network, values: Community) => {
}

if (values.tokenAddress && validateTokenAddress(network, values.tokenAddress) !== 3) {
console.log("Address isValid", validateTokenAddress(network, values.tokenAddress))
errors.tokenAddress = "Invalid address"
}

Expand All @@ -224,9 +220,27 @@ const validateForm = (network: Network, values: Community) => {

const CommunityForm = ({ submitForm, values, setFieldValue, errors, touched, setFieldTouched, isSubmitting }: any) => {
const theme = useTheme()
const { isEtherlink } = useTezos()
const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm"))

const { data: tokenMetadata, isLoading: loading, error } = useTokenMetadata(values?.tokenAddress)
const tokenStandardOptions = isEtherlink
? [
{
name: "erc20",
label: "ERC20"
}
]
: [
{
value: "fa2",
label: "FA2"
},
{
value: "nft",
label: "NFT"
}
]

const codeEditorStyles = {
minHeight: 500,
Expand Down Expand Up @@ -394,8 +408,11 @@ const CommunityForm = ({ submitForm, values, setFieldValue, errors, touched, set
setFieldValue("tokenType", newValue.target.value)
}}
>
<option value={"fa2"}>FA2</option>
<option value={"nft"}>NFT</option>
{tokenStandardOptions.map((opt: any, idx) => (
<option key={idx} value={opt.value}>
{opt.label}
</option>
))}
</CustomSelect>
)}
</Field>
Expand Down
16 changes: 15 additions & 1 deletion src/services/bakingBad/tokenBalances/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,21 @@ export const getDAONFTBalances = async (
return getDAONFTBalances(daoId, network, offset + ELEMENTS_PER_REQUEST, balances.concat(fetchedBalances))
}

export const getTokenMetadata = async (contractAddress: string, network: Network, tokenId: string) => {
export const getTokenMetadata = async (contractAddress: string, network: Network, tokenId?: string) => {
// TODO: To be fixed (@ashutoshpw)
if (network.startsWith("etherlink")) {
return new Token({
id: "",
contract: "",
token_id: 0,
symbol: "",
name: "",
decimals: 0,
standard: "",
network: network,
supply: "0"
})
}
let url = ""
if (tokenId !== undefined) {
url = `https://api.${networkNameMap[network]}.tzkt.io/v1/tokens?contract=${contractAddress}&tokenId=${tokenId}`
Expand Down
26 changes: 23 additions & 3 deletions src/services/beacon/hooks/useTezos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,28 @@ import { useWeb3Modal } from "@web3modal/wagmi/react"
import mixpanel from "mixpanel-browser"
import { BeaconWallet } from "@taquito/beacon-wallet"
import { useChainId, useAccount as useWagmiAccount, useConnect as useWagmiConnect } from "wagmi"
import { disconnect } from "@wagmi/core"

declare global {
interface Window {
disconnectEtherlink: typeof disconnect
web3Modal: any
}
}

window.disconnectEtherlink = disconnect

type WalletConnectReturn = {
tezos: TezosToolkit
connect: () => Promise<TezosToolkit>
// TODO: @ashutoshpw Figure out the impact of adding string here.
connect: () => Promise<TezosToolkit | string>
changeNetwork: (newNetwork: Network) => void
reset: () => void
account: string
network: Network
wallet: BeaconWallet | undefined
etherlink: any
isEtherlink: boolean
}

function formatEthAddress(address?: string) {
Expand All @@ -31,20 +43,23 @@ export const useTezos = (): WalletConnectReturn => {
} = useContext(TezosContext)

const chainId = useChainId()
const { open, close } = useWeb3Modal()
const { address: ethAddress, isConnected } = useWagmiAccount()
const { connect: wagmiConnect, connectors } = useWagmiConnect()
// eslint-disable-next-line react-hooks/exhaustive-deps
const openEthWallet = () => {
wagmiConnect({ connector: connectors[0], chainId })
open({ view: "Connect" })
// wagmiConnect({ connector: connectors[0], chainId })
}

const queryClient = useQueryClient()

const connect = useCallback(
async (newNetwork?: Network) => {
console.log({ newNetwork })
if ((newNetwork || network).startsWith("etherlink")) {
openEthWallet()
return
return "etherlink_login"
}
const { wallet } = await connectWithBeacon(network)

Expand Down Expand Up @@ -92,6 +107,10 @@ export const useTezos = (): WalletConnectReturn => {
changeNetwork: async (newNetwork: Network) => {
mixpanel.register({ Network: newNetwork })
localStorage.setItem("homebase:network", newNetwork)

if ((newNetwork || network).startsWith("etherlink")) {
openEthWallet()
}
const newTezos: TezosToolkit = createTezos(newNetwork)
if (!account) {
dispatch({
Expand Down Expand Up @@ -124,6 +143,7 @@ export const useTezos = (): WalletConnectReturn => {
account,
network,
wallet,
isEtherlink: network?.startsWith("etherlink"),
etherlink: {
isConnected,
account: {
Expand Down
6 changes: 5 additions & 1 deletion src/services/contracts/baseDAO/hooks/useDropAllExpired.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ export const useDropAllExpired = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await params.dao.dropAllExpired(params.expiredProposalIds, tezosToolkit)
Expand Down
6 changes: 5 additions & 1 deletion src/services/contracts/baseDAO/hooks/useDropProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ export const useDropProposal = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await params.dao.dropProposal(params.proposalId, tezosToolkit)
Expand Down
6 changes: 5 additions & 1 deletion src/services/contracts/baseDAO/hooks/useFlush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ export const useFlush = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await params.dao.flush(params.numOfProposalsToFlush, params.expiredProposalIds, tezosToolkit)
Expand Down
6 changes: 5 additions & 1 deletion src/services/contracts/baseDAO/hooks/useFreeze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export const useFreeze = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await (params.dao as BaseDAO)[params.freeze ? "freeze" : "unfreeze"](params.amount, tezosToolkit)
Expand Down
6 changes: 5 additions & 1 deletion src/services/contracts/baseDAO/hooks/useLambdaAddPropose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export const useLambdaAddPropose = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await dao.proposeLambdaAdd(args, tezosToolkit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export const useLambdaExecutePropose = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await dao.proposeLambdaExecute(args, tezosToolkit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export const useLambdaRemovePropose = () => {
let tezosToolkit = tezos

if (!account) {
tezosToolkit = await connect()
const connectedToolkit = await connect()
if (typeof connectedToolkit === "string") {
throw new Error("Failed to connect to Tezos toolkit")
}
tezosToolkit = connectedToolkit
}

const data = await dao.proposeLambdaRemove(args, tezosToolkit)
Expand Down
Loading

0 comments on commit 8c3d997

Please sign in to comment.