Skip to content

Commit

Permalink
Complex extrinsic (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut authored Aug 21, 2024
1 parent b25de78 commit 95cea54
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 137 deletions.
5 changes: 5 additions & 0 deletions src/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Route, Routes } from 'react-router-dom'

import { Home } from '@/pages/Home'
import { Delegate } from '@/pages/Delegate'
import { toast } from 'sonner'
import { useEffect } from 'react'
import { useNetwork } from './contexts/NetworkContext'
Expand All @@ -13,6 +14,10 @@ const pages = [
path: '/home',
element: <Home />,
},
{
path: '/delegate/:address',
element: <Delegate />,
},
]

export const Content = () => {
Expand Down
86 changes: 86 additions & 0 deletions src/components/DelegateeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Check, Copy, Ellipsis } from 'lucide-react'
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTrigger,
} from '@/components/ui/dialog'
import { useNavigate } from 'react-router-dom'
import { ellipsisFn } from '@polkadot-ui/utils'

import copy from 'copy-to-clipboard'
import { useEffect, useState } from 'react'
import { Delegatee } from '@/contexts/DelegateesContext'

interface Props {
delegatee: Delegatee
}
export const DelegateeCard = ({ delegatee: d }: Props) => {
const [copied, setCopied] = useState<boolean>(false)
const navigate = useNavigate()

useEffect(() => {
if (copied) {
setTimeout(() => setCopied(false), 1000)
}
}, [copied])

const onDelegate = () => {
navigate(`/delegate/${d.address}`)
}
return (
<Card className="border-2 flex flex-col p-2 mb-5">
<div className="flex columns-3">
<div className="p-2 w-[10%]">
<img className="rounded-3xl" width="100" src={d.image} />
</div>
<div className="p-2 w-[85%]">
<div className="font-bold">{d.name}</div>
<div className="">{d.shortDescription}</div>
<Button variant="default" className="mt-2" onClick={onDelegate}>
Delegate
</Button>
</div>
<Dialog>
<DialogTrigger asChild>
<Button
variant={'outline'}
className="text-xs"
onClick={() => console.log('read more')}
>
<Ellipsis className="text-xs" />
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<div className="font-bold">{d.name}</div>
</DialogHeader>
<DialogDescription className="flex">
<div>{ellipsisFn(d.address)}</div>
<div className="pl-4 cursor-pointer">
{copied ? (
<Check className="text-[green]" />
) : (
<Copy
className="cursor-pointer"
onClick={() => {
setCopied(true)
copy(d.address)
}}
/>
)}
</div>
</DialogDescription>
<div className="grid py-4">
<div className="items-center">{d.longDescription}</div>
</div>
</DialogContent>
</Dialog>
</div>
<div className="w-full"></div>
</Card>
)
}
27 changes: 3 additions & 24 deletions src/components/LocksCard.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,9 @@
import { useLocks } from '@/contexts/LocksContext'
import { useNetwork } from '@/contexts/NetworkContext'
import { getExpectedBlockTime } from '@/lib/currentVotesAndDelegations'
import { convertMiliseconds } from '@/lib/convertMiliseconds'
import { getExpectedBlockTime } from '@/lib/locks'
import { Card } from '@polkadot-ui/react'
import { useEffect, useState } from 'react'
import moment from 'moment'

function convertMiliseconds(miliseconds: number) {
let days = 0
let hours = 0
let minutes = 0
let seconds = 0
let total_hours = 0
let total_minutes = 0
let total_seconds = 0

total_seconds = Math.floor(miliseconds / 1000)
total_minutes = Math.floor(total_seconds / 60)
total_hours = Math.floor(total_minutes / 60)
days = Math.floor(total_hours / 24)

seconds = total_seconds % 60
minutes = total_minutes % 60
hours = total_hours % 24

return { d: days, h: hours, m: minutes, s: seconds }
}

export const LocksCard = () => {
const { currentLocks } = useLocks()
Expand Down Expand Up @@ -52,7 +31,7 @@ export const LocksCard = () => {
.catch(console.error)
}, [api])

if (!currentLocks) return null
if (!currentLocks || !Object.entries(currentLocks).length) return null

