|
1 |
| -import { useEffect, useState } from "react"; |
2 |
| -import { getMinedBlocks } from "../../lib/kv"; |
3 |
| -import styles from "../../styles/Redeem.module.css"; |
4 |
| -import { useAtom } from "jotai"; |
5 |
| -import { userSessionState } from "../../lib/auth"; |
6 |
| -import fetch from "cross-fetch"; |
7 |
| -import { Configuration, AccountsApi } from "@stacks/blockchain-api-client"; |
8 |
| -import { |
9 |
| - NETWORK_STRING, |
10 |
| - API_BASE_NET_URL, |
11 |
| - CITY_COIN_CORE_ADDRESS, |
12 |
| - CITY_COIN_CORE_CONTRACT_NAME, |
13 |
| - NETWORK, |
14 |
| -} from "../../lib/constants"; |
15 |
| -import { |
16 |
| - getActivationBlock, |
17 |
| - canClaimMiningReward, |
18 |
| - getRegisteredMinerId, |
19 |
| -} from "../../lib/contracts"; |
20 |
| -import { useConnect } from "@syvita/connect-react"; |
21 |
| -import { uintCV } from "@syvita/transactions"; |
22 |
| -import Transaction from "./Transaction"; |
| 1 | +import { useState } from "react"; |
| 2 | +import RedeemRewards from "./Redeem/RedeemRewards"; |
| 3 | +import RedeemMining from "./Redeem/RedeemMining"; |
| 4 | +import RedeemStacking from "./Redeem/RedeemStacking"; |
23 | 5 |
|
24 | 6 | const Redeem = () => {
|
25 |
| - const [userSession] = useAtom(userSessionState); |
| 7 | + const [state, setState] = useState("RedeemRewards"); |
26 | 8 |
|
27 |
| - let STXAddress = ""; |
28 |
| - const userData = userSession.loadUserData(); |
29 |
| - const { doContractCall } = useConnect(); |
30 |
| - const [isLoading, setIsLoading] = useState(false); |
31 |
| - const [percentageChecked, setPercentageChecked] = useState(0); |
32 |
| - const [startBlock, setStartBlock] = useState(0); |
33 |
| - const [endBlock, setEndBlock] = useState(0); |
34 |
| - |
35 |
| - if (NETWORK_STRING == "mainnet") { |
36 |
| - STXAddress = userData.profile.stxAddress.mainnet; |
37 |
| - } else { |
38 |
| - STXAddress = userData.profile.stxAddress.testnet; |
39 |
| - } |
40 |
| - |
41 |
| - const [winningBlocks, setWinningBlocks] = useState([]); |
42 |
| - |
43 |
| - let buttonArray = []; |
44 |
| - let totalWinnings = []; |
45 |
| - |
46 |
| - async function getClaimableBlocks() { |
47 |
| - setIsLoading(true); |
48 |
| - let basePath = "https://stacks-node-api.mainnet.stacks.co"; |
49 |
| - |
50 |
| - if (NETWORK_STRING != "mainnet") { |
51 |
| - basePath = "https://stacks-node-api.testnet.stacks.co"; |
52 |
| - } |
53 |
| - |
54 |
| - const apiConfig = new Configuration({ |
55 |
| - fetchApi: fetch, |
56 |
| - basePath: basePath, |
57 |
| - }); |
58 |
| - const accountsApi = new AccountsApi(apiConfig); |
59 |
| - const response = await accountsApi.getAccountTransactions({ |
60 |
| - limit: 50, |
61 |
| - principal: STXAddress, |
62 |
| - }); |
63 |
| - const txs = response.results.filter( |
64 |
| - (tx) => |
65 |
| - tx.tx_status === "success" && |
66 |
| - tx.tx_type === "contract_call" && |
67 |
| - (tx.contract_call.function_name === "mine-tokens" || |
68 |
| - tx.contract_call.function_name === "mine-many") && |
69 |
| - tx.contract_call.contract_id === |
70 |
| - `${CITY_COIN_CORE_ADDRESS}.${CITY_COIN_CORE_CONTRACT_NAME}` |
71 |
| - ); |
72 |
| - |
73 |
| - let blocksMined = []; |
74 |
| - |
75 |
| - let singleBlocksMined = []; |
76 |
| - |
77 |
| - // ** MAGIC ** |
78 |
| - for (let i = 0; i < txs.length; i++) { |
79 |
| - if (txs[i].contract_call.function_name === "mine-tokens") { |
80 |
| - singleBlocksMined.push(txs[i].block_height); |
81 |
| - } else if (txs[i].contract_call.function_name === "mine-many") { |
82 |
| - blocksMined.push(txs[i].block_height); |
83 |
| - let blocks = txs[i].contract_call.function_args[0].repr; |
84 |
| - var many_amount = (blocks.match(/u/g) || []).length; |
85 |
| - for (let j = 1; j <= many_amount; j++) { |
86 |
| - blocksMined.push(txs[i].block_height + j); |
87 |
| - } |
88 |
| - } |
89 |
| - } |
90 |
| - |
91 |
| - let blocksToCheck = singleBlocksMined.concat(blocksMined); |
92 |
| - |
93 |
| - blocksToCheck = blocksToCheck.filter(Number).sort((a, b) => a - b); |
94 |
| - blocksToCheck = [...new Set(blocksToCheck)]; |
95 |
| - |
96 |
| - let blocksToCheckInRange = []; |
97 |
| - |
98 |
| - let oldestMinedBlock = txs[txs.length - 1].block_height; |
99 |
| - let recentMinedBlock = txs[0].block_height; |
100 |
| - |
101 |
| - blocksToCheck.forEach(function (block) { |
102 |
| - if (startBlock > 0 && endBlock > 0) { |
103 |
| - if (block >= startBlock && block <= endBlock) { |
104 |
| - blocksToCheckInRange.push(block); |
105 |
| - } |
106 |
| - } else { |
107 |
| - blocksToCheckInRange.push(block); |
108 |
| - } |
109 |
| - }); |
110 |
| - |
111 |
| - function sleep(milliseconds) { |
112 |
| - const date = Date.now(); |
113 |
| - let currentDate = null; |
114 |
| - do { |
115 |
| - currentDate = Date.now(); |
116 |
| - } while (currentDate - date < milliseconds); |
117 |
| - } |
118 |
| - |
119 |
| - const canClaimArray = []; |
120 |
| - console.log("LIST OF BLOCKS TO CHECK: " + blocksToCheckInRange); |
121 |
| - |
122 |
| - for (let i = 0; i < blocksToCheckInRange.length; i++) { |
123 |
| - let percent = Math.floor((i / blocksToCheckInRange.length) * 100); |
124 |
| - setPercentageChecked(percent); |
125 |
| - console.log(blocksToCheckInRange[i]); |
126 |
| - let repeat = true; |
127 |
| - let bool = ""; |
128 |
| - while (repeat) { |
129 |
| - try { |
130 |
| - bool = await canClaimMiningReward( |
131 |
| - STXAddress, |
132 |
| - blocksToCheckInRange[i] |
133 |
| - ); |
134 |
| - console.log(bool); |
135 |
| - repeat = false; |
136 |
| - } catch { |
137 |
| - console.log("Too many requests, retrying"); |
138 |
| - sleep(10000); |
139 |
| - repeat = true; |
140 |
| - } |
141 |
| - } |
142 |
| - |
143 |
| - if (bool == true) { |
144 |
| - canClaimArray.push(blocksToCheckInRange[i]); |
145 |
| - } |
146 |
| - } |
147 |
| - setIsLoading(false); |
148 |
| - return canClaimArray; |
149 |
| - } |
150 |
| - |
151 |
| - if ( |
152 |
| - winningBlocks != [] && |
153 |
| - winningBlocks != undefined && |
154 |
| - winningBlocks.length != 0 |
155 |
| - ) { |
156 |
| - console.log("WINNING BLOCKS + " + winningBlocks); |
157 |
| - console.log(winningBlocks.length); |
158 |
| - for (let i = 0; i < winningBlocks.length; i++) { |
159 |
| - totalWinnings = +totalWinnings + +winningBlocks[i]; |
160 |
| - buttonArray.push( |
161 |
| - <button |
162 |
| - onClick={() => claimAction(winningBlocks[i])} |
163 |
| - className={styles.redeemBlocks} |
164 |
| - > |
165 |
| - {"#" + winningBlocks[i]} |
166 |
| - </button> |
167 |
| - ); |
168 |
| - } |
| 9 | + function Redeem() { |
| 10 | + if (state == "RedeemMining") return <RedeemMining />; |
| 11 | + else if (state == "RedeemStacking") return <RedeemStacking />; |
| 12 | + else return <RedeemRewards setState={setState} />; |
169 | 13 | }
|
170 |
| - |
171 |
| - async function claimAction(blockHeight) { |
172 |
| - await doContractCall({ |
173 |
| - contractAddress: CITY_COIN_CORE_ADDRESS, |
174 |
| - contractName: CITY_COIN_CORE_CONTRACT_NAME, |
175 |
| - functionName: "claim-mining-reward", |
176 |
| - functionArgs: [uintCV(blockHeight)], |
177 |
| - network: NETWORK, |
178 |
| - onFinish: (result) => { |
179 |
| - setTxId(result.txId); |
180 |
| - }, |
181 |
| - }); |
182 |
| - } |
183 |
| - |
184 | 14 | return (
|
185 |
| - <div className={styles.redeem}> |
186 |
| - <h2 className={styles.h2}>Redeem mining rewards</h2> |
187 |
| - <p> |
188 |
| - Your may redeem $MIA if you have won a block. You must wait at least 100 |
189 |
| - blocks after you have mined in order to find out if you have won it. |
190 |
| - </p> |
191 |
| - <p> |
192 |
| - Click the button below to check if you have won any blocks, then send |
193 |
| - the transactions that appear to redeem them. |
194 |
| - </p> |
195 |
| - <p> |
196 |
| - Optionally, input a range to check your mined blocks. (Recommended if |
197 |
| - you've mined a lot of blocks!). If nothing is entered, it will check all |
198 |
| - the blocks you've mined since your first mining transaction. |
199 |
| - </p> |
200 |
| - Start: |
201 |
| - <input |
202 |
| - className={styles.blockInput} |
203 |
| - onWheel={(e) => e.target.blur()} |
204 |
| - onChange={(event) => setStartBlock(parseInt(event.target.value))} |
205 |
| - placeholder="Block Height" |
206 |
| - type="number" |
207 |
| - /> |
208 |
| - End: |
209 |
| - <input |
210 |
| - className={styles.blockInput} |
211 |
| - onWheel={(e) => e.target.blur()} |
212 |
| - onChange={(event) => setEndBlock(parseInt(event.target.value))} |
213 |
| - placeholder="Block Height" |
214 |
| - type="number" |
215 |
| - /> |
216 |
| - <button |
217 |
| - className={styles.checkIfWinner} |
218 |
| - onClick={() => |
219 |
| - getClaimableBlocks().then((result) => setWinningBlocks(result)) |
220 |
| - } |
221 |
| - > |
222 |
| - Check Blocks |
223 |
| - </button> |
224 |
| - {isLoading && ( |
225 |
| - <div> |
226 |
| - Checking for claimable blocks... {percentageChecked}% (Please wait) |
227 |
| - </div> |
228 |
| - )} |
229 |
| - {buttonArray && buttonArray} |
| 15 | + <div> |
| 16 | + <Redeem /> |
230 | 17 | </div>
|
231 | 18 | );
|
232 | 19 | };
|
|
0 commit comments