Skip to content

Commit cd39b87

Browse files
authored
Merge pull request #625 from threshold-network/taco
Add Taco application to dashboard
2 parents c8b4952 + a188adf commit cd39b87

File tree

62 files changed

+1150
-465
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1150
-465
lines changed

.env renamed to .env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ REACT_APP_ELECTRUM_HOST=$ELECTRUM_HOST
1818
REACT_APP_ELECTRUM_PORT=$ELECTRUM_PORT
1919
REACT_APP_MOCK_BITCOIN_CLIENT=true
2020

21-
REACT_APP_WALLET_CONNECT_PROJECT_ID=$WALLET_CONNECT_PROJECT_ID
21+
REACT_APP_WALLET_CONNECT_PROJECT_ID=$WALLET_CONNECT_PROJECT_ID
22+
23+
REACT_APP_TACO_DOMAIN=dashboard

.env.production

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ REACT_APP_ELECTRUM_PORT=$ELECTRUM_PORT
2020
REACT_APP_MOCK_BITCOIN_CLIENT=false
2121

2222
REACT_APP_WALLET_CONNECT_PROJECT_ID=$WALLET_CONNECT_PROJECT_ID
23+
REACT_APP_TACO_DOMAIN=mainnet

.env.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
REACT_APP_SUPPORTED_CHAIN_ID=1337
22
REACT_APP_MULTICALL_ADDRESS=0x086813525A7dC7dafFf015Cdf03896Fd276eab60
3+
REACT_APP_TACO_DOMAIN=dashboard

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ cypress/plugins
2121
# Yarn
2222
node_modules/
2323
yarn-error.log
24+
.env
25+
.cosine/