return (
<>
Expand Down
28 changes: 18 additions & 10 deletions src/contexts/AccountsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, {
useCallback,
useEffect,
} from 'react'
import { InjectedAccount } from 'polkadot-api/pjs-signer'
import { InjectedPolkadotAccount } from 'polkadot-api/pjs-signer'
import { useAccounts as useRedotAccounts } from '@reactive-dot/react'

const LOCALSTORAGE_SELECTED_ACCOUNT_KEY = 'delegit.selectedAccount'
Expand All @@ -16,22 +16,30 @@ type AccountContextProps = {
}

export interface IAccountContext {
selectedAccount?: InjectedAccount
accounts: InjectedAccount[]
selectAccount: (account: InjectedAccount | undefined) => void
selectedAccount?: InjectedPolkadotAccount
accounts: InjectedPolkadotAccount[]
selectAccount: (account: InjectedPolkadotAccount | undefined) => void
}

const AccountContext = createContext<IAccountContext | undefined>(undefined)

const AccountContextProvider = ({ children }: AccountContextProps) => {
const accounts = useRedotAccounts()
const [selectedAccount, setSelected] = useState<InjectedAccount | undefined>()
const [selectedAccount, setSelected] = useState<
InjectedPolkadotAccount | undefined
>()

const selectAccount = useCallback((account: InjectedAccount | undefined) => {
account?.address &&
localStorage.setItem(LOCALSTORAGE_SELECTED_ACCOUNT_KEY, account?.address)
setSelected(account)
}, [])
const selectAccount = useCallback(
(account: InjectedPolkadotAccount | undefined) => {
account?.address &&
localStorage.setItem(
LOCALSTORAGE_SELECTED_ACCOUNT_KEY,
account?.address,
)
setSelected(account)
},
[],
)

useEffect(() => {
const previousAccountAddress = localStorage.getItem(
Expand Down
16 changes: 11 additions & 5 deletions src/contexts/DelegateesContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type DelegateesContextProps = {
children: React.ReactNode | React.ReactNode[]
}

type DelegateeProps = {
export type Delegatee = {
address: string
name: string
image: string
Expand All @@ -23,7 +23,8 @@ type DelegateeProps = {
}

export interface IDelegateesContext {
delegetees: DelegateeProps[]
delegetees: Delegatee[]
getDelegateeByAddress: (address?: string) => Delegatee | undefined
}

const DelegateesContext = createContext<IDelegateesContext | undefined>(
Expand All @@ -32,16 +33,21 @@ const DelegateesContext = createContext<IDelegateesContext | undefined>(

const DelegateeContextProvider = ({ children }: DelegateesContextProps) => {
const { network } = useNetwork()
const [delegetees, setDelegatees] = useState<DelegateeProps[]>([])
const [delegetees, setDelegatees] = useState<Delegatee[]>([])

useEffect(() => {
setDelegatees(
(network === 'polkadot'
? polkadotList
: kusamaList) as unknown as DelegateeProps[],
: kusamaList) as unknown as Delegatee[],
)
}, [network])

const getDelegateeByAddress = (address?: string) => {
if (!address) return undefined

return delegetees.find((d) => d.address === address)
}
// Votes thingy - pause for now
// useEffect(() => {
// const a = async (delegetees: any[]) => {
Expand All @@ -56,7 +62,7 @@ const DelegateeContextProvider = ({ children }: DelegateesContextProps) => {
// }, [delegetees])

return (
<DelegateesContext.Provider value={{ delegetees }}>
<DelegateesContext.Provider value={{ delegetees, getDelegateeByAddress }}>
{children}
</DelegateesContext.Provider>
)
Expand Down
20 changes: 20 additions & 0 deletions src/lib/convertMiliseconds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export function convertMiliseconds(miliseconds: number) {
let days = 0
let hours = 0
let minutes = 0
let seconds = 0
let total_hours = 0
let total_minutes = 0
let total_seconds = 0

total_seconds = Math.floor(miliseconds / 1000)
total_minutes = Math.floor(total_seconds / 60)
total_hours = Math.floor(total_minutes / 60)
days = Math.floor(total_hours / 24)

seconds = total_seconds % 60
minutes = total_minutes % 60
hours = total_hours % 24

return { d: days, h: hours, m: minutes, s: seconds }
}
41 changes: 15 additions & 26 deletions src/lib/currentVotesAndDelegations.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { SS58String } from 'polkadot-api'
import { MultiAddress, VotingConviction } from '@polkadot-api/descriptors'
import { DEFAULT_TIME, ONE_DAY, THRESHOLD } from './constants'
import { bnMin } from './bnMin'
import { ApiType } from '@/contexts/NetworkContext'

// export const getOptimalAmount = async (
Expand Down Expand Up @@ -65,14 +63,21 @@ export const getVotingTrackInfo = async (
)
}

export const getDelegateTx = async (
from: SS58String,
target: SS58String,
conviction: VotingConviction,
amount: bigint,
tracks: Array<number>,
api: ApiType,
) => {
export const getDelegateTx = async ({
from,
target,
conviction,
amount,
tracks,
api,
}: {
from: SS58String
target: SS58String
conviction: VotingConviction
amount: bigint
tracks: Array<number>
api: ApiType
}) => {
const tracksInfo = await getVotingTrackInfo(from, api)

const txs: Array<
Expand Down Expand Up @@ -124,19 +129,3 @@ export const getDelegateTx = async (
calls: txs.map((tx) => tx.decodedCall),
})
}

export const getExpectedBlockTime = async (api: ApiType): Promise<bigint> => {
const expectedBlockTime = await api.constants.Babe.ExpectedBlockTime()
if (expectedBlockTime) {
return bnMin(ONE_DAY, expectedBlockTime)
}

const thresholdCheck =
(await api.constants.Timestamp.MinimumPeriod()) > THRESHOLD

if (thresholdCheck) {
return bnMin(ONE_DAY, (await api.constants.Timestamp.MinimumPeriod()) * 2n)
}

return bnMin(ONE_DAY, DEFAULT_TIME)
}
Loading

0 comments on commit 95cea54

Please sign in to comment.