Skip to content

Commit

Permalink
Add mint and burn (#5)
Browse files Browse the repository at this point in the history
* Use just the public vault

* Update opus-pool sdk

* Update vault details hook

* Add mint

* Update unstake and vault comps

* Update form and stake comps

* Update tsconfig

* Add health query, add mint form

* Update forms, hooks, css, add input and user details comps
  • Loading branch information
mariavarvaroi authored Feb 13, 2024
1 parent 42e9b57 commit 1246161
Show file tree
Hide file tree
Showing 29 changed files with 868 additions and 255 deletions.
32 changes: 29 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@chorus-one/opus-pool": "1.0.1",
"@chorus-one/opus-pool": "^1.2.1",
"@tanstack/react-query": "^4.36.1",
"@web3modal/ethereum": "^2.7.1",
"@web3modal/react": "^2.7.1",
Expand All @@ -35,4 +35,4 @@
"typescript": "^5.2.2",
"vite": "^5.0.0"
}
}
}
20 changes: 13 additions & 7 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
height: 100vh;
margin: 0 auto;
text-align: center;
border: 1px solid #ccc;
position: relative;
overflow: hidden;
padding-top: 5rem;
}

.layout {
width: 80vw;
min-width: 80vw;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}

.button-container {
display: flex;
gap: 1rem;
Expand All @@ -19,16 +28,14 @@

.tab-headers {
display: flex;
border-bottom: 1px solid #ddd;
}

.tab-header {
padding: 10px 20px;
cursor: pointer;
margin-right: 4px;
margin-right: 14px;
border: 1px solid #ddd;
border-bottom: none;
border-radius: 5px 5px 0 0;
border-radius: 10px;
background-color: #f9f9f9;
transition: background-color 0.3s;
color: #0e6c78;
Expand All @@ -46,7 +53,6 @@

.tab-content {
padding: 20px;
border: 1px solid #ddd;
border-top: none;
height: max-content;
}
Expand All @@ -61,7 +67,7 @@
.tab-content {
background-color: #222222;
color: #dddddd;
border: 1px solid #444444;
/* border: 1px solid #444444; */
}

.tab-header:hover {
Expand Down
8 changes: 6 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import VaultDetailsUpdater from './updaters/VaultDetailsUpdater';
import { Header } from './components/Header';
import { Tabs } from './components/Tabs';
import { Toaster } from 'react-hot-toast';
import { VaultDetailsComponent } from './components/Vault';

function App() {
const queryClient = new QueryClient();
Expand All @@ -16,8 +17,11 @@ function App() {
<NetworkProvider>
<WagmiConfig config={config}>
<Header />
<Tabs />
<VaultDetailsUpdater />
<div className="layout">
<VaultDetailsComponent />
<Tabs />
<VaultDetailsUpdater />
</div>
<Toaster />
</WagmiConfig>
</NetworkProvider>
Expand Down
73 changes: 73 additions & 0 deletions src/components/AmountInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ChangeEvent, useEffect, useState } from 'react';
import { parseEther } from 'viem';
import { number } from 'yup';

export const AmountInput = ({
setAmount,
isSuccess,
disabled,
title,
}: {
setAmount: React.Dispatch<React.SetStateAction<bigint>>;
isSuccess: boolean;
disabled: boolean;
title: string;
}) => {
const [inputValue, setInputValue] = useState<string>('');
useEffect(() => {
if (isSuccess) {
setInputValue('');
}
}, [isSuccess]);

const onChange = (e: ChangeEvent<HTMLInputElement>) => {
const regex = /^\d*(\.\d{0,18})?$/; // only allow 18 digits after the decimal
const stringValue = e.target.value.replaceAll('+', '').replaceAll('-', '');
let isValid = false;
let validValue: bigint | undefined;
if (stringValue !== '' && !regex.test(stringValue)) {
return;
}
try {
if (stringValue === '') {
validValue = undefined;
} else {
number().validateSync(stringValue);
validValue = parseEther(stringValue);
setAmount(validValue);
}
isValid = true;
} catch (_error) {
// Swallow parsing errors, just don't update the value
}
if (!isValid) return;
setInputValue(stringValue);
};
return (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
border: '1px solid #168F9C',
borderRadius: '0.5rem',
padding: '0.5rem',
}}
>
<input
style={{
border: 'none',
width: '100%',
outline: 'none',
}}
type="text"
placeholder="ETH amount"
onChange={onChange}
value={inputValue}
disabled={disabled}
title={title}
/>
<span>ETH</span>
</div>
);
};
49 changes: 49 additions & 0 deletions src/components/Burn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import { useAccount, useWalletClient } from 'wagmi';
import { useState } from 'react';
import { parseEther } from 'viem';
import { useNetworkAndVaultContext } from '../context/neworkAndVaultContext';
import { useVaultDetails } from '../hooks/useVaultDetails';
import { BurnForm } from './BurnForm';
import { useBurnMutation } from '../hooks/useBurnMutation';

export const BurnComponent = () => {
const { address } = useAccount();
const [amount, setAmount] = useState<bigint>(parseEther('0'));
const { networkType, vaultForChain } = useNetworkAndVaultContext();

const { data: vaultDetails } = useVaultDetails({
network: networkType,
vault: vaultForChain,
address: address,
});
const { mutate: burn, isError, isLoading, isSuccess } = useBurnMutation();

const { data: walletClient } = useWalletClient();

const handleBurn = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!address || !vaultForChain) return;
burn({
userAddress: address,
network: networkType,
vault: vaultForChain,
amount,
walletClient,
});
setAmount(parseEther('0'));
};

return (
<>
<BurnForm
onSubmit={(e) => handleBurn(e)}
maxAmount={vaultDetails?.minted}
setAmount={setAmount}
isError={isError}
isLoading={isLoading}
isSuccess={isSuccess}
/>
</>
);
};
85 changes: 85 additions & 0 deletions src/components/BurnForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useEffect } from 'react';
import { formatEther } from 'viem';
import { useNetworkAndVaultContext } from '../context/neworkAndVaultContext';
import { useAccount } from 'wagmi';
import toast, { LoaderIcon } from 'react-hot-toast';
import { AmountInput } from './AmountInput';