Dockerfile.dev

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Use the specified image
2+
FROM node:18-buster-slim
3+
4+
# Set the working directory
5+
WORKDIR /app
6+
7+
# Install dependencies
8+
RUN apt-get update && apt-get install -y python3 make g++ git openssh-client ca-certificates && \
9+
git config --global url."https://".insteadOf git:// && \
10+
rm -rf /var/lib/apt/lists/* && \
11+
apt-get clean
12+
13+
# Set the environment variables
14+
ENV PYTHON=/usr/bin/python3
15+
ENV NODE_OPTIONS=--max_old_space_size=3072
16+
17+
# Copy package files and install node modules
18+
COPY package*.json yarn.lock ./
19+
RUN npm install -g node-gyp
20+
RUN yarn install --ignore-scripts
21+
RUN yarn upgrade @keep-network/coverage-pools@sepolia \
22+
@keep-network/ecdsa@sepolia \
23+
@keep-network/keep-core@sepolia \
24+
@keep-network/keep-ecdsa@sepolia \
25+
@keep-network/random-beacon@sepolia \
26+
@keep-network/tbtc@sepolia \
27+
@keep-network/tbtc-v2@sepolia \
28+
@threshold-network/coverage-pools@npm:@keep-network/coverage-pools@sepolia \
29+
@threshold-network/solidity-contracts@sepolia
30+
RUN yarn run postinstall
31+
32+
# Expose port 3000
33+
EXPOSE 3000

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,37 @@ The following procedure allows to deploy T token dashboard to production:
112112
approval of someone else from the development team.
113113
5. Once the release action is approved, the new version is automatically
114114
deployed to `dashboard.threshold.network`.
115+
116+
## Local Development
117+
118+
Update `.env` to contain:
119+
120+
```
121+
REACT_APP_SUPPORTED_CHAIN_ID=11155111
122+
REACT_APP_ETH_HOSTNAME_HTTP=https://sepolia.infura.io/v3/<your API key here>
123+
REACT_APP_ETH_HOSTNAME_WS=wss://sepolia.infura.io/v3/<your API key here>
124+
REACT_APP_MULTICALL_ADDRESS=$MULTICALL_ADDRESS
125+
126+
REACT_APP_FEATURE_FLAG_TBTC_V2=true
127+
REACT_APP_FEATURE_FLAG_TBTC_V2_REDEMPTION=true
128+
REACT_APP_FEATURE_FLAG_MULTI_APP_STAKING=true
129+
REACT_APP_FEATURE_FLAG_FEEDBACK_MODULE=false
130+
REACT_APP_FEATURE_FLAG_POSTHOG=false
131+
REACT_APP_FEATURE_FLAG_SENTRY=$SENTRY_SUPPORT
132+
REACT_APP_SENTRY_DSN=$SENTRY_DSN
133+
134+
REACT_APP_ELECTRUM_PROTOCOL=wss
135+
REACT_APP_ELECTRUM_HOST=electrumx-server.test.tbtc.network
136+
REACT_APP_ELECTRUM_PORT=8443
137+
REACT_APP_MOCK_BITCOIN_CLIENT=false
138+
139+
REACT_APP_WALLET_CONNECT_PROJECT_ID=$WALLET_CONNECT_PROJECT_ID
140+
141+
REACT_APP_TACO_DOMAIN=dashboard
142+
```
143+
144+
Then build the docker container and run the dashboard:
145+
146+
```bash
147+
docker-compose up --build
148+
```

docker-compose.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: "3.8"
2+
3+
services:
4+
threshold-dashboard:
5+
container_name: threshold-dashboard
6+
working_dir: /app
7+
environment:
8+
- PYTHON=/usr/bin/python3
9+
- NODE_OPTIONS=--max_old_space_size=3072
10+
ports:
11+
- "3000:3000"
12+
volumes:
13+
- .:/app # Bind mount the current directory to /app in the container
14+
- /app/node_modules # This will prevent node_modules from being overwritten by the local volume
15+
command: bash -c "yarn format:fix && yarn start"
16+
build:
17+
context: .
18+
dockerfile: Dockerfile.dev

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@ledgerhq/wallet-api-client-react": "^1.1.1",
2626
"@reduxjs/toolkit": "^1.6.1",
2727
"@rehooks/local-storage": "^2.4.4",
28+
"@nucypher/nucypher-contracts": "0.13.0",
2829
"@sentry/react": "^7.33.0",
2930
"@sentry/tracing": "^7.33.0",
3031
"@testing-library/jest-dom": "^5.11.4",

src/components/Modal/DeauthorizeApplicationModal/InititateDeauthorization.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,24 @@ const InitiateDeauthorization: FC<
119119
</FlowStep>
120120
<FlowStep
121121
preTitle="Step 2"
122-
title="45 day cooldown"
122+
title={
123+
stakingAppName === "taco" ? "6 month cooldown" : "45 day cooldown"
124+
}
123125
status={FlowStepStatus.inactive}
124126
size="sm"
125127
>
126-
You must wait a 45 day cooldown to then confirm the deauthorization.
127-
This is 1 transaction.
128+
You must wait a {stakingAppName === "taco" ? "6 month" : "45 day"}{" "}
129+
cooldown to then confirm the deauthorization. This is 1 transaction.
128130
</FlowStep>
129131
</Stack>
130132
<Alert status="warning">
131133
<AlertIcon />
132-
Take note! In this 45 day cooldown period, you cannot increase or
133-
decrease your authorization. As a measure of security for the entire
134-
network, in the event of slashing you will be slashed based on your
135-
initial amount.
134+
Take note! In this {stakingAppName === "taco"
135+
? "6 month"
136+
: "45 day"}{" "}
137+
cooldown period, you cannot increase or decrease your authorization.
138+
As a measure of security for the entire network, in the event of
139+
slashing you will be slashed based on your initial amount.
136140
</Alert>
137141
</ModalBody>
138142
<ModalFooter>

src/components/Modal/MapOperatorToStakingProviderConfirmationModal/index.tsx

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import {
1111
import { AddressZero } from "@ethersproject/constants"
1212
import { BodyLg, BodyMd, H5, LabelSm } from "@threshold-network/components"
1313
import { useWeb3React } from "@web3-react/core"
14-
import { FC, useCallback } from "react"
14+
import { FC, useCallback, useState } from "react"
1515
import { ModalType } from "../../../enums"
1616
import { useRegisterMultipleOperatorsTransaction } from "../../../hooks/staking-applications/useRegisterMultipleOperatorsTransaction"
17+
import { useBondOperatorTransaction } from "../../../hooks/staking-applications/useBondOperatorTransaction"
1718
import { useRegisterOperatorTransaction } from "../../../hooks/staking-applications/useRegisterOperatorTransaction"
1819
import { useAppDispatch } from "../../../hooks/store"
1920
import { useModal } from "../../../hooks/useModal"
@@ -23,6 +24,7 @@ import { BaseModalProps } from "../../../types"
2324
import InfoBox from "../../InfoBox"
2425
import withBaseModal from "../withBaseModal"
2526
import { OnSuccessCallback } from "../../../web3/hooks"
27+
import { ApplicationForOperatorMapping } from "../MapOperatorToStakingProviderModal"
2628

2729
const OperatorMappingConfirmation: FC<
2830
BoxProps & { appName: string; operator: string; stakingProvider: string }
@@ -52,16 +54,9 @@ const OperatorMappingConfirmation: FC<
5254

5355
const MapOperatorToStakingProviderConfirmationModal: FC<
5456
BaseModalProps & {
55-
operator: string
56-
isOperatorMappedOnlyInTbtc: boolean
57-
isOperatorMappedOnlyInRandomBeacon: boolean
57+
applications: ApplicationForOperatorMapping[]
5858
}
59-
> = ({
60-
operator,
61-
isOperatorMappedOnlyInTbtc,
62-
isOperatorMappedOnlyInRandomBeacon,
63-
closeModal,
64-
}) => {
59+
> = ({ applications, closeModal }) => {
6560
const { account } = useWeb3React()
6661
const { registerMultipleOperators } =
6762
useRegisterMultipleOperatorsTransaction()
@@ -71,57 +66,77 @@ const MapOperatorToStakingProviderConfirmationModal: FC<
7166
const onSuccess = useCallback<OnSuccessCallback>(
7267
(receipt) => {
7368
openModal(ModalType.MapOperatorToStakingProviderSuccess, {
74-
transactions: [
75-
{
76-
txHash: receipt.transactionHash,
77-
application: {
78-
appName: isOperatorMappedOnlyInRandomBeacon
79-
? "tbtc"
80-
: "randomBeacon",
81-
operator,
82-
stakingProvider: account,
83-
},
69+
transactions: applications.map((app) => ({
70+
txHash: receipt.transactionHash,
71+
application: {
72+
appName: app.appName,
73+
operator: app.operator,
74+
stakingProvider: app.stakingProvider,
8475
},
85-
],
76+
})),
8677
})
8778
},
88-
[openModal, operator, account]
79+
[openModal, applications]
8980
)
81+
const [errorMessage, setErrorMessage] = useState("")
82+
const onError = useCallback((error: Error) => {
83+
setErrorMessage(error.message)
84+
}, [])
9085

9186
const { sendTransaction: registerOperatorTbtc } =
92-
useRegisterOperatorTransaction("tbtc", onSuccess)
87+
useRegisterOperatorTransaction(
88+
"tbtc",
89+
(receipt) => onSuccess(receipt),
90+
onError
91+
)
9392
const { sendTransaction: registerOperatorRandomBeacon } =
94-
useRegisterOperatorTransaction("randomBeacon", onSuccess)
93+
useRegisterOperatorTransaction(
94+
"randomBeacon",
95+
(receipt) => onSuccess(receipt),
96+
onError
97+
)
98+
const { sendTransaction: registerOperatorTaco } = useBondOperatorTransaction(
99+
"taco",
100+
(receipt) => onSuccess(receipt),
101+
onError
102+
)
95103

96104
const submitMappingOperator = async () => {
97-
if (isOperatorMappedOnlyInRandomBeacon) {
98-
const tx = await registerOperatorTbtc(operator)
99-
if (!tx) {
100-
openModal(ModalType.TransactionFailed, {
101-
error: new Error(
102-
"Transaction rejected. You are required to map the Operator Address for both apps."
103-
),
104-
closeModal: () => {
105-
closeModal()
106-
dispatch(mapOperatorToStakingProviderModalClosed())
107-
},
108-
})
105+
if (!account) {
106+
throw new Error(`Wallet not connected`)
107+
}
108+
const transactions = []
109+
for (const app of applications) {
110+
let transaction
111+
switch (app.appName) {
112+
case "tbtc":
113+
transaction = await registerOperatorTbtc(app.operator)
114+
break
115+
case "randomBeacon":
116+
transaction = await registerOperatorRandomBeacon(app.operator)
117+
break
118+
case "taco":
119+
transaction = await registerOperatorTaco(account, app.operator)
120+
break
121+
default:
122+
throw new Error(`Unsupported app name: ${app.appName}`)
109123
}
110-
} else if (isOperatorMappedOnlyInTbtc) {
111-
const tx = await registerOperatorRandomBeacon(operator)
112-
if (!tx) {
124+
if (!transaction) {
113125
openModal(ModalType.TransactionFailed, {
114126
error: new Error(
115-
"Transaction rejected. You are required to map the Operator Address for both apps."
127+
errorMessage
128+
? `Transaction rejected with error: ${errorMessage}`
129+
: `Transaction rejected. You are required to map the Operator Address for ${app.appName}.`
116130
),
131+
isExpandableError: true,
117132
closeModal: () => {
118133
closeModal()
119134
dispatch(mapOperatorToStakingProviderModalClosed())
120135
},
121136
})
137+
return
122138
}
123-
} else {
124-
await registerMultipleOperators(operator)
139+
transactions.push(transaction)
125140
}
126141
}
127142

@@ -135,26 +150,19 @@ const MapOperatorToStakingProviderConfirmationModal: FC<
135150
</H5>
136151
<BodyLg mt="4">
137152
This will require{" "}
138-
{isOperatorMappedOnlyInRandomBeacon || isOperatorMappedOnlyInTbtc
139-
? "1 transaction"
140-
: "2 transactions"}
153+
{applications.filter((app) => app.operator).length +
154+
" transaction(s)"}
141155
. Each mapping is one transaction
142156
</BodyLg>
143157
</InfoBox>
144-
{!isOperatorMappedOnlyInTbtc && (
145-
<OperatorMappingConfirmation
146-
appName="tbtc"
147-
operator={operator}
148-
stakingProvider={account ? account : AddressZero}
149-
/>
150-
)}
151-
{!isOperatorMappedOnlyInRandomBeacon && (
158+
{applications.map((app, index) => (
152159
<OperatorMappingConfirmation
153-
appName="random beacon"
154-
operator={operator}
160+
key={index}
161+
appName={app.appName}
162+
operator={app.operator}
155163
stakingProvider={account ? account : AddressZero}
156164
/>
157-
)}
165+
))}
158166
</ModalBody>
159167
<ModalFooter>
160168
<Button onClick={closeModal} variant="outline" mr={2}>

0 commit comments

Comments
 (0)