-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdeposit.tsx
136 lines (126 loc) · 4.21 KB
/
deposit.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import {
useSwapCanisterBalances,
useSwapCanisterController,
useSwapCanisterLists,
} from '@/hooks';
import { selectPlugState, useAppSelector } from '@/store';
import { Assets, toExponential, Token } from '@psychedelic/sonic-js';
import { ChangeEvent, useState } from 'react';
/**
* Deposit Section React Component
* Example of a component that deposit tokens for swap canister
*/
export const DepositSection = () => {
// Use custom hooks as states from store
const { tokenList } = useSwapCanisterLists();
const { updateBalanceList, balanceList } = useSwapCanisterBalances();
const controller = useSwapCanisterController();
const { principal } = useAppSelector(selectPlugState);
// Create states used for deposit
const [selectedToken, setSelectedToken] = useState<Token.Data>({
amount: '0',
});
const [isDepositRunning, setIsDepositRunning] = useState<boolean>(false);
// If there is no principal we can't swap
if (!principal) {
return (
<section>
<h1>Deposit</h1>
<span>Connect to plug to deposit</span>
</section>
);
}
// Await fetching tokenList and balanceList
if (!tokenList || !balanceList) {
return (
<section>
<h1>Deposit</h1>
<span>Loading...</span>
</section>
);
}
// Create a handler for selecting token
const handleTokenSelect = (e: ChangeEvent<HTMLSelectElement>) => {
const tokenId = e.currentTarget.value;
setSelectedToken({ ...selectedToken, metadata: tokenList[tokenId] });
};
// Create a handler for changing token amount
const handleAmountChange = (e: ChangeEvent<HTMLInputElement>) => {
setSelectedToken({ ...selectedToken, amount: e.currentTarget.value });
};
/**
* Create a handler for deposit tokens using the controller and
* managing app states.
*/
const handleDeposit = () => {
if (!controller || !selectedToken.metadata) return;
setIsDepositRunning(true);
controller
.deposit({
tokenId: selectedToken.metadata.id,
amount: selectedToken.amount,
})
.then(() => Promise.resolve(updateBalanceList()))
.catch((error) => alert(`Deposit failed: ${error}`))
.finally(() => setIsDepositRunning(false));
};
return (
<section>
<h1>Deposit</h1>
{isDepositRunning ? (
<span>Deposit is running...</span>
) : (
<>
<div>
Token:
<select
name="from"
onChange={handleTokenSelect}
value={selectedToken.metadata?.id || ''}
>
<option disabled value="" style={{ display: 'none' }}></option>
{/** Show all available tokens for deposit */}
{Object.values(tokenList).map((token) => (
<option value={token.id} key={token.id}>
{token.symbol}
</option>
))}
</select>
{/** Set maximum value using balance */}
{/** Set step using token decimals */}
<input
type="number"
min={0}
max={
selectedToken.metadata &&
balanceList[selectedToken.metadata.id].token.toNumber()
}
step={
selectedToken.metadata &&
toExponential(-selectedToken.metadata.decimals).toNumber()
}
value={selectedToken.amount}
onChange={handleAmountChange}
/>
<button onClick={handleDeposit}>Deposit</button>
</div>
{selectedToken.metadata && (
<span>
<b>Needed {selectedToken.metadata.symbol}: </b>
{/**
* Calculate the received amount after depositing.
* This applies token fee for approval and transferring.
*/}
{Assets.getDepositAmount({
token: selectedToken.metadata,
amount: selectedToken.amount,
}).toString()}
</span>
)}
</>
)}
</section>
);
};