export const BurnForm = ({
onSubmit,
maxAmount,
setAmount,
isError,
isLoading,
isSuccess,
}: {
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
maxAmount: bigint | undefined;
setAmount: React.Dispatch<React.SetStateAction<bigint>>;
isError: boolean;
isLoading: boolean;
isSuccess: boolean;
}) => {
const { wrongNetwork } = useNetworkAndVaultContext();
const { isConnected } = useAccount();

useEffect(() => {
if (isError) {
toast.error('Something went wrong');
}
}, [isError]);

return (
<div style={{ padding: '1rem', border: '1px', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<h2>Burn osETH</h2>
<form
onSubmit={(e) => {
onSubmit(e);
}}
style={{ width: '450px', margin: '1rem auto' }}
>
<AmountInput
disabled={!isConnected || isLoading || wrongNetwork}
title={!isConnected ? 'Connect wallet' : 'Enter the amount to stake'}
isSuccess={isSuccess}
setAmount={setAmount}
/>
<div
style={{
width: '100%',
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
gap: '0.5rem',
marginBottom: '0.5rem',
}}
>
<div style={{ fontSize: '0.8rem', color: '#168F9C' }}>Available to burn:</div>
<div style={{ fontSize: '0.8rem', color: '#168F9C', fontWeight: 'bold' }}>
{maxAmount ? formatEther(maxAmount) : '0'} ETH
</div>
</div>
<button disabled={!isConnected || isLoading || wrongNetwork} type="submit">
{isConnected ? (
isLoading ? (
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
}}
>
<LoaderIcon />
<span>Waiting for confirmation</span>
</div>
) : (
'Burn osETH'
)
) : (
'Connect wallet to burn osETH'
)}
</button>
</form>
</div>
);
};
Loading

0 comments on commit 1246161

Please sign in to comment.