Skip to content

Commit

Permalink
Finished first versions of Stake and Swap
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrosimao committed Feb 17, 2022
1 parent 109ad1c commit deedbbe
Show file tree
Hide file tree
Showing 14 changed files with 455 additions and 207 deletions.
3 changes: 2 additions & 1 deletion src/components/CryptoInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const CryptoInput: React.FC<t.CryptoInputPropsType> = ({
currencyQuote,
onChange,
onChangeCurrency,
showBalance = true,
}) => {
const [currency, setCurrency] = React.useState<t.CurrencyTypeEnum>(
t.CurrencyTypeEnum.NEAR
Expand All @@ -33,7 +34,7 @@ export const CryptoInput: React.FC<t.CryptoInputPropsType> = ({

return (
<>
{maxValue ? (
{showBalance && maxValue ? (
<Box
flex
width="90%"
Expand Down
1 change: 1 addition & 0 deletions src/components/CryptoInput/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface CryptoInputPropsType {
onChangeCurrency?: (e: string) => void
maxValue?: string
currencyQuote?: number
showBalance?: boolean
}

export enum CurrencyTypeEnum {
Expand Down
5 changes: 0 additions & 5 deletions src/components/CryptoInput/utils.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const Navbar: React.FC = () => {
weight="normal"
size="medium"
reverse={false}
onClick={() => router.push('/swap')}
/>
<Anchor
label="borrow"
Expand Down
163 changes: 163 additions & 0 deletions src/components/SwapInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import * as React from 'react'
import { Box, Button, Text, TextInput } from 'grommet'

import * as t from './types'

export const SwapInput: React.FC<t.SwapInputPropsType> = ({
value,
maxValue,
swapQuote,
onChange,
onChangeCurrency,
}) => {
const [currency, setCurrency] = React.useState<t.CurrencyTypeEnum>(
t.CurrencyTypeEnum.NEAR
)
const handleChangeCurrency = () => {
const newCurrency =
currency === t.CurrencyTypeEnum.NEAR
? t.CurrencyTypeEnum.QUID
: t.CurrencyTypeEnum.NEAR
setCurrency(newCurrency)
onChangeCurrency && onChangeCurrency(newCurrency)
}

return (
<Box flex align="center" direction="column">
{maxValue ? (
<Box
width="90%"
gap="small"
pad="none"
align="center"
justify="between"
direction="row"
margin="0 auto"
>
<Text alignSelf="start">Pay:</Text>
<Box flex justify="end" align="center" direction="row" gap="xsmall">
<Text as="p" size="xsmall" margin="0" alignSelf="center">
balance: {Number(maxValue || 0).toFixed(3)}
</Text>
<Button
label="max"
alignSelf="end"
size="small"
onClick={() => {
onChange(maxValue)
}}
/>
</Box>
</Box>
) : null}
<Box
margin="5px auto 0 auto"
border={{ size: 'xsmall' }}
width="90%"
flex
direction="column"
round="small"
pad="small"
background="background-back"
>
<Box width="100%" flex direction="row">
<TextInput
plain={true}
focusIndicator={false}
type="number"
name="withdraw"
step="0.1"
placeholder="0.000"
size="xxlarge"
textAlign="start"
min={0}
value={value}
onChange={(e) => {
onChange(e?.target?.value)
}}
/>
<Button
primary
plain={false}
alignSelf="end"
margin="auto 0"
label={currency}
onClick={handleChangeCurrency}
/>
</Box>
</Box>
<Box
width="90%"
margin="20px auto 0 auto"
gap="small"
pad="none"
align="center"
justify="between"
direction="row"
>
<Text alignSelf="start">Receive: (approximately)</Text>
</Box>
<Box
margin="5px auto 0 auto"
border={{ size: 'xsmall' }}
width="90%"
flex
direction="column"
round="small"
pad="small"
background="background-back"
>
<Box width="100%" flex direction="row">
<TextInput
plain={true}
focusIndicator={false}
type="number"
name="withdraw"
step="0.1"
placeholder="0.000"
size="xxlarge"
textAlign="start"
min={0}
value={
swapQuote && value ? String(Number(value) * swapQuote) : undefined
}
onChange={(e) => {
onChange(String(Number(e?.target?.value) / (swapQuote || 1)))
}}
/>
<Button
primary
plain={false}
alignSelf="end"
margin="auto 0"
// size="small"
// style={{ cursor: 'pointer' }}
label={
currency === t.CurrencyTypeEnum.NEAR
? t.CurrencyTypeEnum.QUID
: t.CurrencyTypeEnum.NEAR
}
onClick={handleChangeCurrency}
/>
</Box>
</Box>
{/* Todo: display some info about the swap transaction */}
{/*<Box width="90%" justify="end">*/}
{/* <Text weight="lighter" size="xsmall" alignSelf="end" color="text-weak">*/}
{/* {fiatValue && Number(value)*/}
{/* ? `Approximate value: ~${fiatValue.toFixed(2)} usd`*/}
{/* : null}*/}
{/* </Text>*/}
{/* <Text weight="lighter" size="xsmall" alignSelf="end" color="text-weak">*/}
{/* Price Impact: ~1%*/}
{/* </Text>*/}
{/* <Text weight="lighter" size="xsmall" alignSelf="end" color="text-weak">*/}
{/* Max slippage: ~1%*/}
{/* </Text>*/}
{/* <Text weight="lighter" size="xsmall" alignSelf="end" color="text-weak">*/}
{/* Minimum received after slippage: ~${(fiatValue * 0.95).toFixed(2)} usd*/}
{/* </Text>*/}
{/*</Box>*/}
</Box>
)
}
12 changes: 12 additions & 0 deletions src/components/SwapInput/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface SwapInputPropsType {
value?: string
onChange: (value: string) => void
onChangeCurrency?: (e: string) => void
maxValue?: string
swapQuote?: number
}

export enum CurrencyTypeEnum {
NEAR = 'Near',
QUID = 'qUid',
}
52 changes: 52 additions & 0 deletions src/hooks/useGetBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useState, useEffect, useContext } from 'react'
import { utils } from 'near-api-js'

import { NearContext } from 'src/near/nearContext'

// Todo: replace by redux-toolkit query
export const useGetBalance = (): {
quidBalance: string
nearBalance: string
isLoading: boolean
refetch: () => void
} => {
const { contract, currentUser, walletConnection } = useContext(NearContext)
const [quidBalance, setQuidBalance] = useState<string>('')
const [nearBalance, setNearBalance] = useState<string>('')
const [isLoading, setIsLoading] = useState<boolean>(true)

const fetchQuidBalance = async () => {
try {
setIsLoading(true)
// Get qUid balance
const quidRes = await walletConnection
?.account()
.viewFunction(contract?.contractId || '', 'ft_balance_of', {
account_id: currentUser?.accountId,
})
const newQuidBalance = utils.format.formatNearAmount(quidRes)
setQuidBalance(Number(newQuidBalance).toFixed(3))
// Get Near balance
const newNearBalance = utils.format.formatNearAmount(
currentUser?.balance || '0'
)
setNearBalance(Number(newNearBalance).toFixed(3))
} catch (e) {
// Todo: add a toaster warning of errors
console.error(e)
} finally {
setIsLoading(false)
}
}

useEffect(() => {
fetchQuidBalance()
}, [contract])

return {
quidBalance,
nearBalance,
isLoading,
refetch: fetchQuidBalance,
}
}
63 changes: 63 additions & 0 deletions src/hooks/useGetStats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useState, useEffect, useContext } from 'react'
import { utils } from 'near-api-js'

import { NearContext } from 'src/near/nearContext'

export interface StatsType {
nearSpTotal: string
quidSpTotal: string
nearSpStaked: string
quidSpStaked: string
}
// Todo: replace by redux-toolkit query
export const useGetStats = (): {
stats: StatsType | null
isLoading: boolean
refetch: () => void
} => {
const { contract, currentUser } = useContext(NearContext)
const [stats, setStats] = useState<StatsType | null>(null)
const [isLoading, setIsLoading] = useState<boolean>(true)

const getPledged = async () => {
return contract?.get_pledge({
account: currentUser?.accountId,
})
}
const getStats = async () => {
return contract?.get_pool_stats({})
}

const fetchStats = async () => {
try {
setIsLoading(true)
const newStats = await getStats()
const newPledged = await getPledged()
setStats({
nearSpTotal: utils.format.formatNearAmount(
newStats?.blood_debit || '0'
),
quidSpTotal: utils.format.formatNearAmount(
newStats?.blood_credit || '0'
),
nearSpStaked: utils.format.formatNearAmount(newPledged?.near_sp || '0'),
quidSpStaked: utils.format.formatNearAmount(newPledged?.quid_sp || '0'),
})
} catch (e) {
// Todo: add a toaster warning of errors
console.error(e)
} finally {
setIsLoading(false)
}
}

useEffect(() => {
fetchStats()
}, [contract])

return {
stats,
isLoading,
refetch: fetchStats,
}
}
2 changes: 1 addition & 1 deletion src/near/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const CONTRACT_NAME =
process.env.CONTRACT_NAME || 'dev-1644330473949-94120853225128'
process.env.CONTRACT_NAME || 'dev-1644873487217-61450440829727'

export enum NETWORK_TYPE {
PRODUCTION = 'production',
Expand Down
2 changes: 1 addition & 1 deletion src/near/initContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const initContract = async (): Promise<NearContextType> => {
// View methods are read-only – they don't modify the state, but usually return some value
viewMethods: ['get_pledge', 'get_pool_stats'],
// Change methods can modify the state, but you don't receive the returned value when called
changeMethods: ['renege', 'borrow', 'deposit', 'fold', 'new'],
changeMethods: ['renege', 'borrow', 'deposit', 'fold', 'swap', 'new'],
}
)
// @ts-ignore - Todo: verify whats the problem with Contract ts type
Expand Down
12 changes: 12 additions & 0 deletions src/near/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export interface ContractType extends nearAPI.Contract {
gas?: string,
deposit?: string
) => void
swap: (
// @ts-ignore Todo: find a solution for this weird duplicate alert
{ amount: string, repay: boolean, short: boolean }: Record<string, unknown>,
gas?: string,
deposit?: string
) => void
/*
* Call this function to attempt liquidating a single Pledge
*/
Expand All @@ -85,4 +91,10 @@ export interface ContractType extends nearAPI.Contract {
gas?: string,
deposit?: string
) => Promise<PoolStatsType>
// // Get Pool Stats
// get_stats: (
// { account: string, short: boolean }: Record<string, unknown>,
// gas?: string,
// deposit?: string
// ) => Promise<PoolStatsType>
}
Loading

0 comments on commit deedbbe

Please sign in to comment.