diff --git a/packages/miami-ui/components/Dashboard/ActivityFeed.js b/packages/miami-ui/components/Dashboard/ActivityFeed.js
index 6fd5e05..06c74a4 100644
--- a/packages/miami-ui/components/Dashboard/ActivityFeed.js
+++ b/packages/miami-ui/components/Dashboard/ActivityFeed.js
@@ -43,9 +43,11 @@ const ActivityFeed = () => {
function getAmount(transaction) {
let amount = 0;
- console.log(transaction.tx_id);
if (!transaction.post_conditions[0]) {
amount = 0;
+ if (transaction.contract_call.function_name == "claim-mining-reward") {
+ amount = 250000;
+ }
return amount;
}
switch (transaction.contract_call.function_name) {
@@ -57,6 +59,9 @@ const ActivityFeed = () => {
case "claim-mining-reward":
amount = 250000;
break;
+ case "claim-stacking-reward":
+ amount = transaction.post_conditions[0].amount / 1000000;
+ break;
case "mine-tokens":
amount = transaction.post_conditions[0].amount / 1000000;
break;
@@ -103,7 +108,7 @@ const ActivityFeed = () => {
switch (transaction.contract_call) {
case "mine-tokens":
case "mine-many":
- transaction.contract_call = "Mine";
+ transaction.contract_call = "Redeem";
break;
case "claim-mining-reward":
case "claim-stacking-reward":
diff --git a/packages/miami-ui/components/Dashboard/Redeem.js b/packages/miami-ui/components/Dashboard/Redeem.js
index b91ba34..bbe99ec 100644
--- a/packages/miami-ui/components/Dashboard/Redeem.js
+++ b/packages/miami-ui/components/Dashboard/Redeem.js
@@ -1,232 +1,19 @@
-import { useEffect, useState } from "react";
-import { getMinedBlocks } from "../../lib/kv";
-import styles from "../../styles/Redeem.module.css";
-import { useAtom } from "jotai";
-import { userSessionState } from "../../lib/auth";
-import fetch from "cross-fetch";
-import { Configuration, AccountsApi } from "@stacks/blockchain-api-client";
-import {
- NETWORK_STRING,
- API_BASE_NET_URL,
- CITY_COIN_CORE_ADDRESS,
- CITY_COIN_CORE_CONTRACT_NAME,
- NETWORK,
-} from "../../lib/constants";
-import {
- getActivationBlock,
- canClaimMiningReward,
- getRegisteredMinerId,
-} from "../../lib/contracts";
-import { useConnect } from "@syvita/connect-react";
-import { uintCV } from "@syvita/transactions";
-import Transaction from "./Transaction";
+import { useState } from "react";
+import RedeemRewards from "./Redeem/RedeemRewards";
+import RedeemMining from "./Redeem/RedeemMining";
+import RedeemStacking from "./Redeem/RedeemStacking";
const Redeem = () => {
- const [userSession] = useAtom(userSessionState);
+ const [state, setState] = useState("RedeemRewards");
- let STXAddress = "";
- const userData = userSession.loadUserData();
- const { doContractCall } = useConnect();
- const [isLoading, setIsLoading] = useState(false);
- const [percentageChecked, setPercentageChecked] = useState(0);
- const [startBlock, setStartBlock] = useState(0);
- const [endBlock, setEndBlock] = useState(0);
-
- if (NETWORK_STRING == "mainnet") {
- STXAddress = userData.profile.stxAddress.mainnet;
- } else {
- STXAddress = userData.profile.stxAddress.testnet;
- }
-
- const [winningBlocks, setWinningBlocks] = useState([]);
-
- let buttonArray = [];
- let totalWinnings = [];
-
- async function getClaimableBlocks() {
- setIsLoading(true);
- let basePath = "https://stacks-node-api.mainnet.stacks.co";
-
- if (NETWORK_STRING != "mainnet") {
- basePath = "https://stacks-node-api.testnet.stacks.co";
- }
-
- const apiConfig = new Configuration({
- fetchApi: fetch,
- basePath: basePath,
- });
- const accountsApi = new AccountsApi(apiConfig);
- const response = await accountsApi.getAccountTransactions({
- limit: 50,
- principal: STXAddress,
- });
- const txs = response.results.filter(
- (tx) =>
- tx.tx_status === "success" &&
- tx.tx_type === "contract_call" &&
- (tx.contract_call.function_name === "mine-tokens" ||
- tx.contract_call.function_name === "mine-many") &&
- tx.contract_call.contract_id ===
- `${CITY_COIN_CORE_ADDRESS}.${CITY_COIN_CORE_CONTRACT_NAME}`
- );
-
- let blocksMined = [];
-
- let singleBlocksMined = [];
-
- // ** MAGIC **
- for (let i = 0; i < txs.length; i++) {
- if (txs[i].contract_call.function_name === "mine-tokens") {
- singleBlocksMined.push(txs[i].block_height);
- } else if (txs[i].contract_call.function_name === "mine-many") {
- blocksMined.push(txs[i].block_height);
- let blocks = txs[i].contract_call.function_args[0].repr;
- var many_amount = (blocks.match(/u/g) || []).length;
- for (let j = 1; j <= many_amount; j++) {
- blocksMined.push(txs[i].block_height + j);
- }
- }
- }
-
- let blocksToCheck = singleBlocksMined.concat(blocksMined);
-
- blocksToCheck = blocksToCheck.filter(Number).sort((a, b) => a - b);
- blocksToCheck = [...new Set(blocksToCheck)];
-
- let blocksToCheckInRange = [];
-
- let oldestMinedBlock = txs[txs.length - 1].block_height;
- let recentMinedBlock = txs[0].block_height;
-
- blocksToCheck.forEach(function (block) {
- if (startBlock > 0 && endBlock > 0) {
- if (block >= startBlock && block <= endBlock) {
- blocksToCheckInRange.push(block);
- }
- } else {
- blocksToCheckInRange.push(block);
- }
- });
-
- function sleep(milliseconds) {
- const date = Date.now();
- let currentDate = null;
- do {
- currentDate = Date.now();
- } while (currentDate - date < milliseconds);
- }
-
- const canClaimArray = [];
- console.log("LIST OF BLOCKS TO CHECK: " + blocksToCheckInRange);
-
- for (let i = 0; i < blocksToCheckInRange.length; i++) {
- let percent = Math.floor((i / blocksToCheckInRange.length) * 100);
- setPercentageChecked(percent);
- console.log(blocksToCheckInRange[i]);
- let repeat = true;
- let bool = "";
- while (repeat) {
- try {
- bool = await canClaimMiningReward(
- STXAddress,
- blocksToCheckInRange[i]
- );
- console.log(bool);
- repeat = false;
- } catch {
- console.log("Too many requests, retrying");
- sleep(10000);
- repeat = true;
- }
- }
-
- if (bool == true) {
- canClaimArray.push(blocksToCheckInRange[i]);
- }
- }
- setIsLoading(false);
- return canClaimArray;
- }
-
- if (
- winningBlocks != [] &&
- winningBlocks != undefined &&
- winningBlocks.length != 0
- ) {
- console.log("WINNING BLOCKS + " + winningBlocks);
- console.log(winningBlocks.length);
- for (let i = 0; i < winningBlocks.length; i++) {
- totalWinnings = +totalWinnings + +winningBlocks[i];
- buttonArray.push(
- claimAction(winningBlocks[i])}
- className={styles.redeemBlocks}
- >
- {"#" + winningBlocks[i]}
-
- );
- }
+ function Redeem() {
+ if (state == "RedeemMining") return ;
+ else if (state == "RedeemStacking") return ;
+ else return ;
}
-
- async function claimAction(blockHeight) {
- await doContractCall({
- contractAddress: CITY_COIN_CORE_ADDRESS,
- contractName: CITY_COIN_CORE_CONTRACT_NAME,
- functionName: "claim-mining-reward",
- functionArgs: [uintCV(blockHeight)],
- network: NETWORK,
- onFinish: (result) => {
- setTxId(result.txId);
- },
- });
- }
-
return (
-
-
Redeem mining rewards
-
- Your may redeem $MIA if you have won a block. You must wait at least 100
- blocks after you have mined in order to find out if you have won it.
-
-
- Click the button below to check if you have won any blocks, then send
- the transactions that appear to redeem them.
-
-
- Optionally, input a range to check your mined blocks. (Recommended if
- you've mined a lot of blocks!). If nothing is entered, it will check all
- the blocks you've mined since your first mining transaction.
-
- Start:
-
e.target.blur()}
- onChange={(event) => setStartBlock(parseInt(event.target.value))}
- placeholder="Block Height"
- type="number"
- />
- End:
-
e.target.blur()}
- onChange={(event) => setEndBlock(parseInt(event.target.value))}
- placeholder="Block Height"
- type="number"
- />
-
- getClaimableBlocks().then((result) => setWinningBlocks(result))
- }
- >
- Check Blocks
-
- {isLoading && (
-
- Checking for claimable blocks... {percentageChecked}% (Please wait)
-
- )}
- {buttonArray && buttonArray}
+
+
);
};
diff --git a/packages/miami-ui/components/Dashboard/Redeem/RedeemMining.js b/packages/miami-ui/components/Dashboard/Redeem/RedeemMining.js
new file mode 100644
index 0000000..7e49eb7
--- /dev/null
+++ b/packages/miami-ui/components/Dashboard/Redeem/RedeemMining.js
@@ -0,0 +1,224 @@
+import { useState } from "react";
+import styles from "../../../styles/RedeemMining.module.css";
+import { useAtom } from "jotai";
+import { userSessionState } from "../../../lib/auth";
+import fetch from "cross-fetch";
+import { Configuration, AccountsApi } from "@stacks/blockchain-api-client";
+import {
+ NETWORK_STRING,
+ CITY_COIN_CORE_ADDRESS,
+ CITY_COIN_CORE_CONTRACT_NAME,
+ NETWORK,
+} from "../../../lib/constants";
+import { canClaimMiningReward } from "../../../lib/contracts";
+import { useConnect } from "@syvita/connect-react";
+import { uintCV } from "@syvita/transactions";
+
+const RedeemMining = () => {
+ const [userSession] = useAtom(userSessionState);
+
+ let STXAddress = "";
+ const userData = userSession.loadUserData();
+ const { doContractCall } = useConnect();
+ const [isLoading, setIsLoading] = useState(false);
+ const [percentageChecked, setPercentageChecked] = useState(0);
+ const [startBlock, setStartBlock] = useState(0);
+ const [endBlock, setEndBlock] = useState(0);
+
+ if (NETWORK_STRING == "mainnet") {
+ STXAddress = userData.profile.stxAddress.mainnet;
+ } else {
+ STXAddress = userData.profile.stxAddress.testnet;
+ }
+
+ const [winningBlocks, setWinningBlocks] = useState([]);
+
+ let buttonArray = [];
+ let totalWinnings = [];
+
+ async function getClaimableBlocks() {
+ setIsLoading(true);
+ let basePath = "https://stacks-node-api.mainnet.stacks.co";
+
+ if (NETWORK_STRING != "mainnet") {
+ basePath = "https://stacks-node-api.testnet.stacks.co";
+ }
+
+ const apiConfig = new Configuration({
+ fetchApi: fetch,
+ basePath: basePath,
+ });
+ const accountsApi = new AccountsApi(apiConfig);
+ const response = await accountsApi.getAccountTransactions({
+ limit: 50,
+ principal: STXAddress,
+ });
+ const txs = response.results.filter(
+ (tx) =>
+ tx.tx_status === "success" &&
+ tx.tx_type === "contract_call" &&
+ (tx.contract_call.function_name === "mine-tokens" ||
+ tx.contract_call.function_name === "mine-many") &&
+ tx.contract_call.contract_id ===
+ `${CITY_COIN_CORE_ADDRESS}.${CITY_COIN_CORE_CONTRACT_NAME}`
+ );
+
+ let blocksMined = [];
+
+ let singleBlocksMined = [];
+
+ // ** MAGIC **
+ for (let i = 0; i < txs.length; i++) {
+ if (txs[i].contract_call.function_name === "mine-tokens") {
+ singleBlocksMined.push(txs[i].block_height);
+ } else if (txs[i].contract_call.function_name === "mine-many") {
+ blocksMined.push(txs[i].block_height);
+ let blocks = txs[i].contract_call.function_args[0].repr;
+ var many_amount = (blocks.match(/u/g) || []).length;
+ for (let j = 1; j <= many_amount; j++) {
+ blocksMined.push(txs[i].block_height + j);
+ }
+ }
+ }
+
+ let blocksToCheck = singleBlocksMined.concat(blocksMined);
+
+ blocksToCheck = blocksToCheck.filter(Number).sort((a, b) => a - b);
+ blocksToCheck = [...new Set(blocksToCheck)];
+
+ let blocksToCheckInRange = [];
+
+ blocksToCheck.forEach(function (block) {
+ if (startBlock > 0 && endBlock > 0) {
+ if (block >= startBlock && block <= endBlock) {
+ blocksToCheckInRange.push(block);
+ }
+ } else {
+ blocksToCheckInRange.push(block);
+ }
+ });
+
+ function sleep(milliseconds) {
+ const date = Date.now();
+ let currentDate = null;
+ do {
+ currentDate = Date.now();
+ } while (currentDate - date < milliseconds);
+ }
+
+ const canClaimArray = [];
+ console.log("LIST OF BLOCKS TO CHECK: " + blocksToCheckInRange);
+
+ for (let i = 0; i < blocksToCheckInRange.length; i++) {
+ let percent = Math.floor((i / blocksToCheckInRange.length) * 100);
+ setPercentageChecked(percent);
+ console.log(blocksToCheckInRange[i]);
+ let repeat = true;
+ let bool = "";
+ while (repeat) {
+ try {
+ bool = await canClaimMiningReward(
+ STXAddress,
+ blocksToCheckInRange[i]
+ );
+ console.log(bool);
+ repeat = false;
+ } catch {
+ console.log("Too many requests, retrying");
+ sleep(10000);
+ repeat = true;
+ }
+ }
+
+ if (bool == true) {
+ canClaimArray.push(blocksToCheckInRange[i]);
+ }
+ }
+ setIsLoading(false);
+ return canClaimArray;
+ }
+
+ if (
+ winningBlocks != [] &&
+ winningBlocks != undefined &&
+ winningBlocks.length != 0
+ ) {
+ console.log("WINNING BLOCKS + " + winningBlocks);
+ console.log(winningBlocks.length);
+ for (let i = 0; i < winningBlocks.length; i++) {
+ totalWinnings = +totalWinnings + +winningBlocks[i];
+ buttonArray.push(
+
claimAction(winningBlocks[i])}
+ className={styles.redeemBlocks}
+ >
+ {"#" + winningBlocks[i]}
+
+ );
+ }
+ }
+
+ async function claimAction(blockHeight) {
+ await doContractCall({
+ contractAddress: CITY_COIN_CORE_ADDRESS,
+ contractName: CITY_COIN_CORE_CONTRACT_NAME,
+ functionName: "claim-mining-reward",
+ functionArgs: [uintCV(blockHeight)],
+ network: NETWORK,
+ onFinish: (result) => {
+ setTxId(result.txId);
+ },
+ });
+ }
+
+ return (
+
+
Redeem mining rewards
+
+ Your may redeem $MIA if you have won a block. You must wait at least 100
+ blocks after you have mined in order to find out if you have won it.
+
+
+ Click the button below to check if you have won any blocks, then send
+ the transactions that appear to redeem them.
+
+
+ Optionally, input a range to check your mined blocks. (Recommended if
+ you've mined a lot of blocks!). If nothing is entered, it will check all
+ the blocks you've mined since your first mining transaction.
+
+ Start:
+
e.target.blur()}
+ onChange={(event) => setStartBlock(parseInt(event.target.value))}
+ placeholder="Block Height"
+ type="number"
+ />
+ End:
+
e.target.blur()}
+ onChange={(event) => setEndBlock(parseInt(event.target.value))}
+ placeholder="Block Height"
+ type="number"
+ />
+
+ getClaimableBlocks().then((result) => setWinningBlocks(result))
+ }
+ >
+ Check Blocks
+
+ {isLoading && (
+
+ Checking for claimable blocks... {percentageChecked}% (Please wait)
+
+ )}
+ {buttonArray && buttonArray}
+
+ );
+};
+
+export default RedeemMining;
diff --git a/packages/miami-ui/components/Dashboard/Redeem/RedeemRewards.js b/packages/miami-ui/components/Dashboard/Redeem/RedeemRewards.js
new file mode 100644
index 0000000..5b17a0a
--- /dev/null
+++ b/packages/miami-ui/components/Dashboard/Redeem/RedeemRewards.js
@@ -0,0 +1,25 @@
+import styles from '../../../styles/RedeemRewards.module.css';
+
+const RedeemRewards = ({ setState }) => {
+ return (
+
+
Redeem rewards
+
+ Claim your STX rewards from stacking your MiamiCoin, or claim your MIA
+ rewards from mining MiamiCoin.
+
+
+
+ You need to have either stacked MiamiCoin or mined MiamiCoin already to
+ redeem the rewards.
+
+
+
+ setState("RedeemMining")} className={styles.redeemMining}>Mining Rewards
+ setState("RedeemStacking")} className={styles.redeemStacking}>Stacking Rewards
+
+
+ );
+};
+
+export default RedeemRewards;
\ No newline at end of file
diff --git a/packages/miami-ui/components/Dashboard/Redeem/RedeemStacking.js b/packages/miami-ui/components/Dashboard/Redeem/RedeemStacking.js
new file mode 100644
index 0000000..e249b36
--- /dev/null
+++ b/packages/miami-ui/components/Dashboard/Redeem/RedeemStacking.js
@@ -0,0 +1,214 @@
+import { useEffect, useState } from "react";
+import styles from "../../../styles/RedeemStacking.module.css";
+import { useAtom } from "jotai";
+import { userSessionState } from "../../../lib/auth";
+import {
+ getUserId,
+ getStackingRewardForCycle,
+ getCurrentCycle,
+ getStackerAtCycle,
+} from "../../../lib/contracts";
+import {
+ NETWORK_STRING,
+ CITY_COIN_CORE_ADDRESS,
+ CITY_COIN_CORE_CONTRACT_NAME,
+ NETWORK,
+ CITY_COIN_TOKEN_CONTRACT_NAME,
+ CITY_COIN_TOKEN_CONTRACT_ADDRESS,
+ CC_NAME,
+} from "../../../lib/constants";
+import { useConnect } from "@syvita/connect-react";
+import {
+ uintCV,
+ createAssetInfo,
+ makeStandardSTXPostCondition,
+ makeContractFungiblePostCondition,
+ PostConditionMode,
+ FungibleConditionCode,
+ makeContractSTXPostCondition,
+} from "@syvita/transactions";
+
+const RedeemStacking = () => {
+ const prevCycle = 1;
+ const [cycleToRedeem, setCycleToRedeem] = useState(1);
+ const [userSession] = useAtom(userSessionState);
+ const [cycleNum, setCycleNum] = useState(0);
+ const [totalSTX, setTotalSTX] = useState(0);
+ const [isLoading, setIsLoading] = useState(false);
+ const [percentageChecked, setPercentageChecked] = useState(0);
+ const [buttons, setButtons] = useState([]);
+ const userData = userSession.loadUserData();
+ const { doContractCall } = useConnect();
+
+ let STXAddress = "";
+ let buttonArray = [];
+
+ if (NETWORK_STRING == "mainnet") {
+ STXAddress = userData.profile.stxAddress.mainnet;
+ } else {
+ STXAddress = userData.profile.stxAddress.testnet;
+ }
+
+ useEffect(() => {
+ getCycleRewards();
+ }, []);
+
+ async function getCycleRewards() {
+ setIsLoading(true);
+
+ const userId = await getUserId(STXAddress);
+ const currentCycle = await getCurrentCycle();
+
+ setCycleNum(currentCycle);
+
+ if (!(cycleToRedeem > 0)) {
+ setCycleToRedeem(1);
+ }
+ let cyclesToCheck = [];
+ let startingCycle = 1;
+
+ while (startingCycle <= currentCycle) {
+ cyclesToCheck.push(startingCycle);
+ startingCycle++;
+ }
+
+ console.log(cyclesToCheck);
+ const cycleRewardDict = [];
+ let sum = 0;
+
+ for (let i = 0; i < cyclesToCheck.length; i++) {
+ let percent = Math.floor((i / cyclesToCheck.length) * 100);
+ setPercentageChecked(percent);
+ console.log(cyclesToCheck[i]);
+ let repeat = true;
+ let reward = 0;
+ let stackerInfo = [];
+ while (repeat) {
+ try {
+ reward = await getStackingRewardForCycle(userId, cyclesToCheck[i]);
+ console.log("CYCLE: " + cyclesToCheck[i]);
+ console.log("REWARD: " + reward);
+ stackerInfo = await getStackerAtCycle(userId, cyclesToCheck[i]);
+ repeat = false;
+ } catch {
+ console.log("Too many requests, retrying");
+ sleep(10000);
+ repeat = true;
+ }
+ }
+
+ sum += reward;
+
+ if (reward > 0 || stackerInfo[1] > 0) {
+ cycleRewardDict.push({
+ cycle: cyclesToCheck[i],
+ amountStacked: stackerInfo[0],
+ toReturn: stackerInfo[1],
+ reward: reward,
+ });
+ }
+ }
+
+ setTotalSTX(sum);
+
+ console.log("CYCLE REWARDS: " + JSON.stringify(cycleRewardDict));
+ setIsLoading(false);
+
+ if (
+ cycleRewardDict != [] &&
+ cycleRewardDict != undefined &&
+ cycleRewardDict.length != 0
+ ) {
+ for (let i = 0; i < cycleRewardDict.length; i++) {
+ buttonArray.push(
+
+ claimStackingReward(
+ cycleRewardDict[i].cycle,
+ cycleRewardDict[i].reward,
+ cycleRewardDict[i].amountStacked,
+ cycleRewardDict[i].toReturn
+ )
+ }
+ className={styles.redeemCycles}
+ >
+ {"CYCLE #" + cycleRewardDict[i].cycle}
+
+ );
+ }
+ setButtons(buttonArray);
+ }
+ }
+
+ function sleep(milliseconds) {
+ const date = Date.now();
+ let currentDate = null;
+ do {
+ currentDate = Date.now();
+ } while (currentDate - date < milliseconds);
+ }
+
+ async function claimStackingReward(
+ cycleToRedeem,
+ reward,
+ amountStacked,
+ toReturn
+ ) {
+ let postConditions = [];
+ if (toReturn > 0) {
+ postConditions = [
+ makeContractFungiblePostCondition(
+ CITY_COIN_CORE_ADDRESS,
+ CITY_COIN_CORE_CONTRACT_NAME,
+ FungibleConditionCode.Equal,
+ uintCV(amountStacked).value,
+ createAssetInfo(
+ CITY_COIN_TOKEN_CONTRACT_ADDRESS,
+ CITY_COIN_TOKEN_CONTRACT_NAME,
+ CC_NAME
+ )
+ ),
+ ];
+ } else {
+ postConditions = [
+ makeContractSTXPostCondition(
+ CITY_COIN_CORE_ADDRESS,
+ CITY_COIN_CORE_CONTRACT_NAME,
+ FungibleConditionCode.Equal,
+ uintCV(reward).value
+ ),
+ ];
+ }
+
+ await doContractCall({
+ contractAddress: CITY_COIN_CORE_ADDRESS,
+ contractName: CITY_COIN_CORE_CONTRACT_NAME,
+ functionName: "claim-stacking-reward",
+ functionArgs: [uintCV(cycleToRedeem)],
+ network: NETWORK,
+ postConditionMode: PostConditionMode.Deny,
+ postConditions: postConditions,
+ });
+ }
+
+ return (
+
+
Redeem stacking rewards
+
+ You have a total of {" " + (totalSTX / 1000000).toLocaleString() + " "}
+ redeemable STX from the below cycles. Send the transactions below to
+ redeem them.
+
+
You'll need to send a transaction for every cycle.
+
(Current Cycle: {cycleNum})
+ {isLoading && (
+
+ Checking for cycle rewards... {percentageChecked}% (Please wait)
+
+ )}
+ {buttons && buttons}
+
+ );
+};
+
+export default RedeemStacking;
diff --git a/packages/miami-ui/components/Dashboard/Stack/StackHowLong.js b/packages/miami-ui/components/Dashboard/Stack/StackHowLong.js
index ea59449..4a44da7 100644
--- a/packages/miami-ui/components/Dashboard/Stack/StackHowLong.js
+++ b/packages/miami-ui/components/Dashboard/Stack/StackHowLong.js
@@ -114,8 +114,12 @@ const StackHowLong = () => {
Stack MiamiCoin
- How many reward cycles do you want to stack for? Reward cycles are 2100
- blocks long (just over 2 weeks).
+ How many reward cycles do you want to stack for? Cycles are 2100 blocks
+ long (just over 2 weeks).
+
+
+ Stacking requires you lock $MIA for up to 32 consecutive cycles and 1
+ cool down cycle.
diff --git a/packages/miami-ui/styles/Redeem.module.css b/packages/miami-ui/styles/RedeemMining.module.css
similarity index 100%
rename from packages/miami-ui/styles/Redeem.module.css
rename to packages/miami-ui/styles/RedeemMining.module.css
diff --git a/packages/miami-ui/styles/RedeemRewards.module.css b/packages/miami-ui/styles/RedeemRewards.module.css
new file mode 100644
index 0000000..f783312
--- /dev/null
+++ b/packages/miami-ui/styles/RedeemRewards.module.css
@@ -0,0 +1,58 @@
+.redeem {
+ margin-top: 169px;
+ margin-left: 10%;
+ margin-right: 10%;
+ max-width: 529px;
+}
+
+.h2 {
+ font-weight: 500;
+ font-size: 24px;
+ line-height: 130%;
+}
+
+.redeem p {
+ font-weight: normal;
+ font-size: 18px;
+ line-height: 140%;
+ color: #000000;
+}
+
+.buttons {
+ display: flex;
+ flex-direction: row;
+ margin-top: 20px;
+}
+
+.mine button:hover {
+ background: #36454f;
+}
+
+.redeemStacking {
+ all: unset;
+ width: 256.5px;
+ height: 34px;
+ background: #000000;
+ border-radius: 10px;
+ color: #ffffff;
+ font-weight: 500;
+ font-size: 16px;
+ line-height: 160%;
+ text-align: center;
+ cursor: pointer;
+}
+
+.redeemMining {
+ all: unset;
+ width: 256.5px;
+ height: 34px;
+ background: #000000;
+ border-radius: 10px;
+ color: #ffffff;
+ font-weight: 500;
+ font-size: 16px;
+ line-height: 160%;
+ text-align: center;
+ cursor: pointer;
+ margin-right: 16px;
+}
diff --git a/packages/miami-ui/styles/RedeemStacking.module.css b/packages/miami-ui/styles/RedeemStacking.module.css
new file mode 100644
index 0000000..6b4600a
--- /dev/null
+++ b/packages/miami-ui/styles/RedeemStacking.module.css
@@ -0,0 +1,46 @@
+.redeemStacking {
+ margin-top: 169px;
+ margin-left: 10%;
+ margin-right: 10%;
+ max-width: 529px;
+}
+
+.h2 {
+ font-weight: 500;
+ font-size: 24px;
+ line-height: 130%;
+}
+
+.redeemStacking p {
+ font-weight: normal;
+ font-size: 18px;
+ line-height: 140%;
+ color: #000000;
+}
+
+.redeemStacking input {
+ width: 150px;
+ height: 34px;
+ margin-top: 15px;
+ margin-left: 10px;
+ background: rgba(0, 0, 0, 0.05);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ box-sizing: border-box;
+ border-radius: 10px;
+ margin-right: 16px;
+}
+
+.redeemCycles {
+ all: unset;
+ width: 500px;
+ height: 34px;
+ background: black;
+ border-radius: 10px;
+ color: white;
+ font-weight: 500;
+ font-size: 16px;
+ margin-bottom: 5px;
+ line-height: 160%;
+ text-align: center;
+ cursor: pointer;
+}
diff --git a/packages/miami-ui/styles/StackHowLong.module.css b/packages/miami-ui/styles/StackHowLong.module.css
index c07b602..9cbbfb0 100644
--- a/packages/miami-ui/styles/StackHowLong.module.css
+++ b/packages/miami-ui/styles/StackHowLong.module.css
@@ -1,5 +1,5 @@
.stack {
- margin-top: 243px;
+ margin-top: 200px;
margin-left: 10%;
margin-right: 10%;
max-width: 529px;
diff --git a/packages/miami-ui/yarn.lock b/packages/miami-ui/yarn.lock
index ea496a2..655400b 100644
--- a/packages/miami-ui/yarn.lock
+++ b/packages/miami-ui/yarn.lock
@@ -1608,11 +1608,6 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"
-err-code@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
- integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
-
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@@ -3493,11 +3488,6 @@ resolve@^2.0.0-next.3:
is-core-module "^2.2.0"
path-parse "^1.0.6"
-retry@^0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
- integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
-
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"