Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion apps/subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ type ClankerToken @entity {
tokenAddress: Bytes!
msgSender: Bytes!
tokenAdmin: Bytes! # The admin address (may or may not be a DAO)

# Token metadata
tokenImage: String!
tokenName: String!
Expand Down Expand Up @@ -565,6 +564,7 @@ type ZoraDropMintComment @entity {
# Swap routing entities

enum CoinType {
UNKNOWN
WETH
CLANKER_TOKEN
ZORA_COIN
Expand Down Expand Up @@ -622,6 +622,8 @@ type PaymentOption @entity {
# Payment token details
tokenAddress: Bytes!
tokenType: CoinType!
tokenName: String!
tokenSymbol: String!

# Hops from this payment token to the target coin (when buying)
# Or from target coin to this payment token (when selling)
Expand Down
13 changes: 13 additions & 0 deletions apps/subgraph/src/utils/coinInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CLANKER_TICK_SPACING, DYNAMIC_FEE_FLAG, WETH_ADDRESS } from './constant
* Coin type constants for routing
*/
export namespace CoinType {
export const UNKNOWN: string = 'UNKNOWN'
export const WETH: string = 'WETH'
export const CLANKER_TOKEN: string = 'CLANKER_TOKEN'
export const ZORA_COIN: string = 'ZORA_COIN'
Expand All @@ -18,6 +19,8 @@ export namespace CoinType {
export class CoinInfo {
address: Bytes
type: string
name: string
symbol: string
pairedToken: Bytes | null
poolId: Bytes | null // Uniswap V4 pool identifier (from either poolId or poolKeyHash)
fee: BigInt | null
Expand All @@ -27,6 +30,8 @@ export class CoinInfo {
constructor(
address: Bytes,
type: string,
name: string,
symbol: string,
pairedToken: Bytes | null,
poolId: Bytes | null,
fee: BigInt | null,
Expand All @@ -35,6 +40,8 @@ export class CoinInfo {
) {
this.address = address
this.type = type
this.name = name
this.symbol = symbol
this.pairedToken = pairedToken
this.poolId = poolId
this.fee = fee
Expand All @@ -55,6 +62,8 @@ export function loadCoinInfo(tokenAddress: Bytes): CoinInfo | null {
return new CoinInfo(
tokenAddress,
CoinType.WETH,
'Wrapped Ether',
'WETH',
null, // WETH has no pairedToken
null, // WETH has no pool
null,
Expand All @@ -69,6 +78,8 @@ export function loadCoinInfo(tokenAddress: Bytes): CoinInfo | null {
return new CoinInfo(
zoraCoin.coinAddress,
CoinType.ZORA_COIN,
zoraCoin.name,
zoraCoin.symbol,
zoraCoin.currency,
zoraCoin.poolKeyHash, // poolKeyHash is the Uniswap V4 pool identifier
zoraCoin.poolFee,
Expand All @@ -83,6 +94,8 @@ export function loadCoinInfo(tokenAddress: Bytes): CoinInfo | null {
return new CoinInfo(
clankerToken.tokenAddress,
CoinType.CLANKER_TOKEN,
clankerToken.tokenName,
clankerToken.tokenSymbol,
clankerToken.pairedToken,
clankerToken.poolId, // poolId is the Uniswap V4 pool identifier
DYNAMIC_FEE_FLAG,
Expand Down
15 changes: 12 additions & 3 deletions apps/subgraph/src/utils/swapPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,18 @@ export function buildSwapRoute(coinAddress: Bytes, timestamp: BigInt): SwapRoute
continue
}

// Determine token type
let tokenType = CoinType.WETH
let tokenType = CoinType.UNKNOWN
let tokenName = 'Unknown Token'
let tokenSymbol = 'UNKNOWN'
const info = loadCoinInfo(tokenBytes)
if (info) {
if (!info) {
log.warning('Payment option has missing coin info, using UNKNOWN metadata: {}', [
tokenAddr,
])
} else {
tokenType = info.type
tokenName = info.name
tokenSymbol = info.symbol
}

// Create payment option
Expand All @@ -253,6 +260,8 @@ export function buildSwapRoute(coinAddress: Bytes, timestamp: BigInt): SwapRoute
option.route = routeId
option.tokenAddress = tokenBytes
option.tokenType = tokenType
option.tokenName = tokenName
option.tokenSymbol = tokenSymbol
option.startHopIndex = startHopIndex
option.endHopIndex = endHopIndex
option.isDirectSwap = endHopIndex - startHopIndex == 0 // Single hop = direct swap
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/HoldersSection/HoldersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const HolderItem = ({ address, balance, isDrop = false }: HolderItemProps) => {
justify="space-between"
gap="x3"
py="x1"
px="x4"
px="x2"
borderRadius="curved"
className={holderLink}
>
Expand Down
5 changes: 1 addition & 4 deletions apps/web/src/components/HoldersSection/HoldersSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,10 @@ export const HoldersSection = ({

return (
<Box mb="x3">
<Flex align="center" justify="space-between" mb="x3">
<Flex align="center" mb="x3">
<Text variant="label-sm" color="text3">
{title}
</Text>
<Text variant="label-xs" color="text3">
Showing {filteredHolders.length}
</Text>
</Flex>
<HoldersList holders={filteredHolders} isDrop={isDrop} />
</Box>
Expand Down
17 changes: 12 additions & 5 deletions apps/web/src/components/LinksProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { AddressType, CHAIN_ID } from '@buildeross/types'
import {
AddressType,
CHAIN_ID,
DaoTab,
ProposalCreateStage,
ProposalTab,
} from '@buildeross/types'
import { LinksProvider as BaseLinksProvider } from '@buildeross/ui/LinksProvider'
import { chainIdToSlug } from '@buildeross/utils/chains'
import React from 'react'
Expand Down Expand Up @@ -26,7 +32,7 @@ export const LinksProvider: React.FC<LinksProviderProps> = ({ children }) => {
)

const getDaoLink = React.useCallback(
(chainId: CHAIN_ID, tokenAddress: AddressType, tab?: string) => {
(chainId: CHAIN_ID, tokenAddress: AddressType, tab?: DaoTab) => {
const baseHref = `/dao/${chainIdToSlug(chainId)}/${tokenAddress}`
return {
href: tab ? `${baseHref}?tab=${tab}` : baseHref,
Expand All @@ -40,7 +46,7 @@ export const LinksProvider: React.FC<LinksProviderProps> = ({ children }) => {
chainId: CHAIN_ID,
tokenAddress: AddressType,
proposalId: string | number | bigint,
tab?: string
tab?: ProposalTab
) => {
const baseHref = `/dao/${chainIdToSlug(chainId)}/${tokenAddress}/vote/${proposalId}`
return {
Expand All @@ -51,9 +57,10 @@ export const LinksProvider: React.FC<LinksProviderProps> = ({ children }) => {
)

const getProposalCreateLink = React.useCallback(
(chainId: CHAIN_ID, tokenAddress: AddressType) => {
(chainId: CHAIN_ID, tokenAddress: AddressType, stage?: ProposalCreateStage) => {
const baseHref = `/dao/${chainIdToSlug(chainId)}/${tokenAddress}/proposal/create`
return {
href: `/dao/${chainIdToSlug(chainId)}/${tokenAddress}/proposal/create`,
href: stage ? `${baseHref}?stage=${stage}` : baseHref,
}
},
[]
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/layouts/BaseLayout/BaseLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function BaseLayout({
nav,
...props
}: BaseLayoutProps) {
const { style, ...rest } = props
const chainStore = useMemo(() => createChainStore(chain), [chain])
const daoStore = useMemo(() => createDaoStore(addresses), [addresses])
const { openConnectModal } = useConnectModal()
Expand All @@ -38,9 +39,11 @@ export function BaseLayout({
<ConnectModalProvider value={{ openConnectModal }}>
<ChainStoreProvider store={chainStore}>
<DaoStoreProvider store={daoStore}>
<Box>
<Box style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
{nav || <DefaultLayoutNav />}
<Box {...props}>{children}</Box>
<Box style={{ ...style, flex: 1 }} {...rest}>
{children}
</Box>
{footer}
</Box>
</DaoStoreProvider>
Expand Down
15 changes: 13 additions & 2 deletions apps/web/src/layouts/DaoLayout/DaoLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ type DaoPageProps = {
chainId?: number
}

export function getDaoLayout(page: ReactElement<DaoPageProps>) {
type DaoLayoutOptions = {
hideFooterOnMobile?: boolean
}

export function getDaoLayout(
page: ReactElement<DaoPageProps>,
options?: DaoLayoutOptions
) {
const addresses = page.props?.addresses ?? {}
const chainId = page.props?.chainId ?? 1
const chain =
PUBLIC_DEFAULT_CHAINS.find((c) => c.id === chainId) ?? PUBLIC_DEFAULT_CHAINS[0]

return (
<DefaultLayout chain={chain} addresses={addresses}>
<DefaultLayout
chain={chain}
addresses={addresses}
hideFooterOnMobile={options?.hideFooterOnMobile}
>
{page}
</DefaultLayout>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useAccount } from 'wagmi'
export const NoCreatorCoinWarning: React.FC = () => {
const router = useRouter()
const { address: userAddress } = useAccount()
const { createProposal, setTransactionType } = useProposalStore()
const { startProposalDraft } = useProposalStore()

// Get addresses and chain from stores
const addresses = useDaoStore((x) => x.addresses)
Expand All @@ -36,17 +36,17 @@ export const NoCreatorCoinWarning: React.FC = () => {

// Handle creating a Creator Coin proposal
const handleCreateCreatorCoinProposal = () => {
setTransactionType(TransactionType.CREATOR_COIN)
createProposal({
title: undefined,
summary: undefined,
disabled: false,
transactions: [],
startProposalDraft({
transactionType: TransactionType.CREATOR_COIN,
})
// Navigate to proposal create page
router.push({
pathname: '/dao/[network]/[token]/proposal/create',
query: router.query,
query: {
network: router.query.network,
token: router.query.token,
stage: 'transactions',
},
})
}

Expand Down
58 changes: 15 additions & 43 deletions apps/web/src/modules/dashboard/CreateActions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { COINING_ENABLED } from '@buildeross/constants/coining'
import type { AddressType } from '@buildeross/types'
import { Button, Flex, Grid } from '@buildeross/zord'
import { Button, Flex } from '@buildeross/zord'
import Link from 'next/link'
import React, { useState } from 'react'

Expand All @@ -13,9 +12,7 @@ export interface CreateActionsProps {

export const CreateActions: React.FC<CreateActionsProps> = ({ userAddress }) => {
const [selectorOpen, setSelectorOpen] = useState(false)
const [actionType, setActionType] = useState<'post' | 'proposal'>(
COINING_ENABLED ? 'post' : 'proposal'
)
const [actionType, setActionType] = useState<'post' | 'proposal'>('post')

const handleCreatePost = () => {
setActionType('post')
Expand All @@ -30,44 +27,19 @@ export const CreateActions: React.FC<CreateActionsProps> = ({ userAddress }) =>
return (
<>
<Flex direction="column" className={actionButtons} gap="x3">
{COINING_ENABLED ? (
<>
<Flex gap="x3">
<Button onClick={handleCreatePost} variant="primary" style={{ flex: 1 }}>
Create Post
</Button>
<Button
onClick={handleCreateProposal}
variant="outline"
style={{ flex: 1 }}
>
Create Proposal
</Button>
</Flex>
<Link href="/create" style={{ width: '100%', flex: 1 }}>
<Button style={{ width: '100%' }} variant="outline" className={daoButton}>
Create a DAO
</Button>
</Link>
</>
) : (
<>
<Grid columns={2} gap="x3">
<Button
onClick={handleCreateProposal}
variant="primary"
style={{ flex: 1 }}
>
Create Proposal
</Button>
<Link href="/create" style={{ flex: 1 }}>
<Button variant="outline" style={{ width: '100%' }}>
Create a DAO
</Button>
</Link>
</Grid>
</>
)}
<Flex gap="x3">
<Button onClick={handleCreatePost} variant="primary" style={{ flex: 1 }}>
Create Post
</Button>
<Button onClick={handleCreateProposal} variant="outline" style={{ flex: 1 }}>
Create Proposal
</Button>
</Flex>
<Link href="/create" style={{ width: '100%', flex: 1 }}>
<Button style={{ width: '100%' }} variant="outline" className={daoButton}>
Create a DAO
</Button>
</Link>
</Flex>

<DaoSelectorModal
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/modules/dashboard/DaoAuctionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const DaoAuctionCard = (props: DaoAuctionCardProps) => {
<Flex className={outerAuctionCard} direction="column" align="stretch">
<Link
link={getAuctionLink(chainId, tokenAddress, currentAuction?.token?.tokenId)}
isExternal
style={{ width: '100%' }}
>
<Flex align="center" gap="x2" mb="x3" w="100%">
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/modules/dashboard/DaoProposalCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const DaoProposalCard = ({
px={'x3'}
position={'relative'}
link={getProposalLink?.(chainId, collectionAddress, proposalNumber)}
isExternal
className={proposalCardVariants[displayWarning ? 'warning' : 'default']}
>
<Text
Expand Down
Loading
Loading