-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(buyback-ui): added workspace (#257)
* feat(buyback-ui): added workspace * feat(chart): implemented chart to ultrasound workspace * feat(useSellSNX): impleneted mutation to sell snx * yarn typecheck * feat(snxPrice): added snx price hook * chore(typecheck) * chore(theme): remove extending theme func * fix(deps) * feat(button): disable when not on base * feat(BurnSNX): added margin to botton row * fix(deps) * fix: update snx price hook * feat(SNXPrice): used pyth price * feat(input): fixed input * fix(typescript) * feat(links): added links to why text and learn more button --------- Co-authored-by: Peiman <[email protected]>
- Loading branch information
1 parent
33af071
commit 6b4a332
Showing
40 changed files
with
1,591 additions
and
2 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
NEXT_PUBLIC_WC_PROJECT_ID=xxx | ||
NEXT_PUBLIC_INFURA_KEY=xxx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
INFURA_KEY=xxx | ||
PYTH_MAINNET_ENDPOINT=https://hermes.pyth.network/ | ||
PYTH_TESTNET_ENDPOINT=https://hermes.pyth.network/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# ULTRASOUND HOMES |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
const path = require('path'); | ||
require.resolve('core-js'); | ||
require.resolve('@babel/runtime-corejs3/core-js/date/now'); | ||
|
||
module.exports = { | ||
presets: [ | ||
require.resolve('@babel/preset-typescript'), | ||
[require.resolve('@babel/preset-react'), { runtime: 'automatic' }], | ||
], | ||
|
||
plugins: [[require.resolve('@babel/plugin-transform-runtime'), { corejs: 3 }]], | ||
|
||
env: { | ||
production: { | ||
presets: [ | ||
[ | ||
require.resolve('@babel/preset-env'), | ||
{ | ||
useBuiltIns: 'usage', | ||
corejs: { version: 3, proposals: true }, | ||
modules: false, | ||
targets: { | ||
browsers: require('./package.json').browserslist, | ||
}, | ||
}, | ||
], | ||
], | ||
}, | ||
|
||
development: { | ||
presets: [ | ||
[ | ||
require.resolve('@babel/preset-env'), | ||
{ | ||
modules: false, | ||
targets: { browsers: ['last 1 Chrome version'] }, | ||
}, | ||
], | ||
], | ||
plugins: [require.resolve('react-refresh/babel')], | ||
}, | ||
|
||
test: { | ||
presets: [ | ||
[ | ||
require.resolve('@babel/preset-env'), | ||
{ | ||
modules: 'commonjs', | ||
targets: { node: 'current' }, | ||
}, | ||
], | ||
], | ||
plugins: [ | ||
[ | ||
require.resolve('babel-plugin-istanbul'), | ||
{ | ||
cwd: path.resolve('../..'), | ||
all: true, | ||
excludeNodeModules: false, | ||
include: ['v3'], | ||
exclude: ['**/*.test.*', '**/*.cy.*', '**/*.e2e.*'], | ||
}, | ||
'istanbul', | ||
], | ||
], | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Button, Flex, Image, Link, Text, Tooltip, useDisclosure } from '@chakra-ui/react'; | ||
import { BurnSNXModal } from './BurnSNXModal'; | ||
import { isBaseAndromeda } from '@snx-v3/isBaseAndromeda'; | ||
import { useNetwork } from '@snx-v3/useBlockchain'; | ||
import { useSNXPrice } from '../hooks/useSNXPrice'; | ||
|
||
export function BurnSNX() { | ||
const { network } = useNetwork(); | ||
const { isOpen, onOpen, onClose } = useDisclosure(); | ||
const { data: SNXPrice } = useSNXPrice(); | ||
|
||
return ( | ||
<Flex | ||
border="1px solid" | ||
borderColor="gray.900" | ||
rounded="base" | ||
flexDir="column" | ||
bg="navy.700" | ||
w="415px" | ||
> | ||
<Image src="/burn-snx.svg" h="284px" /> | ||
<Flex flexDir="column" gap="6" p="4"> | ||
<Text fontWeight={700} fontSize="18px" color="white"> | ||
Sell SNX at premium and watch it burn | ||
</Text> | ||
<Text fontSize="16px"> | ||
Sell your SNX at a <b>premium</b> price to the Buyback and Burn contract and get USDC on | ||
Base | ||
</Text> | ||
<Text fontWeight={700} fontSize="20px"> | ||
{SNXPrice?.eq(0) ? ( | ||
'refecthing...' | ||
) : ( | ||
<> | ||
Buyback Price: <s>$ {SNXPrice?.toNumber().toFixed(2)}</s> $ | ||
{SNXPrice ? (SNXPrice?.toNumber() + SNXPrice?.toNumber() * 0.01).toFixed(2) : 0} | ||
</> | ||
)} | ||
</Text> | ||
<Flex gap="4" mt="65px"> | ||
{!isBaseAndromeda(network?.id, network?.preset) ? ( | ||
<Tooltip label="Please conect to the Base network"> | ||
<Button isDisabled={true}>Burn SNX</Button> | ||
</Tooltip> | ||
) : ( | ||
<Button onClick={() => onOpen()}>Burn SNX</Button> | ||
)} | ||
<Link | ||
href="https://blog.synthetix.io/the-andromeda-release-buyback-and-burn/" | ||
target="_blank" | ||
rel="noopener" | ||
> | ||
<Button variant="outline" colorScheme="gray" color="white"> | ||
Lean More | ||
</Button> | ||
</Link> | ||
</Flex> | ||
</Flex> | ||
<BurnSNXModal isOpen={isOpen} onClose={onClose} /> | ||
</Flex> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
import { | ||
Button, | ||
Divider, | ||
Flex, | ||
Image, | ||
Input, | ||
Modal, | ||
ModalBody, | ||
ModalCloseButton, | ||
ModalContent, | ||
ModalHeader, | ||
ModalOverlay, | ||
Spinner, | ||
Text, | ||
} from '@chakra-ui/react'; | ||
import { useWallet } from '@snx-v3/useBlockchain'; | ||
import { useTokenBalance } from '@snx-v3/useTokenBalance'; | ||
import { SNXUSDBalanceOfBuyBackContract } from '../hooks/SNXUSDBalanceOfBuyBackContract'; | ||
import { useApprove } from '@snx-v3/useApprove'; | ||
import Wei from '@synthetixio/wei'; | ||
import { useState } from 'react'; | ||
import { useSellSNX } from '../mutations/useSellSNX'; | ||
import { useBurnEvents } from '../hooks/useBurnEvents'; | ||
import { useSNXPrice } from '../hooks/useSNXPrice'; | ||
|
||
export function BurnSNXModal({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) { | ||
const [amount, setAmount] = useState<Wei | undefined>(new Wei(0)); | ||
const [receivingUSDCAmount, setReceivingUSDCAmount] = useState(0); | ||
const { data: events } = useBurnEvents(); | ||
const { connect, activeWallet } = useWallet(); | ||
const { data: SNXPrice } = useSNXPrice(); | ||
|
||
const { data: snxBalance } = useTokenBalance('0x22e6966B799c4D5B13BE962E1D117b56327FDa66'); | ||
const { data: usdcBalance } = useTokenBalance('0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'); | ||
const { data: contractBalance } = SNXUSDBalanceOfBuyBackContract( | ||
'0x632cAa10A56343C5e6C0c066735840c096291B18' | ||
); | ||
|
||
const { requireApproval, approve, refetchAllowance } = useApprove({ | ||
contractAddress: '0x22e6966B799c4D5B13BE962E1D117b56327FDa66', | ||
amount: amount ? amount.toBN() : 0, | ||
spender: '0x632cAa10A56343C5e6C0c066735840c096291B18', | ||
}); | ||
const { mutateAsync, isPending } = useSellSNX(); | ||
|
||
return ( | ||
<Modal isOpen={isOpen} onClose={onClose}> | ||
<ModalOverlay /> | ||
<ModalContent bg="navy.700" border="1px solid" borderColor="gray.900" rounded="base"> | ||
<ModalHeader color="white"> | ||
Burn your SNX | ||
<Divider mt="2" /> | ||
</ModalHeader> | ||
<ModalCloseButton /> | ||
<ModalBody> | ||
<Flex flexDir="column" gap="4"> | ||
<Text fontWeight={700} color="white"> | ||
Burn | ||
</Text> | ||
<Flex border="1px solid" borderColor="gray.900" rounded="base" flexDir="column" p="4"> | ||
<Flex justifyContent="space-between" w="100%"> | ||
<Flex | ||
alignItems="center" | ||
border="1px solid" | ||
borderColor="gray.900" | ||
p="2" | ||
rounded="base" | ||
justifyContent="center" | ||
w="90px" | ||
gap="2" | ||
> | ||
<Image src="/snx-input.svg" /> | ||
<Text fontWeight={700} fontSize="16px"> | ||
SNX | ||
</Text> | ||
</Flex> | ||
<Input | ||
variant="unstyled" | ||
placeholder="0.00" | ||
textAlign="end" | ||
fontSize="24px" | ||
color="white" | ||
type="number" | ||
overflow="scroll" | ||
fontWeight={700} | ||
value={amount ? amount.toNumber() : ''} | ||
onChange={(e) => { | ||
try { | ||
if (SNXPrice) { | ||
const snxAmount = new Wei(e.target.value); | ||
setAmount(snxAmount); | ||
setReceivingUSDCAmount( | ||
snxAmount.mul(SNXPrice).add(SNXPrice.mul(0.01)).toNumber() | ||
); | ||
} | ||
} catch (error) { | ||
console.error('failed to parse input: ', Error); | ||
setAmount(undefined); | ||
} | ||
}} | ||
/> | ||
</Flex> | ||
<Flex w="100%" justifyContent="space-between"> | ||
<Text | ||
color="gray.500" | ||
fontSize="12px" | ||
mt="2" | ||
cursor="pointer" | ||
onClick={() => { | ||
if (SNXPrice && snxBalance) { | ||
setAmount(snxBalance); | ||
setReceivingUSDCAmount( | ||
snxBalance.mul(SNXPrice).add(SNXPrice.mul(0.01)).toNumber() | ||
); | ||
} | ||
}} | ||
> | ||
Balance: {snxBalance ? snxBalance.toNumber().toFixed(2) : '-'} | ||
</Text> | ||
<Text color="gray.500" fontSize="12px" mt="2"> | ||
$ | ||
</Text> | ||
</Flex> | ||
<Text color="gray.500" fontSize="12px"> | ||
max burnable:{' '} | ||
{contractBalance && | ||
events?.SNXPrice && | ||
( | ||
new Wei(contractBalance, 18).toNumber() / | ||
(events.SNXPrice + events.SNXPrice * 0.01) | ||
).toFixed(2)} | ||
</Text> | ||
</Flex> | ||
<Text fontWeight={700}>Receive</Text> | ||
<Flex border="1px solid" borderColor="gray.900" rounded="base" flexDir="column" p="4"> | ||
<Flex justifyContent="space-between" w="100%"> | ||
<Flex | ||
alignItems="center" | ||
border="1px solid" | ||
borderColor="gray.900" | ||
p="2" | ||
rounded="base" | ||
justifyContent="center" | ||
w="120px" | ||
gap="2" | ||
> | ||
<Image src="/usdc.svg" /> | ||
<Text fontWeight={700} fontSize="16px"> | ||
USDC | ||
</Text> | ||
</Flex> | ||
<Input | ||
variant="unstyled" | ||
placeholder="0.00" | ||
textAlign="end" | ||
fontSize="24px" | ||
color="white" | ||
type="number" | ||
isDisabled={true} | ||
overflow="scroll" | ||
fontWeight={700} | ||
_disabled={{ color: 'white' }} | ||
value={receivingUSDCAmount} | ||
/> | ||
</Flex> | ||
<Flex w="100%" justifyContent="space-between" gap="2"> | ||
<Text color="gray.500" fontSize="12px" mt="2"> | ||
Balance: {usdcBalance ? usdcBalance.toNumber().toFixed(2) : '-'} | ||
</Text> | ||
</Flex> | ||
</Flex> | ||
{isPending ? ( | ||
<Spinner colorScheme="black" alignSelf="center" /> | ||
) : ( | ||
<Button | ||
my="4" | ||
onClick={async () => { | ||
if (activeWallet?.address) { | ||
if (requireApproval) { | ||
await approve(false); | ||
await refetchAllowance(); | ||
} | ||
if (amount) { | ||
await mutateAsync(amount); | ||
onClose(); | ||
} | ||
} else { | ||
onClose(); | ||
connect(); | ||
} | ||
}} | ||
> | ||
{activeWallet?.address | ||
? requireApproval | ||
? 'Approve SNX' | ||
: 'Burn SNX' | ||
: 'Connect Wallet'} | ||
</Button> | ||
)} | ||
</Flex> | ||
</ModalBody> | ||
</ModalContent> | ||
</Modal> | ||
); | ||
} |
Oops, something went wrong.