From fd22d13d00a3d942a46185b05d5f678f9d08bec6 Mon Sep 17 00:00:00 2001 From: Andrei Taranu Date: Tue, 27 Jun 2023 20:56:36 +0300 Subject: [PATCH 1/2] Create CONTRIBUTING.md (#596) --- CONTRIBUTING.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..ee7c6098 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Contributing to tezos homebase + +Thank you for your interest in contributing to tezos homebase, a web app that allows anyone to create and manage DAOs on Tezos. We welcome and appreciate any contributions, whether it is code, documentation, design, feedback, or ideas. + + +## How to contribute + +There are many ways you can contribute to our project: + +- Report bugs or suggest features by opening an [issue](https://github.com/dOrgTech/homebase-app/issues). +- Fix bugs or implement features by submitting a [pull request](https://github.com/dOrgTech/homebase-app/pulls). +- Improve the documentation or the user interface by editing the files directly on GitHub or forking the repo. +- Join our [Discord server](https://discord.gg/9cduRr5) and chat with us about the project. + +## Development setup + +To set up your local development environment, follow these steps: + +1. Fork and clone the repo: `git clone https://github.com//homebase-app.git` +2. Install the dependencies: `yarn install` +3. Create a `.env` file in the root directory and add the required environment variables (see `.env.example` for reference) +4. Run the app in development mode: `yarn start` +5. Open http://localhost:3000 to view the app in the browser + +## Pull request guidelines + +Before you submit a pull request, please make sure that: + +- Your code follows the [Prettier](https://prettier.io/) code style and format +- Your code passes the [ESLint](https://eslint.org/) checks and has no errors or warnings +- Your code is well-tested and has good coverage +- Your code is documented with comments and JSDoc annotations +- Your commit messages are clear and descriptive +- Your branch is up-to-date with the `develop` branch + +To submit a pull request, follow these steps: + +1. Create a new branch from the `develop` branch: `git checkout -b ` +2. Make your changes and commit them: `git commit -m ""` +3. Push your branch to your fork: `git push origin ` +4. Go to https://github.com/dOrgTech/homebase-app and create a new pull request from your branch to the `develop` branch +5. Fill out the pull request template and wait for a review + +## Review process + +We will review your pull request as soon as possible and provide feedback or suggestions if needed. We may ask you to make some changes before we merge your pull request. Please be patient and respectful with us and other contributors. + +Thank you for reading this guide and for contributing to tezos homebase! From 6c8903c9295c1c8bfa7bd2d2fa25d298356d06fc Mon Sep 17 00:00:00 2001 From: fabiolalombardim <37227394+fabiolalombardim@users.noreply.github.com> Date: Fri, 21 Jul 2023 06:57:27 +0200 Subject: [PATCH 2/2] UI upgrades & Self deployed step added (#609) * All Homebase modals updated (#593) * modals updated * current delegate added * Settings modal (#594) * contract field & delegate added * responsive modal * Add delegated token deployment (#592) Signed-off-by: Manank Patni * ui upgrades & self deployed step added * faq links changed * article link added - deployment type * Add api call to deployer Signed-off-by: Manank Patni * Add backend logic * Fix states and progress Signed-off-by: Manank Patni * Add DAO Deployer API ENV Signed-off-by: Manank Patni * states on deployment fixed --------- Signed-off-by: Manank Patni Co-authored-by: Manank Patni --- src/assets/img/download.svg | 3 + src/assets/img/lite-dao.svg | 9 +- src/assets/img/managed.svg | 3 + src/assets/img/self-deployed.svg | 3 + src/modules/common/CopyAddress.tsx | 2 +- src/modules/common/CopyButton.tsx | 7 +- src/modules/common/MainButton.tsx | 1 + src/modules/common/SmallButton.tsx | 1 + src/modules/common/TitleBlock.tsx | 30 +- .../creator/components/NavigationBar.tsx | 15 +- src/modules/creator/index.tsx | 28 +- src/modules/creator/state/types.ts | 2 + src/modules/creator/steps/DaoSettings.tsx | 96 +- src/modules/creator/steps/DeploymentType.tsx | 156 + src/modules/creator/steps/Governance.tsx | 39 +- src/modules/creator/steps/Quorum.tsx | 404 +- src/modules/creator/steps/Review.tsx | 74 +- src/modules/creator/steps/Summary.tsx | 4 +- src/modules/creator/steps/Template.tsx | 14 +- src/modules/creator/steps/index.tsx | 25 +- src/modules/explorer/components/BatchBar.tsx | 22 +- .../components/ConfigProposalForm.tsx | 132 +- .../DelegationChangeProposalForm.tsx | 71 +- .../components/GuardianChangeProposalForm.tsx | 96 +- .../components/NewTreasuryProposalDialog.tsx | 16 +- .../explorer/components/ProposalForm.tsx | 48 +- .../explorer/components/ProposalFormInput.tsx | 2 +- .../components/ProposalFormSendButton.tsx | 5 +- .../explorer/components/ResponsiveDialog.tsx | 29 +- .../pages/Config/components/DAOInfoTable.tsx | 268 +- .../pages/DAO/components/Settings.tsx | 41 +- src/modules/explorer/pages/DAOList/index.tsx | 5 - .../explorer/pages/Proposals/index.tsx | 4 - src/services/config/constants.ts | 3 +- .../contracts/baseDAO/hooks/useOriginate.ts | 241 +- src/services/contracts/baseDAO/types.ts | 3 +- src/services/contracts/baseDAO/utils.ts | 9 + .../contracts/token/assets/MultiAsset.json | 4592 ----------------- .../assets/fa2_single_asset_delegated.ts | 938 ++++ .../contracts/token/hooks/useToken.ts | 8 +- src/services/contracts/token/index.ts | 39 +- src/theme/index.ts | 6 +- src/theme/legacy.ts | 7 +- 43 files changed, 2194 insertions(+), 5307 deletions(-) create mode 100644 src/assets/img/download.svg create mode 100644 src/assets/img/managed.svg create mode 100644 src/assets/img/self-deployed.svg create mode 100644 src/modules/creator/steps/DeploymentType.tsx delete mode 100644 src/services/contracts/token/assets/MultiAsset.json create mode 100644 src/services/contracts/token/assets/fa2_single_asset_delegated.ts diff --git a/src/assets/img/download.svg b/src/assets/img/download.svg new file mode 100644 index 00000000..b3f04df2 --- /dev/null +++ b/src/assets/img/download.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/lite-dao.svg b/src/assets/img/lite-dao.svg index c3bfe185..4a78a7d7 100644 --- a/src/assets/img/lite-dao.svg +++ b/src/assets/img/lite-dao.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/src/assets/img/managed.svg b/src/assets/img/managed.svg new file mode 100644 index 00000000..b7f7df8d --- /dev/null +++ b/src/assets/img/managed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/self-deployed.svg b/src/assets/img/self-deployed.svg new file mode 100644 index 00000000..c5786f01 --- /dev/null +++ b/src/assets/img/self-deployed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/modules/common/CopyAddress.tsx b/src/modules/common/CopyAddress.tsx index af74a764..71c0fc32 100644 --- a/src/modules/common/CopyAddress.tsx +++ b/src/modules/common/CopyAddress.tsx @@ -16,7 +16,7 @@ export const CopyAddress: React.FC = ({ address, typographyProps }) => { <> - + {isMobileSmall ? toShortAddress(address) : address} diff --git a/src/modules/common/CopyButton.tsx b/src/modules/common/CopyButton.tsx index af259835..3b2d9f0b 100644 --- a/src/modules/common/CopyButton.tsx +++ b/src/modules/common/CopyButton.tsx @@ -1,8 +1,9 @@ import React, { useState } from "react" import { Box, styled, Tooltip } from "@material-ui/core" -import { FileCopyOutlined } from "@material-ui/icons" +import { FileCopyOutlined, Image } from "@material-ui/icons" +import DownloadIcon from "assets/img/download.svg" -const CopyIcon = styled(FileCopyOutlined)({ +const CopyIcon = styled("img")({ cursor: "pointer" }) @@ -23,7 +24,7 @@ export const CopyButton: React.FC<{ text: string; style?: any }> = ({ text, styl }} > - + ) diff --git a/src/modules/common/MainButton.tsx b/src/modules/common/MainButton.tsx index c22aed76..7c195a97 100644 --- a/src/modules/common/MainButton.tsx +++ b/src/modules/common/MainButton.tsx @@ -7,6 +7,7 @@ export const MainButton = styled(Button)(({ theme }) => ({ "transition": ".15s ease-in", "background": theme.palette.secondary.main, "textTransform": "none", + "borderRadius": 8, "&$disabled": { boxShadow: "none" diff --git a/src/modules/common/SmallButton.tsx b/src/modules/common/SmallButton.tsx index 29a66d65..39d060bb 100644 --- a/src/modules/common/SmallButton.tsx +++ b/src/modules/common/SmallButton.tsx @@ -6,6 +6,7 @@ export const SmallButton = styled(Button)({ "boxShadow": "0px 0px 7px -2px rgba(0, 0, 0, 0.2)", "transition": ".15s ease-out", "textTransform": "capitalize", + "borderRadius": 8, "&$disabled": { boxShadow: "none" diff --git a/src/modules/common/TitleBlock.tsx b/src/modules/common/TitleBlock.tsx index 247a852d..2eed2299 100644 --- a/src/modules/common/TitleBlock.tsx +++ b/src/modules/common/TitleBlock.tsx @@ -1,4 +1,4 @@ -import { Grid, Paper, styled, Tooltip, Typography } from "@material-ui/core" +import { Grid, Link, Paper, styled, Tooltip, Typography } from "@material-ui/core" import React from "react" import { ReactElement } from "react-markdown/lib/react-markdown" import { InfoRounded } from "@material-ui/icons" @@ -7,14 +7,9 @@ import { CopyButton } from "./CopyButton" const StyledGrid = styled(Grid)({ height: "fit-content", - background: "#2F3438", borderRadius: 8, - padding: "30px 40px", - marginBottom: 38 -}) - -const CustomTypography = styled(Typography)({ - marginTop: 27 + padding: "0", + gap: 16 }) const CustomTooltip = styled(Tooltip)({ @@ -33,7 +28,7 @@ const InfoIconInput = styled(InfoRounded)(({ theme }) => ({ })) const CustomTooltipText = styled(Typography)({ - fontSize: 12, + fontSize: 14, marginLeft: 2 }) @@ -50,9 +45,16 @@ interface Props { description: ReactElement | string tooltip?: boolean tooltipText?: string + tooltipLink?: string } -export const TitleBlock: React.FC = ({ title = "", description, tooltip = false, tooltipText = "" }) => { +export const TitleBlock: React.FC = ({ + title = "", + description, + tooltip = false, + tooltipText = "", + tooltipLink = "" +}) => { return ( @@ -66,9 +68,9 @@ export const TitleBlock: React.FC = ({ title = "", description, tooltip = - + {tooltipText} - + ) : null} @@ -79,9 +81,9 @@ export const TitleBlock: React.FC = ({ title = "", description, tooltip = {description} ) : description ? ( - + {description} - + ) : null} diff --git a/src/modules/creator/components/NavigationBar.tsx b/src/modules/creator/components/NavigationBar.tsx index 218709f6..c74bac0b 100644 --- a/src/modules/creator/components/NavigationBar.tsx +++ b/src/modules/creator/components/NavigationBar.tsx @@ -3,6 +3,7 @@ import React from "react" import { ArrowBackIos } from "@material-ui/icons" import { NavigationBarProps } from "modules/creator/state" +import { MainButton } from "modules/common/MainButton" const Footer = styled(Grid)(({ theme }) => ({ background: theme.palette.primary.main, @@ -27,14 +28,12 @@ const BackButton = styled(Paper)({ width: "fit-content" }) -const NextButton = styled(Paper)(({ theme }) => ({ - boxShadow: "none", - borderRadius: 4, +const NextButton = styled(MainButton)(({ theme }) => ({ textAlign: "center", float: "right", cursor: "pointer", background: theme.palette.secondary.light, - padding: 8 + padding: "8px 16px" })) const BackButtonIcon = styled(ArrowBackIos)(({ theme }) => ({ @@ -58,14 +57,18 @@ export const NavigationBar: React.FC = ({ back, next }) => { {back && ( - {back.text} + + {back.text} + )} {next && ( - {next.text} + + {next.text} + )} diff --git a/src/modules/creator/index.tsx b/src/modules/creator/index.tsx index 0029cf90..20985732 100644 --- a/src/modules/creator/index.tsx +++ b/src/modules/creator/index.tsx @@ -10,13 +10,14 @@ import { styled, useMediaQuery, useTheme, - Theme + Theme, + Link } from "@material-ui/core" import ProgressBar from "react-customizable-progressbar" import { useHistory } from "react-router" import { CreatorContext, StepInfo } from "modules/creator/state" -import { StepRouter, STEPS, useStepNumber } from "modules/creator/steps" +import { StepRouter, STEPS, urlToStepMap, useStepNumber } from "modules/creator/steps" import { NavigationBar } from "modules/creator/components/NavigationBar" import { Navbar } from "modules/common/Toolbar" import mixpanel from "mixpanel-browser" @@ -26,7 +27,6 @@ const PageContainer = styled(Grid)(({ theme }) => ({ })) const StepContentContainer = styled(Grid)({ - marginTop: 28, alignItems: "baseline", height: "100%", paddingTop: 0, @@ -72,18 +72,17 @@ const FAQClickToAction = styled(Typography)(({ theme }) => ({ color: theme.palette.secondary.main, fontSize: "14px", cursor: "pointer", - marginTop: 16, - marginBottom: 8 + fontWeight: 300 })) const ProgressContainer = styled(Grid)(({ theme }) => ({ background: "#2F3438", display: "grid", borderRadius: 8, - maxHeight: 585, + maxHeight: 650, paddingTop: 20, position: "sticky", - top: 153 + top: 130 })) const custom = (theme: Theme) => ({ @@ -127,10 +126,6 @@ export const DAOCreate: React.FC = () => { const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down("sm")) - const goToFAQ = (): void => { - history.push("/faq") - } - useEffect(() => { mixpanel.unregister("daoAddress") mixpanel.unregister("daoType") @@ -146,7 +141,7 @@ export const DAOCreate: React.FC = () => { { trackStrokeColor={"rgba(255, 255, 255, 0.2)"} > - {progress === 0.5 ? 0 : step * 20}% + {Math.floor((step / (Object.keys(urlToStepMap).length - 1)) * 100)}% - New to DAOs? Read our FAQ + New to DAOs? + + Read our FAQ + {STEPS.map(({ title, path }: StepInfo, index: number) => ( @@ -181,7 +179,7 @@ export const DAOCreate: React.FC = () => { - {step < 5 && } + {step < 6 && } diff --git a/src/modules/creator/state/types.ts b/src/modules/creator/state/types.ts index 3ecee0a3..6bbe0081 100644 --- a/src/modules/creator/state/types.ts +++ b/src/modules/creator/state/types.ts @@ -68,6 +68,8 @@ export interface NavigationBarProps { export type DAOTemplate = "lambda" | "lite" | "" +export type DeploymentMethod = "managed" | "self-deployed" + type DeploymentStatus = { deploying: boolean successful: boolean diff --git a/src/modules/creator/steps/DaoSettings.tsx b/src/modules/creator/steps/DaoSettings.tsx index 69f6e66b..9c5f7651 100644 --- a/src/modules/creator/steps/DaoSettings.tsx +++ b/src/modules/creator/steps/DaoSettings.tsx @@ -70,6 +70,9 @@ const CustomFormikTextField = withStyles({ "& .MuiInputBase-input": { textAlign: "initial" }, + "& .MuiInputBase-root": { + textWeight: 300 + }, "& .MuiInput-underline:before": { borderBottom: "none !important" }, @@ -93,11 +96,13 @@ const CustomTextarea = styled(withTheme(TextareaAutosize))(props => ({ "marginTop": 14, "fontWeight": 300, "padding": "21px 20px", - "fontFamily": "system-ui", "border": "none", "fontSize": 16, + "fontFamily": "Roboto Mono", "color": props.theme.palette.text.secondary, "background": "#2F3438", + "lineHeight": "135%", + "letterSpacing": -0.18, "borderRadius": 8, "paddingRight": 40, "wordBreak": "break-word", @@ -158,6 +163,22 @@ const DaoSettingsForm = withRouter(({ submitForm, values, setFieldValue, errors, return ( <> + + + {" "} + DAO Name{" "} + + + + + {errors.name && touched.name ? {errors.name} : null} + {" "} @@ -215,55 +236,12 @@ const DaoSettingsForm = withRouter(({ submitForm, values, setFieldValue, errors, )} - - - - {" "} - DAO Name{" "} - - - - - {errors.name && touched.name ? {errors.name} : null} - - - - - - Description - - - - - {() => ( - { - setFieldValue("description", newValue.target.value) - }} - /> - )} - - - - - - {errors.description && touched.description ? {errors.description} : null} {" "} - Guardian{" "} + Guardian Address{" "} @@ -294,6 +272,32 @@ const DaoSettingsForm = withRouter(({ submitForm, values, setFieldValue, errors, {errors.guardian && touched.guardian ? {errors.guardian} : null} + + + + DAO Description + + + + + {() => ( + { + setFieldValue("description", newValue.target.value) + }} + /> + )} + + + + + + {errors.description && touched.description ? {errors.description} : null} + ) }) @@ -383,7 +387,7 @@ export const DaoSettings = (): JSX.Element => { return ( These settings will define the name, symbol, and initial distribution of your token. You will need a diff --git a/src/modules/creator/steps/DeploymentType.tsx b/src/modules/creator/steps/DeploymentType.tsx new file mode 100644 index 00000000..8fd999d4 --- /dev/null +++ b/src/modules/creator/steps/DeploymentType.tsx @@ -0,0 +1,156 @@ +import React, { useContext, useEffect, useState } from "react" +import { Grid, styled, Typography, Box, useMediaQuery, useTheme, makeStyles, Link } from "@material-ui/core" +import { useHistory } from "react-router" + +import { ReactComponent as ManagedIcon } from "assets/img/managed.svg" +import { ReactComponent as SelfDeployedIcon } from "assets/img/self-deployed.svg" + +import { ActionTypes, CreatorContext, DeploymentMethod } from "modules/creator/state" +import { TitleBlock } from "modules/common/TitleBlock" +import { useRouteMatch } from "react-router-dom" + +const LambdaCustomBox = styled(Grid)(({ theme }) => ({ + "height": 480, + "marginTop": 30, + "background": "#2F3438", + "borderRadius": 8, + "maxWidth": 320, + "width": "-webkit-fill-available", + "padding": "40px 44px", + "textAlign": "start", + "cursor": "pointer", + "paddingBottom": 0, + "&:hover": { + border: "3px solid rgba(129, 254, 183, 0.4)", + paddingTop: 37, + paddingBottom: 0, + paddingRight: 41, + paddingLeft: 41 + }, + ["@media (max-width:1167px)"]: { + marginBottom: 20, + marginTop: 20 + } +})) + +const styles = makeStyles({ + selected: { + border: "3px solid rgba(129, 254, 183, 0.4)", + padding: "37px 41px" + } +}) + +const BoxTitle = styled(Typography)({ + fontSize: 18, + fontWeight: 500, + fontFamily: "Roboto Mono", + marginBottom: 10 +}) + +const BoxDescription = styled(Typography)({ + fontWeight: 300, + fontSize: 16 +}) + +export const DeploymentType = (): JSX.Element => { + const { state, dispatch, updateCache } = useContext(CreatorContext) + const { template } = state.data + + const history = useHistory() + + const match = useRouteMatch() + + const theme = useTheme() + const style = styles() + + const isMobileSmall = useMediaQuery(theme.breakpoints.down("xs")) + + const [selectedTemplate, setTemplate] = useState("managed") + const [error, setError] = useState(false) + + useEffect(() => { + dispatch({ + type: ActionTypes.UPDATE_NAVIGATION_BAR, + next: { + handler: () => { + history.push(`review`, { method: selectedTemplate }) + }, + text: "Deploy DAO" + }, + back: { + text: "Back", + handler: () => history.push(`summary`) + } + }) + }, [dispatch, history, match.path, match.url, selectedTemplate]) + + const update = (templateValue: DeploymentMethod) => { + setError(false) + setTemplate(templateValue) + } + + return ( + + + Learn more about the two available deployment options in{" "} + + this article + {" "} + + } + /> + + update("managed")} + className={selectedTemplate === "managed" ? style.selected : ""} + > + + Managed + + + Homebase will deploy a contract on-chain with your parameters using a dedicated endpoint.{" "} + + + Requires upfront payment for the transaction fees (7 XTZ).{" "} + + Takes between 3 and 5 minutes. + + {" "} + update("self-deployed")} + className={selectedTemplate === "self-deployed" ? style.selected : ""} + > + + Self-Deployed + + Use your private key to sign four transactions. + + May need multiple tries as bytecode can get stuck between app and wallet. If it’s not working, please use + the managed option. + + Can take up to 15 minutes. + + {" "} + + + ) +} diff --git a/src/modules/creator/steps/Governance.tsx b/src/modules/creator/steps/Governance.tsx index f9bdb2ea..00585a4c 100644 --- a/src/modules/creator/steps/Governance.tsx +++ b/src/modules/creator/steps/Governance.tsx @@ -14,7 +14,6 @@ import dayjs from "dayjs" import { TitleBlock } from "modules/common/TitleBlock" import BigNumber from "bignumber.js" import { mutezToXtz, parseUnits } from "services/contracts/utils" -import { formatUnits } from "services/contracts/utils" import { FieldChange, handleChange } from "../utils" const TimeBox = styled(Grid)(({ theme }) => ({ @@ -28,7 +27,8 @@ const TimeBox = styled(Grid)(({ theme }) => ({ const TimeText = styled(Typography)({ marginTop: -20, - marginLeft: 16 + marginLeft: 16, + fontWeight: 300 }) const CustomTooltip = styled(Tooltip)({ @@ -151,7 +151,8 @@ const Value = styled(Typography)({ const styles = { voting: { marginTop: 6, - marginBottom: 16 + marginBottom: 16, + fontWeight: 400 } } @@ -177,8 +178,13 @@ const GridNoPadding = styled(Grid)({ const InfoBox = styled(Paper)({ boxShadow: "none", border: "none", - background: "inherit", - marginTop: 20 + marginTop: 20, + justifyContent: "center", + alignItems: "center", + gap: 10, + backgroundColor: "#2F3438", + borderRadius: 8, + padding: "32px 48px" }) const validateForm = (values: VotingSettings) => { @@ -376,14 +382,6 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se return "0 minutes" } - // const controlMaxFieldLimit = (field: string, value: any) => { - // const itemValue = value.target.value.split(".") - // if ((itemValue[0] && itemValue[0].length > 18) || (itemValue[1] && itemValue[1].length > 8)) { - // return value.preventDefault() - // } - // setFieldValue(field, value.target.value) - // } - useEffect(() => { if (values) { dispatch({ @@ -726,16 +724,16 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se - + You will need to wait for a full cycle before making your first proposal. - + {`A proposal will accept votes for ${formatDate(votingTime)} after it is created. Once the voting cycle ends, if the proposal is accepted, it will become executable after another ${formatDate( flushDelayTime )}.`} - + If not executed within {formatDate(expiryDelayTime)} after voting ends, the proposal will expire and won't be available for execution anymore. @@ -744,7 +742,7 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se > - + Required Stake to Propose @@ -796,12 +794,12 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se - + Returned Stake After Proposal Rejection - + {() => ( @@ -897,8 +895,9 @@ export const Governance: React.FC = () => { diff --git a/src/modules/creator/steps/Quorum.tsx b/src/modules/creator/steps/Quorum.tsx index 77f733a7..92b9edfa 100644 --- a/src/modules/creator/steps/Quorum.tsx +++ b/src/modules/creator/steps/Quorum.tsx @@ -14,12 +14,16 @@ const ErrorText = styled(Typography)({ display: "flex", minWidth: "100%", fontSize: 14, - color: "red" + color: "red", + height: 42 }) -const SpacingContainer = styled(Grid)({ - marginTop: 25 -}) +const SpacingContainer = styled(Grid)(({ theme }) => ({ + marginTop: 25, + [theme.breakpoints.down("sm")]: { + gap: 16 + } +})) const AdditionContainer = styled(Grid)(({ theme }) => ({ marginTop: 14, @@ -63,11 +67,6 @@ const ValueText = styled(Typography)({ } }) -const GridItemContainer = styled(Grid)(() => ({ - display: "flex", - alignItems: "center" -})) - const InfoIconInput = styled(InfoRounded)(({ theme }) => ({ cursor: "default", color: theme.palette.secondary.light, @@ -91,32 +90,6 @@ const ParentContainer = styled(Grid)({ } }) -const CustomInputContainer = styled(Grid)(({ theme }) => ({ - border: "none", - height: 54, - marginTop: 14, - background: "#2F3438", - borderRadius: 8, - alignItems: "center", - justifyContent: "end", - padding: "12px 25px", - minWidth: 150, - maxWidth: 150, - ["@media (max-width:1167px)"]: { - maxWidth: "100%", - minWidth: "100%", - paddingLeft: 25, - paddingRight: 25 - } -})) - -const InputContainer = styled(Grid)({ - paddingRight: 15, - ["@media (max-width:1167px)"]: { - paddingRight: 0 - } -}) - const validateForm = (values: QuorumSettings) => { const errors: FormikErrors = {} @@ -192,181 +165,199 @@ const QuorumForm = ({ submitForm, values, errors, touched, setFieldValue, setFie return ( <> - - - Quorum Threshold - + + + + Initial Quorum Threshold + + + + + + handleChange(e)} + placeholder="00" + inputProps={{ min: 0, max: 100, step: 1 }} + component={TextField} + InputProps={{ + endAdornment: % + }} + onClick={() => setFieldTouched("quorumThreshold")} + // onChange={(e: any) => controlMaxFieldLimit("quorumThreshold", e)} + /> + + + + + + + + + + {errors.quorumThreshold && touched.quorumThreshold ? {errors.quorumThreshold} : null} + + + + + + Initial Quorum Change + + + + + + handleChange(e)} + placeholder="00" + inputProps={{ min: 0, max: 100, step: 1 }} + component={TextField} + InputProps={{ + endAdornment: % + }} + onClick={() => setFieldTouched("quorumChange")} + // onChange={(e: any) => controlMaxFieldLimit("quorumChange", e)} + /> + + + + + + + + + + {errors.quorumChange && touched.quorumChange ? {errors.quorumChange} : null} + + - - - - - - handleChange(e)} - placeholder="00" - inputProps={{ min: 0, max: 100, step: 1 }} - component={TextField} - InputProps={{ - endAdornment: % - }} - onClick={() => setFieldTouched("quorumThreshold")} - // onChange={(e: any) => controlMaxFieldLimit("quorumThreshold", e)} - /> - - - - - - - - - - - - - - - handleChange(e)} - placeholder="00" - inputProps={{ min: 0, max: 100, step: 1 }} - component={TextField} - InputProps={{ - endAdornment: % - }} - onClick={() => setFieldTouched("minQuorumAmount")} - // onChange={(e: any) => controlMaxFieldLimit("minQuorumAmount", e)} - > - - - Min - - - - - - - - - - - - handleChange(e)} - placeholder="00" - inputProps={{ min: 0, max: 100, step: 1 }} - component={TextField} - InputProps={{ - endAdornment: % - }} - onClick={() => setFieldTouched("maxQuorumAmount")} - // onChange={(e: any) => controlMaxFieldLimit("maxQuorumAmount", e)} - > - - - Max - - - - - - - - {errors.quorumThreshold && touched.quorumThreshold ? {errors.quorumThreshold} : null} - {errors.minQuorumAmount && touched.minQuorumAmount ? {errors.minQuorumAmount} : null} - {errors.maxQuorumAmount && touched.maxQuorumAmount ? {errors.maxQuorumAmount} : null} - - - - - Quorum Change - + + + + Min. Quorum Threshold + + + + + + handleChange(e)} + placeholder="00" + inputProps={{ min: 0, max: 100, step: 1 }} + component={TextField} + InputProps={{ + endAdornment: % + }} + onClick={() => setFieldTouched("minQuorumAmount")} + // onChange={(e: any) => controlMaxFieldLimit("minQuorumAmount", e)} + > + + + + + + + + + + {errors.minQuorumAmount && touched.minQuorumAmount ? {errors.minQuorumAmount} : null} + + + + + + Max. Quorum Change + + + + + + handleChange(e)} + placeholder="00" + inputProps={{ min: 0, max: 100, step: 1 }} + component={TextField} + InputProps={{ + endAdornment: % + }} + onClick={() => setFieldTouched("quorumMaxChange")} + // onChange={(e: any) => controlMaxFieldLimit("quorumMaxChange", e)} + /> + + + + + + + + + + {errors.quorumMaxChange && touched.quorumMaxChange ? {errors.quorumMaxChange} : null} + + - - - - - handleChange(e)} - placeholder="00" - inputProps={{ min: 0, max: 100, step: 1 }} - component={TextField} - InputProps={{ - endAdornment: % - }} - onClick={() => setFieldTouched("quorumChange")} - // onChange={(e: any) => controlMaxFieldLimit("quorumChange", e)} - /> - - - - - - - - - - {errors.quorumChange && touched.quorumChange ? {errors.quorumChange} : null} - - - - - Quorum Max Change - + + + + Max. Quorum Threshold + + + + + + handleChange(e)} + placeholder="00" + inputProps={{ min: 0, max: 100, step: 1 }} + component={TextField} + InputProps={{ + endAdornment: % + }} + onClick={() => setFieldTouched("maxQuorumAmount")} + // onChange={(e: any) => controlMaxFieldLimit("maxQuorumAmount", e)} + > + + + + + + + + + + {errors.maxQuorumAmount && touched.maxQuorumAmount ? {errors.maxQuorumAmount} : null} + + - - - - - - handleChange(e)} - placeholder="00" - inputProps={{ min: 0, max: 100, step: 1 }} - component={TextField} - InputProps={{ - endAdornment: % - }} - onClick={() => setFieldTouched("quorumMaxChange")} - // onChange={(e: any) => controlMaxFieldLimit("quorumMaxChange", e)} - /> - - - - - - - - - - {errors.quorumMaxChange && touched.quorumMaxChange ? {errors.quorumMaxChange} : null} - ) } @@ -399,8 +390,9 @@ export const Quorum: React.FC = () => { "\u0027" + "s total supply" } - tooltipText={"Quorum Settings"} + tooltipText={"Quorum"} tooltip={true} + tooltipLink={"how-to-configure-your-dao-in-homebase/configure-proposal-and-voting"} > { activeState } = useOriginate(state.data.template) const history = useHistory() - console.log("states: ", states) + + const historyState = history.location?.state as { method: DeploymentMethod } + const deploymentMethod = historyState.method // TODO: Fix infinite calling here useEffect(() => { ;(async () => { - if (!validDAOData && info && metadataCarrierParams) { + if (!validDAOData && info && metadataCarrierParams && deploymentMethod) { mutate({ metadataParams: metadataCarrierParams, - params: info + params: info, + deploymentMethod }) } })() @@ -100,39 +103,44 @@ export const Review: React.FC = () => { - - - Deploying - - - {" "} - {state.data.orgSettings.name} - - - {" "} - to the Tezos Network - - - - - {data && data.address ? ( - history.push("/explorer/dao/" + data.address)} - > - Go to my DAO - - ) : null} - - + {data && !data.address ? ( + + + Deploying + + + {" "} + {state.data.orgSettings.name} + + + {" "} + to the Tezos Network + + + ) : null} + + + {data && data.address ? ( + history.push("/explorer/dao/" + data.address)} + > + Go to my DAO + + ) : null} + + + {states[0].activeText !== "" && states[2].completedText === "" && error === null ? ( - - This may take several minutes - + data && data.address ? null : ( + + This may take several minutes, Do not close the tab + + ) ) : null} ) : ( diff --git a/src/modules/creator/steps/Summary.tsx b/src/modules/creator/steps/Summary.tsx index 6704bdb4..65b9935b 100644 --- a/src/modules/creator/steps/Summary.tsx +++ b/src/modules/creator/steps/Summary.tsx @@ -113,9 +113,9 @@ export const Summary = (): JSX.Element => { type: ActionTypes.UPDATE_NAVIGATION_BAR, next: { handler: () => { - history.push(`review`) + history.push(`type`) }, - text: "Launch" + text: "Continue" }, back: { handler: () => history.push(`quorum`), diff --git a/src/modules/creator/steps/Template.tsx b/src/modules/creator/steps/Template.tsx index db9dc8d6..629265e2 100644 --- a/src/modules/creator/steps/Template.tsx +++ b/src/modules/creator/steps/Template.tsx @@ -1,7 +1,6 @@ import React, { useContext, useEffect, useState } from "react" import { Grid, styled, Typography, Box, useMediaQuery, useTheme, makeStyles } from "@material-ui/core" import { useHistory } from "react-router" -import { ReactComponent as LambdaIcon } from "assets/img/lambda.svg" import { ReactComponent as LiteIcon } from "assets/img/lite-dao.svg" import { ReactComponent as FullIcon } from "assets/img/full-dao.svg" @@ -57,7 +56,10 @@ const BoxTitle = styled(Typography)({ const BoxDescription = styled(Typography)({ fontWeight: 300, - fontSize: 16 + fontSize: 16, + lineHeight: "135%", + letterSpacing: -0.18, + alignSelf: "stretch" }) export const Template = (): JSX.Element => { @@ -95,6 +97,10 @@ export const Template = (): JSX.Element => { return history.push("/lite") }, text: "Continue" + }, + back: { + text: "Back", + handler: () => history.push("/creator/ownership") } }) }, [dispatch, history, match.path, match.url, selectedTemplate]) @@ -118,7 +124,7 @@ export const Template = (): JSX.Element => { onClick={() => update("lambda")} className={selectedTemplate === "lambda" ? style.selected : ""} > - + Full DAO Contract interaction. Transfer assets based on vote outcomes. @@ -134,7 +140,7 @@ export const Template = (): JSX.Element => { onClick={() => update("lite")} className={selectedTemplate === "lite" ? style.selected : ""} > - + Lite DAO Off-chain weighted voting. Multiple voting strategies. No treasury.{" "} diff --git a/src/modules/creator/steps/index.tsx b/src/modules/creator/steps/index.tsx index 5deeaa22..efc92a1f 100644 --- a/src/modules/creator/steps/index.tsx +++ b/src/modules/creator/steps/index.tsx @@ -9,22 +9,25 @@ import { ProtectedRoute } from "modules/creator/components/ProtectedRoute" import { Quorum } from "./Quorum" import mixpanel from "mixpanel-browser" import { Template } from "./Template" +import { DeploymentType } from "./DeploymentType" export const STEPS: StepInfo[] = [ - { title: "Select template", index: 0, path: "template" }, - { title: "Configure DAO settings", index: 1, path: "dao" }, - { title: "Configure Proposal & Voting", index: 2, path: "voting" }, - { title: "Adjust Quorum", index: 3, path: "quorum" }, - { title: "Review information", index: 4, path: "summary" } + { title: "DAO Template", index: 0, path: "template" }, + { title: "DAO Basics", index: 1, path: "dao" }, + { title: "Proposals & Voting", index: 2, path: "voting" }, + { title: "Quorum", index: 3, path: "quorum" }, + { title: "Review Information", index: 4, path: "summary" }, + { title: "Deployment Type", index: 5, path: "type" } ] -const urlToStepMap: Record = { +export const urlToStepMap: Record = { template: 0, dao: 1, voting: 2, quorum: 3, summary: 4, - review: 5 + type: 5, + review: 6 } const AnalyticsWrappedStep: React.FC<{ name: string; index: number }> = ({ name, index, children }) => { @@ -69,8 +72,13 @@ export const StepRouter: React.FC = () => { + + + + + - + @@ -99,3 +107,4 @@ export { Template } from "modules/creator/steps/Template" export { DaoSettings } from "modules/creator/steps/DaoSettings" export { Governance } from "modules/creator/steps/Governance" export { Review } from "modules/creator/steps/Review" +export { DeploymentType } from "modules/creator/steps/DeploymentType" diff --git a/src/modules/explorer/components/BatchBar.tsx b/src/modules/explorer/components/BatchBar.tsx index e6ca4519..ad03453a 100644 --- a/src/modules/explorer/components/BatchBar.tsx +++ b/src/modules/explorer/components/BatchBar.tsx @@ -45,13 +45,13 @@ const AddButton = styled(Paper)({ "minWidth": 31, "textAlign": "center", "padding": 0, - "background": "#383e43", - "color": "#fff", + "background": "inherit", + "color": "rgb(129, 254, 183)", "alignItems": "center", "display": "flex", "justifyContent": "center", "cursor": "pointer", - + "boxShadow": "none", "&:hover": { background: "#3c4349" } @@ -69,10 +69,10 @@ interface Props { export const BatchBar = ({ isBatch, handleIsBatchChange, onClickAdd, items, activeItem, setActiveItem }: Props) => { return ( - + - + Batch Transfer? @@ -90,13 +90,17 @@ export const BatchBar = ({ isBatch, handleIsBatchChange, onClickAdd, items, acti item key={index} onClick={() => setActiveItem(index)} - style={Number(index + 1) === activeItem ? { background: "#81FEB7" } : { background: "#3c4349" }} + style={Number(index + 1) === activeItem ? { background: "#81FEB7" } : { background: "inherit" }} > - #{index + 1} + {index + 1} ) @@ -105,6 +109,6 @@ export const BatchBar = ({ isBatch, handleIsBatchChange, onClickAdd, items, acti + ) : null} - + ) } diff --git a/src/modules/explorer/components/ConfigProposalForm.tsx b/src/modules/explorer/components/ConfigProposalForm.tsx index cedc6b7d..28436398 100644 --- a/src/modules/explorer/components/ConfigProposalForm.tsx +++ b/src/modules/explorer/components/ConfigProposalForm.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/display-name */ -import { Grid, Typography, TextField } from "@material-ui/core" +import { Grid, Typography, TextField, styled } from "@material-ui/core" import React, { useCallback } from "react" import { useDAO } from "services/services/dao/hooks/useDAO" import { SendButton } from "./ProposalFormSendButton" @@ -8,6 +8,13 @@ import { useDAOID } from "../pages/DAO/router" import { ProposalFormInput } from "./ProposalFormInput" import { useProposeConfigChange } from "../../../services/contracts/baseDAO/hooks/useProposeConfigChange" import { ResponsiveDialog } from "./ResponsiveDialog" +import * as yup from "yup" +import { yupResolver } from "@hookform/resolvers/yup" + +const ErrorText = styled(Typography)({ + fontSize: 14, + color: "red" +}) type RecursivePartial = { [P in keyof T]?: RecursivePartial @@ -27,16 +34,24 @@ interface Props { defaultTab?: number } -// const validationSchema: Yup.SchemaOf = Yup.object({ -// frozen_extra_value: Yup.number().required("Required"), -// slash_scale_value: Yup.number().min(0, "Cannot be lesser than 0").max(100, "Cannot be greater than 100") -// }); +const validationSchema = yup.object({ + frozen_extra_value: yup.number().typeError("Amount must be a number"), + returnedPercentage: yup + .number() + .min(0, "Cannot be lesser than 0") + .max(100, "Cannot be greater than 100") + .typeError("Amount must be a number") +}) export const ConfigProposalForm: React.FC = ({ open, handleClose }) => { const daoId = useDAOID() const { data: dao } = useDAO(daoId) - const methods = useForm() + const methods = useForm({ resolver: yupResolver(validationSchema) }) + + const { + formState: { errors } + } = methods const { mutate } = useProposeConfigChange() @@ -64,69 +79,112 @@ export const ConfigProposalForm: React.FC = ({ open, handleClose }) => { handleClose() } }, - [dao, handleClose, methods, mutate] + [dao, mutate, methods, handleClose] ) return ( - + All fields are optional. Leave empty what you wish to leave unchanged - - + {/* + ( )} /> + */} + + + ( + + )} + /> + + + + Current:{" "} + + + {dao && dao?.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} + + - {/* */} - + ( - + )} /> + {errors.returnedPercentage?.message} + + + Current:{" "} + + + {dao && dao?.data.extra.returnedPercentage.toString()}% + + - - - Proposal Fee:{" "} - - - {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} - + + + + Proposal Fee:{" "} + + + {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} + + + + + Submit + + - - - Submit - diff --git a/src/modules/explorer/components/DelegationChangeProposalForm.tsx b/src/modules/explorer/components/DelegationChangeProposalForm.tsx index 45099290..1f4a2965 100644 --- a/src/modules/explorer/components/DelegationChangeProposalForm.tsx +++ b/src/modules/explorer/components/DelegationChangeProposalForm.tsx @@ -9,6 +9,15 @@ import { useDAOID } from "../pages/DAO/router" import { ProposalFormInput } from "./ProposalFormInput" import { ResponsiveDialog } from "./ResponsiveDialog" import { useProposeDelegationChange } from "services/contracts/baseDAO/hooks/useProposeDelegationChange" +import * as yup from "yup" +import { yupResolver } from "@hookform/resolvers/yup" +import { validateContractAddress, validateAddress } from "@taquito/utils" +import { useDelegate } from "services/contracts/baseDAO/hooks/useDelegate" + +const ErrorText = styled(Typography)({ + fontSize: 14, + color: "red" +}) type RecursivePartial = { [P in keyof T]?: RecursivePartial @@ -31,10 +40,24 @@ const Content = styled(Grid)({ padding: "10px 0" }) +const isInvalidKtOrTzAddress = (address: string | undefined) => { + if (address !== undefined) { + return validateContractAddress(address) !== 3 && validateAddress(address) !== 3 ? false : true + } + return false +} + +const validationSchema = yup.object({ + newDelegationAddress: yup + .string() + .test("is-valid-address", "Must be a valid address", value => isInvalidKtOrTzAddress(value)) +}) + export const DelegationChangeProposalForm: React.FC = ({ open, handleClose, defaultValues }) => { const daoId = useDAOID() const { data: dao } = useDAO(daoId) + const currentDelegate = useDelegate(dao && dao?.data.address ? dao?.data.address : "") const methods = useForm({ defaultValues: useMemo( () => ({ @@ -42,10 +65,14 @@ export const DelegationChangeProposalForm: React.FC = ({ open, handleClos ...defaultValues }), [defaultValues] - ) - // resolver: yupResolver(validationSchema as any), + ), + resolver: yupResolver(validationSchema) }) + const { + formState: { errors } + } = methods + const newDelegationAddress = methods.watch("newDelegationAddress") useEffect(() => { @@ -74,6 +101,19 @@ export const DelegationChangeProposalForm: React.FC = ({ open, handleClos title={"Change Delegate"} > + {dao && ( + + + Current Delegate:{" "} + + + {currentDelegate && currentDelegate.data && currentDelegate.data.address + ? currentDelegate.data.address + : "-"} + + + )} + = ({ open, handleClos )} /> + {errors.newDelegationAddress?.message} - - - Proposal Fee:{" "} - - - {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} - - + + + + Proposal Fee:{" "} + + + {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} + + - - Submit - + + + Submit + + + diff --git a/src/modules/explorer/components/GuardianChangeProposalForm.tsx b/src/modules/explorer/components/GuardianChangeProposalForm.tsx index 86cb69f0..10f092c2 100644 --- a/src/modules/explorer/components/GuardianChangeProposalForm.tsx +++ b/src/modules/explorer/components/GuardianChangeProposalForm.tsx @@ -8,6 +8,14 @@ import { useDAOID } from "../pages/DAO/router" import { ProposalFormInput } from "./ProposalFormInput" import { useProposeGuardianChange } from "../../../services/contracts/baseDAO/hooks/useProposeGuardianChange" import { ResponsiveDialog } from "./ResponsiveDialog" +import * as yup from "yup" +import { yupResolver } from "@hookform/resolvers/yup" +import { validateContractAddress, validateAddress } from "@taquito/utils" + +const ErrorText = styled(Typography)({ + fontSize: 14, + color: "red" +}) type RecursivePartial = { [P in keyof T]?: RecursivePartial @@ -28,6 +36,19 @@ interface Props { const Content = styled(Grid)({}) +const isInvalidKtOrTzAddress = (address: string | undefined) => { + if (address !== undefined) { + return validateContractAddress(address) !== 3 && validateAddress(address) !== 3 ? false : true + } + return false +} + +const validationSchema = yup.object({ + newGuardianAddress: yup + .string() + .test("is-valid-address", "Must be a valid address", value => isInvalidKtOrTzAddress(value)) +}) + export const GuardianChangeProposalForm: React.FC = ({ open, handleClose, defaultValues }) => { const daoId = useDAOID() const { data: dao } = useDAO(daoId) @@ -39,10 +60,14 @@ export const GuardianChangeProposalForm: React.FC = ({ open, handleClose, ...defaultValues }), [defaultValues] - ) - // resolver: yupResolver(validationSchema as any), + ), + resolver: yupResolver(validationSchema) }) + const { + formState: { errors } + } = methods + const newGuardianAddress = methods.watch("newGuardianAddress") useEffect(() => { @@ -68,17 +93,35 @@ export const GuardianChangeProposalForm: React.FC = ({ open, handleClose, onClose={handleClose} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" - title={"Update Guardian"} + title={"Change Guardian"} > {dao && ( Current Guardian:{" "} - {dao.data.guardian} + + + {dao.data.guardian} )} + {/* + + ( + + )} + /> + + */} = ({ open, handleClose, )} /> + {errors.newGuardianAddress?.message} - - - Proposal Fee:{" "} - - - {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} - + + + + Proposal Fee:{" "} + + + {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} + + + + + Submit + + - - - Submit - diff --git a/src/modules/explorer/components/NewTreasuryProposalDialog.tsx b/src/modules/explorer/components/NewTreasuryProposalDialog.tsx index a707f90c..fb06bf50 100644 --- a/src/modules/explorer/components/NewTreasuryProposalDialog.tsx +++ b/src/modules/explorer/components/NewTreasuryProposalDialog.tsx @@ -29,14 +29,14 @@ export type Asset = Token | { symbol: "XTZ" } const AmountText = styled(Typography)(({ theme }) => ({ color: theme.palette.secondary.main, - fontSize: 14, + fontSize: 16, lineHeight: "146.3%", - marginRight: 10 + marginRight: 10, + fontWeight: 300 })) const DAOBalanceText = styled(Typography)({ color: "#ffff", - fontSize: 14, lineHeight: "100%", marginRight: 10 }) @@ -201,7 +201,7 @@ export const NewTreasuryProposalDialog: React.FC<{ open: boolean }> = ({ open }) }, [index, setValue, max, currentAssetBalance, currentTransfer, ledger]) return ( - + = ({ open }) {"Must be greater than zero"} ) : null} - - - DAO Balance + + + DAO Balance: - + {daoAssets ? ( {currentAssetBalance !== undefined && diff --git a/src/modules/explorer/components/ProposalForm.tsx b/src/modules/explorer/components/ProposalForm.tsx index 3d86bbb3..a4e75112 100644 --- a/src/modules/explorer/components/ProposalForm.tsx +++ b/src/modules/explorer/components/ProposalForm.tsx @@ -92,7 +92,8 @@ const enabledForms: Record< } const Content = styled(Grid)({ - padding: "0 54px" + padding: "0 54px", + paddingBottom: 24 }) const SwapText = styled(Typography)({ @@ -193,7 +194,6 @@ export const ProposalFormContainer: React.FC = ({ if (state === 0) { handleChangeTab?.(1) } else if (state === 1) { - console.log() handleChangeTab?.(0) } else { return @@ -221,7 +221,7 @@ export const ProposalFormContainer: React.FC = ({ ))} - + = ({ /> - - - Proposal Fee:{" "} - - - {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} - - + + + + Proposal Fee:{" "} + + + {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""} + + - - Submit - + + + Submit + + + )} diff --git a/src/modules/explorer/components/ProposalFormInput.tsx b/src/modules/explorer/components/ProposalFormInput.tsx index e6aa4e6c..099bad43 100644 --- a/src/modules/explorer/components/ProposalFormInput.tsx +++ b/src/modules/explorer/components/ProposalFormInput.tsx @@ -3,7 +3,7 @@ import Editor from "react-simple-code-editor" import { Grid, styled, Typography } from "@material-ui/core" const StyledBody = styled(Grid)(({ theme }) => ({ - "borderRadius": 4, + "borderRadius": 8, "background": theme.palette.primary.main, "padding": "0 20px", "minHeight": 54, diff --git a/src/modules/explorer/components/ProposalFormSendButton.tsx b/src/modules/explorer/components/ProposalFormSendButton.tsx index 03a59806..e174cc3e 100644 --- a/src/modules/explorer/components/ProposalFormSendButton.tsx +++ b/src/modules/explorer/components/ProposalFormSendButton.tsx @@ -10,8 +10,9 @@ const SendContainer = styled(Grid)(({ theme }) => ({ })) const StyledSendButton = styled(MainButton)(({ theme }) => ({ - width: 101, - color: "#1C1F23" + width: 96, + color: "#1C1F23", + height: 40 })) export const SendButton: React.FC = ({ children, ...props }) => { diff --git a/src/modules/explorer/components/ResponsiveDialog.tsx b/src/modules/explorer/components/ResponsiveDialog.tsx index a7138b4d..eaddf628 100644 --- a/src/modules/explorer/components/ResponsiveDialog.tsx +++ b/src/modules/explorer/components/ResponsiveDialog.tsx @@ -8,12 +8,15 @@ const Content = styled(Grid)({ padding: "41px 46px" }) -const TitleText = styled(Typography)({ +const TitleText = styled(Typography)(({ theme }) => ({ color: "#ffff", fontWeight: 550, lineHeight: ".80", - textTransform: "capitalize" -}) + textTransform: "capitalize", + [theme.breakpoints.down("sm")]: { + fontSize: 18 + } +})) const CustomDialog = styled(Dialog)({ "& .MuiDialog-paperWidthMd": { @@ -48,8 +51,13 @@ export const ResponsiveDialog: React.FC<{ return isSmall ? ( - - {onGoBack ? : null} + + {onGoBack !== undefined ? ( + + {" "} + + + ) : null} {title} @@ -57,14 +65,21 @@ export const ResponsiveDialog: React.FC<{ - {children} + + {children} + ) : ( - {onGoBack ? : null} + {onGoBack !== undefined ? ( + + {" "} + + + ) : null}{" "} {title} diff --git a/src/modules/explorer/pages/Config/components/DAOInfoTable.tsx b/src/modules/explorer/pages/Config/components/DAOInfoTable.tsx index c2ae6ce2..d5794866 100644 --- a/src/modules/explorer/pages/Config/components/DAOInfoTable.tsx +++ b/src/modules/explorer/pages/Config/components/DAOInfoTable.tsx @@ -1,109 +1,225 @@ /* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ -import { styled, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from "@material-ui/core" +import { + Grid, + styled, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, + useMediaQuery, + useTheme +} from "@material-ui/core" import React from "react" import { useDAO } from "services/services/dao/hooks/useDAO" import BigNumber from "bignumber.js" import { useDAOID } from "../../DAO/router" +import { useDelegate } from "services/contracts/baseDAO/hooks/useDelegate" +import { CopyButton } from "modules/common/CopyButton" +import { CopyAddress } from "modules/common/CopyAddress" -const RowValue = styled(Typography)({ +const RowValue = styled(Typography)(({ theme }) => ({ fontWeight: 300, - fontSize: 18 -}) + fontSize: 18, + [theme.breakpoints.down("sm")]: { + fontSize: 16 + } +})) -const TableTitle = styled(Typography)({ +const TableTitle = styled(Typography)(({ theme }) => ({ fontWeight: 500, - fontSize: 18 -}) + fontSize: 18, + [theme.breakpoints.down("sm")]: { + fontSize: 16 + } +})) const CustomTableContainer = styled(TableContainer)(({ theme }) => ({ + width: "inherit", [theme.breakpoints.down("sm")]: {} })) +const CustomTableCell = styled(TableCell)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + paddingBottom: 0, + paddingLeft: "16px !important", + textAlign: "end" + } +})) + +const CustomTableCellTitle = styled(TableCell)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + paddingLeft: "16px !important" + } +})) + +const CustomTableCellValue = styled(TableCell)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + paddingTop: 0, + paddingRight: "16px !important", + textAlign: "end", + paddingBottom: 0 + } +})) + export const DaoInfoTables: React.FC = () => { const daoId = useDAOID() const { data: dao } = useDAO(daoId) + const theme = useTheme() + const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) + const currentDelegate = useDelegate(dao && dao?.data.address ? dao?.data.address : "") return ( <> + + + + {dao ? ( + <> + + + + Contract Address (Treasury) + + + + + {isMobileSmall ? ( + + ) : ( + <> + + {dao.data.address} + + + + )} + + + + + + + Current Delegate + + + + + {currentDelegate && currentDelegate.data && currentDelegate.data.address ? ( + isMobileSmall ? ( + + ) : ( + + {currentDelegate.data.address} + + + ) + ) : ( + "-" + )} + + + + + ) : null} + +
+
- + Proposal & Voting Settings - + {dao ? ( <> - - Voting Period Duration - - + + + Voting Period Duration + + + {dao.data.period} blocks - + - - Flush Delay Duration - - + + + Flush Delay Duration + + + {new BigNumber(dao.data.proposal_flush_level).toNumber() - 2 * new BigNumber(dao.data.period).toNumber()}{" "} blocks - + - - Proposal Blocks to Expire - - + + + Proposal Blocks to Expire + + + {new BigNumber(dao.data.proposal_expired_level).toNumber() - new BigNumber(dao.data.proposal_flush_level).toNumber()}{" "} blocks - + - - Stake Required to Propose - - + + + Stake Required to Propose + + + {new BigNumber(dao.data.extra.frozen_extra_value).toNumber()} locked {dao.data.token.symbol} - + - - Stake Returned if Rejected - - + + + Stake Returned if Rejected + + + {dao.data.extra.returnedPercentage}% of locked {dao.data.token.symbol} - + - - Transfer Maximum XTZ Amount - - + + + Transfer Maximum XTZ Amount + + + {new BigNumber(dao.data.extra.max_xtz_amount).div(10 ** 6).toNumber()} XTZ - + - - Transfer Minimum XTZ Amount - - + + + Transfer Minimum XTZ Amount + + + {new BigNumber(dao.data.extra.min_xtz_amount).div(10 ** 6).toNumber()} XTZ - + ) : null} @@ -115,55 +231,65 @@ export const DaoInfoTables: React.FC = () => {
- + Quorum Settings - + {dao ? ( <> - - Quorum Threshold - - + + + Quorum Threshold + + + {dao.data.quorum_threshold.toNumber()} {dao.data.token.symbol} - + - - Quorum Min Amount - - + + + Quorum Min Amount + + + {new BigNumber(dao.data.min_quorum_threshold).div(10000).toNumber()}% - + - - Quorum Max Amount - - + + + Quorum Max Amount + + + {new BigNumber(dao.data.max_quorum_threshold).div(10000).toNumber()}% - + - - Quorum Change - - + + + Quorum Change + + + {new BigNumber(dao.data.quorum_change).div(10000).toNumber()}% - + - - Quorum Max Change - - + + + Quorum Max Change + + + {new BigNumber(dao.data.max_quorum_change).div(10000).toNumber()}% - + ) : null} diff --git a/src/modules/explorer/pages/DAO/components/Settings.tsx b/src/modules/explorer/pages/DAO/components/Settings.tsx index 0a9d4025..32004f20 100644 --- a/src/modules/explorer/pages/DAO/components/Settings.tsx +++ b/src/modules/explorer/pages/DAO/components/Settings.tsx @@ -1,53 +1,14 @@ /* eslint-disable react/display-name */ -import { Grid, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core" -import React, { useState } from "react" -import { useDAO } from "services/services/dao/hooks/useDAO" -import { useDAOID } from "../router" +import React from "react" import { ResponsiveDialog } from "modules/explorer/components/ResponsiveDialog" import { DaoInfoTables } from "../../Config/components/DAOInfoTable" -const OptionContainer = styled(Grid)(({ theme }) => ({ - "minHeight": 80, - "background": theme.palette.primary.main, - "borderRadius": 8, - "padding": "35px 42px", - "marginBottom": 16, - "cursor": "pointer", - "height": 110, - "&:hover": { - background: theme.palette.secondary.dark, - scale: 1.01, - transition: "0.15s ease-in" - } -})) - -const ActionText = styled(Typography)(({ theme }) => ({ - fontWeight: 400, - fontSize: 20, - marginBottom: 8 -})) - -const ActionDescriptionText = styled(Typography)(({ theme }) => ({ - fontWeight: 300, - fontSize: 16 -})) - -interface Action { - id: any - name: string - description: string - isLambda: boolean -} - interface Props { open: boolean handleClose: () => void } export const DaoSettingModal: React.FC = ({ open, handleClose }) => { - const theme = useTheme() - const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) - return ( <> diff --git a/src/modules/explorer/pages/DAOList/index.tsx b/src/modules/explorer/pages/DAOList/index.tsx index 7c97c0e7..c8666d81 100644 --- a/src/modules/explorer/pages/DAOList/index.tsx +++ b/src/modules/explorer/pages/DAOList/index.tsx @@ -115,11 +115,6 @@ const ExternalLink = styled(Typography)({ } }) -const ExternalLinkIcon = styled(LaunchOutlined)({ - fontSize: 14, - marginBottom: 2 -}) - export const DAOList: React.FC = () => { const { network, account, tezos } = useTezos() const { data: daos, isLoading } = useAllDAOs(network) diff --git a/src/modules/explorer/pages/Proposals/index.tsx b/src/modules/explorer/pages/Proposals/index.tsx index f8a2ee0c..bbdb671b 100644 --- a/src/modules/explorer/pages/Proposals/index.tsx +++ b/src/modules/explorer/pages/Proposals/index.tsx @@ -192,10 +192,6 @@ export const Proposals: React.FC = () => { setOpenDialog(false) } - useEffect(() => { - console.log("se actualizó") - }, [openDialog]) - const onFlush = useCallback(async () => { if (executableProposals && expiredProposals && executableProposals.length && data) { mutate({ diff --git a/src/services/config/constants.ts b/src/services/config/constants.ts index 725b4a5e..562c6290 100644 --- a/src/services/config/constants.ts +++ b/src/services/config/constants.ts @@ -15,7 +15,8 @@ export enum EnvKey { REACT_APP_V2_URL = "REACT_APP_V2_URL", REACT_APP_LITE_API_URL = "REACT_APP_LITE_API_URL", REACT_APP_API_URL = "REACT_APP_API_URL", - REACT_APP_BASE_URL = "REACT_APP_BASE_URL" + REACT_APP_BASE_URL = "REACT_APP_BASE_URL", + REACT_APP_DAO_DEPLOYER_API = "REACT_APP_DAO_DEPLOYER_API" } export enum FeatureFlag { diff --git a/src/services/contracts/baseDAO/hooks/useOriginate.ts b/src/services/contracts/baseDAO/hooks/useOriginate.ts index 0e01e961..fdf01010 100644 --- a/src/services/contracts/baseDAO/hooks/useOriginate.ts +++ b/src/services/contracts/baseDAO/hooks/useOriginate.ts @@ -6,7 +6,7 @@ import { useMutation, useQueryClient } from "react-query" import { deployMetadataCarrier } from "services/contracts/metadataCarrier/deploy" import { initTezosInstance, useTezos } from "services/beacon/hooks/useTezos" -import { BaseDAO } from ".." +import { BaseDAO, replacer } from ".." import { getDAO } from "services/services/dao/services" import mixpanel from "mixpanel-browser" import { InMemorySigner } from "@taquito/signer" @@ -14,6 +14,7 @@ import { ALICE_PRIV_KEY } from "services/beacon" import { getSignature } from "services/lite/utils" import { saveLiteCommunity } from "services/services/lite/lite-services" import { Community } from "models/Community" +import { EnvKey, getEnv } from "services/config" const INITIAL_STATES = [ { @@ -28,6 +29,14 @@ const INITIAL_STATES = [ activeText: "", completedText: "" }, + { + activeText: "", + completedText: "" + }, + { + activeText: "", + completedText: "" + }, { activeText: "", completedText: "" @@ -69,108 +78,154 @@ export const useOriginate = (template: DAOTemplate) => { const { tezos, connect, network, account, wallet } = useTezos() const result = useMutation, Error, OriginateParams>( - async ({ metadataParams, params }) => { + async ({ metadataParams, params, deploymentMethod }) => { const updatedStates = INITIAL_STATES - updatedStates[0] = { - activeText: "Deploying Metadata Carrier Contract", - completedText: "" - } + let contract - setActiveState(0) - setStates(updatedStates) + if (deploymentMethod === "managed") { + const deployParams: any = { + params: { ...params }, + metadataParams: { ...metadataParams } + } - let newTezos: TezosToolkit = tezos + updatedStates[0] = { + activeText: `Deploying ${template} DAO Contract`, + completedText: "" + } - if (network !== "mainnet") { - newTezos = initTezosInstance(network) - const signer = await InMemorySigner.fromSecretKey(ALICE_PRIV_KEY) - newTezos.setProvider({ signer }) + setActiveState(0) + setStates(updatedStates) - params.orgSettings.administrator = await newTezos.wallet.pkh() - } + const resp = await fetch(`${getEnv(EnvKey.REACT_APP_DAO_DEPLOYER_API)}/deploy`, { + method: "POST", + body: JSON.stringify({ deployParams: deployParams }, replacer), + headers: { "Content-Type": "application/json" } + }) - mixpanel.track("Started DAO origination", { - contract: "MetadataCarrier", - daoName: params.orgSettings.name, - daoType: params.template - }) + const data = await resp.json() + console.log(data) + const address = data.address - const metadata = await deployMetadataCarrier({ - ...metadataParams, - tezos: newTezos, - connect - }) + contract = await tezos.wallet.at(address) - if (!metadata) { - throw new Error(`Could not deploy ${template}DAO because MetadataCarrier contract deployment failed`) - } + mixpanel.track("Started DAO origination", { + contract: "BaseDAO", + daoName: params.orgSettings.name + }) - updatedStates[0] = { - ...updatedStates[0], - completedText: `Deployed Metadata Carrier with address "${metadata.deployAddress}" and key "${metadata.keyName}"` - } + if (!contract) { + throw new Error(`Error deploying ${template}DAO`) + } - updatedStates[1] = { - activeText: `Deploying ${template} DAO Contract`, - completedText: "" - } + updatedStates[1] = { + ...updatedStates[1], + completedText: `Deployed ${template} DAO contract with address "${contract.address}"` + } - setActiveState(1) - setStates(updatedStates) + setActiveState(1) + setStates(updatedStates) - mixpanel.track("Started DAO origination", { - contract: "BaseDAO", - daoName: params.orgSettings.name - }) + updatedStates[2] = { + activeText: `Waiting for DAO to be indexed`, + completedText: "" + } - const contract = await BaseDAO.baseDeploy(template, { - tezos: newTezos, - metadata, - params, - network - }) + setActiveState(2) + setStates(updatedStates) + } else { + updatedStates[0] = { + activeText: "Deploying Metadata Carrier Contract", + completedText: "" + } - if (!contract) { - throw new Error(`Error deploying ${template}DAO`) - } + setActiveState(0) + setStates(updatedStates) - updatedStates[1] = { - ...updatedStates[1], - completedText: `Deployed ${template} DAO contract with address "${contract.address}"` - } + mixpanel.track("Started DAO origination", { + contract: "MetadataCarrier", + daoName: params.orgSettings.name, + daoType: params.template + }) - updatedStates[2] = { - activeText: `Waiting for DAO ownership to be transferred`, - completedText: "" - } + const metadata = await deployMetadataCarrier({ + ...metadataParams, + tezos, + connect + }) - setActiveState(2) - setStates(updatedStates) + if (!metadata) { + throw new Error(`Could not deploy ${template}DAO because MetadataCarrier contract deployment failed`) + } - const tx = await BaseDAO.transfer_ownership(contract.address, contract.address, newTezos) + updatedStates[0] = { + ...updatedStates[0], + completedText: `Deployed Metadata Carrier with address "${metadata.deployAddress}" and key "${metadata.keyName}"` + } - if (!tx) { - throw new Error(`Error transferring ownership of ${template}DAO to itself`) - } + updatedStates[1] = { + activeText: `Deploying ${template} DAO Contract`, + completedText: "" + } - updatedStates[2] = { - ...updatedStates[2], - completedText: `Ownership of ${template} DAO transferred to the DAO "${contract.address}"` - } + setActiveState(1) + setStates(updatedStates) - updatedStates[3] = { - activeText: `Waiting for DAO to be indexed`, - completedText: "" - } + mixpanel.track("Started DAO origination", { + contract: "BaseDAO", + daoName: params.orgSettings.name + }) - setActiveState(3) - setStates(updatedStates) + contract = await BaseDAO.baseDeploy(template, { + tezos, + metadata, + params, + network + }) - mixpanel.track("Completed DAO creation", { - daoName: params.orgSettings.name, - daoType: params.template - }) + if (!contract) { + throw new Error(`Error deploying ${template}DAO`) + } + + updatedStates[1] = { + ...updatedStates[1], + completedText: `Deployed ${template} DAO contract with address "${contract.address}"` + } + + updatedStates[2] = { + activeText: `Waiting for DAO ownership to be transferred`, + completedText: "" + } + + setActiveState(2) + setStates(updatedStates) + + const tx = await BaseDAO.transfer_ownership(contract.address, contract.address, tezos) + + if (!tx) { + throw new Error(`Error transferring ownership of ${template}DAO to itself`) + } + + updatedStates[2] = { + ...updatedStates[2], + completedText: `Ownership of ${template} DAO transferred to the DAO "${contract.address}"` + } + + updatedStates[3] = { + activeText: `Waiting for DAO to be indexed`, + completedText: "" + } + + setActiveState(3) + setStates(updatedStates) + + mixpanel.track("Completed DAO creation", { + daoName: params.orgSettings.name, + daoType: params.template + }) + } + + console.log("This is the contract deployed", contract) mixpanel.track("Waiting for DAO indexation", { daoName: params.orgSettings.name, @@ -179,11 +234,9 @@ export const useOriginate = (template: DAOTemplate) => { const indexed = await waitForIndexation(contract.address) - updatedStates[3] = { - ...updatedStates[3], - completedText: indexed - ? `Deployed ${metadataParams.metadata.unfrozenToken.name} successfully` - : `Deployed ${metadataParams.metadata.unfrozenToken.name} successfully, but metadata has not been indexed yet. This usually takes a few minutes, your DAO page may not be available yet.` + updatedStates[4] = { + activeText: `Deployling Lite DAO`, + completedText: "" } setActiveState(4) @@ -208,7 +261,25 @@ export const useOriginate = (template: DAOTemplate) => { const { signature, payloadBytes } = await getSignature(account, wallet, JSON.stringify(values)) const publicKey = (await wallet?.client.getActiveAccount())?.publicKey - const resp = await saveLiteCommunity(signature, publicKey, payloadBytes) + await saveLiteCommunity(signature, publicKey, payloadBytes) + + updatedStates[4] = { + activeText: "", + completedText: "Successfully deployed Lite DAO" + } + + setActiveState(5) + setStates(updatedStates) + + updatedStates[5] = { + ...updatedStates[5], + completedText: indexed + ? `Deployed ${metadataParams.metadata.unfrozenToken.name} successfully` + : `Deployed ${metadataParams.metadata.unfrozenToken.name} successfully, but metadata has not been indexed yet. This usually takes a few minutes, your DAO page may not be available yet.` + } + + setActiveState(6) + setStates(updatedStates) } mixpanel.track("Completed DAO indexation", { diff --git a/src/services/contracts/baseDAO/types.ts b/src/services/contracts/baseDAO/types.ts index 95b426a5..527caa16 100644 --- a/src/services/contracts/baseDAO/types.ts +++ b/src/services/contracts/baseDAO/types.ts @@ -2,7 +2,7 @@ import { ContractAbstraction, TezosToolkit, Wallet } from "@taquito/taquito" import { MetadataCarrierDeploymentData, MetadataCarrierParameters } from "services/contracts/metadataCarrier/types" import { BigNumber } from "bignumber.js" -import { MigrationParams } from "modules/creator/state" +import { DeploymentMethod, MigrationParams } from "modules/creator/state" import { Token as TokenModel } from "models/Token" export type Contract = ContractAbstraction | undefined @@ -60,6 +60,7 @@ export interface ConfigProposalParams { export interface OriginateParams { metadataParams: MetadataCarrierParameters params: MigrationParams + deploymentMethod: DeploymentMethod } export interface VoteParams { diff --git a/src/services/contracts/baseDAO/utils.ts b/src/services/contracts/baseDAO/utils.ts index ec096355..ee93996d 100644 --- a/src/services/contracts/baseDAO/utils.ts +++ b/src/services/contracts/baseDAO/utils.ts @@ -61,3 +61,12 @@ export const calculateCycleInfo = (originationTime: string, votingPeriod: number export const unpackExtraNumValue = (bytes: string): BigNumber => { return new BigNumber((unpackDataBytes({ bytes }) as { int: string }).int) } + +export const replacer = (name: any, val: any) => { + // convert Number to string + if (val && val.constructor === BigNumber) { + return val.toString() + } else { + return val // return as is + } +} diff --git a/src/services/contracts/token/assets/MultiAsset.json b/src/services/contracts/token/assets/MultiAsset.json deleted file mode 100644 index e1f8b94a..00000000 --- a/src/services/contracts/token/assets/MultiAsset.json +++ /dev/null @@ -1,4592 +0,0 @@ -[ - { - "prim": "storage", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%admin" - ] - }, - { - "prim": "bool", - "annots": [ - "%paused" - ] - } - ] - }, - { - "prim": "option", - "args": [ - { - "prim": "address" - } - ], - "annots": [ - "%pending_admin" - ] - } - ], - "annots": [ - "%admin" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ], - "annots": [ - "%ledger" - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - } - ] - }, - { - "prim": "unit" - } - ], - "annots": [ - "%operators" - ] - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "big_map", - "args": [ - { - "prim": "nat" - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat", - "annots": [ - "%token_id" - ] - }, - { - "prim": "map", - "args": [ - { - "prim": "string" - }, - { - "prim": "bytes" - } - ], - "annots": [ - "%token_info" - ] - } - ] - } - ], - "annots": [ - "%token_metadata" - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "nat" - }, - { - "prim": "nat" - } - ], - "annots": [ - "%token_total_supply" - ] - } - ] - } - ], - "annots": [ - "%assets" - ] - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "string" - }, - { - "prim": "bytes" - } - ], - "annots": [ - "%metadata" - ] - } - ] - } - ] - }, - { - "prim": "parameter", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "unit", - "annots": [ - "%confirm_admin" - ] - }, - { - "prim": "bool", - "annots": [ - "%pause" - ] - } - ] - }, - { - "prim": "address", - "annots": [ - "%set_admin" - ] - } - ], - "annots": [ - "%admin" - ] - }, - { - "prim": "or", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "nat", - "annots": [ - "%token_id" - ] - } - ] - } - ], - "annots": [ - "%requests" - ] - }, - { - "prim": "contract", - "args": [ - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "nat", - "annots": [ - "%token_id" - ] - } - ], - "annots": [ - "%request" - ] - }, - { - "prim": "nat", - "annots": [ - "%balance" - ] - } - ] - } - ] - } - ], - "annots": [ - "%callback" - ] - } - ], - "annots": [ - "%balance_of" - ] - }, - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%from_" - ] - }, - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%to_" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat", - "annots": [ - "%token_id" - ] - }, - { - "prim": "nat", - "annots": [ - "%amount" - ] - } - ] - } - ] - } - ], - "annots": [ - "%txs" - ] - } - ] - } - ], - "annots": [ - "%transfer" - ] - } - ] - }, - { - "prim": "list", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%operator" - ] - }, - { - "prim": "nat", - "annots": [ - "%token_id" - ] - } - ] - } - ], - "annots": [ - "%add_operator" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%operator" - ] - }, - { - "prim": "nat", - "annots": [ - "%token_id" - ] - } - ] - } - ], - "annots": [ - "%remove_operator" - ] - } - ] - } - ], - "annots": [ - "%update_operators" - ] - } - ], - "annots": [ - "%assets" - ] - } - ] - }, - { - "prim": "or", - "args": [ - { - "prim": "or", - "args": [ - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat", - "annots": [ - "%token_id" - ] - }, - { - "prim": "nat", - "annots": [ - "%amount" - ] - } - ] - } - ] - } - ], - "annots": [ - "%burn_tokens" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat", - "annots": [ - "%token_id" - ] - }, - { - "prim": "map", - "args": [ - { - "prim": "string" - }, - { - "prim": "bytes" - } - ], - "annots": [ - "%token_info" - ] - } - ], - "annots": [ - "%create_token" - ] - } - ] - }, - { - "prim": "list", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address", - "annots": [ - "%owner" - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat", - "annots": [ - "%token_id" - ] - }, - { - "prim": "nat", - "annots": [ - "%amount" - ] - } - ] - } - ] - } - ], - "annots": [ - "%mint_tokens" - ] - } - ], - "annots": [ - "%tokens" - ] - } - ] - } - ] - }, - { - "prim": "code", - "args": [ - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "FA2_TOKEN_UNDEFINED" - } - ] - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "FA2_INSUFFICIENT_BALANCE" - } - ] - }, - { - "prim": "LAMBDA", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - } - ] - }, - { - "prim": "nat" - }, - [ - { - "prim": "UNPAIR" - }, - { - "prim": "GET" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "nat" - }, - { - "int": "0" - } - ] - } - ], - [] - ] - } - ] - ] - }, - { - "prim": "DUP" - }, - { - "prim": "LAMBDA", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "lambda", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - } - ] - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat" - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - } - ] - } - ] - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - }, - [ - { - "prim": "UNPAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "ADD" - }, - { - "prim": "DUP" - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "nat" - }, - { - "int": "0" - } - ] - }, - { - "prim": "COMPARE" - }, - { - "prim": "EQ" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "DROP" - }, - { - "prim": "NONE", - "args": [ - { - "prim": "nat" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "UPDATE" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SOME" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "UPDATE" - } - ] - ] - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "APPLY" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "LAMBDA", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "lambda", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - } - ] - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "string" - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat" - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - } - ] - } - ] - } - ] - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - }, - { - "prim": "nat" - } - ] - }, - [ - { - "prim": "UNPAIR" - }, - { - "prim": "UNPAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SUB" - }, - { - "prim": "ISNAT" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "DROP", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DUP" - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "nat" - }, - { - "int": "0" - } - ] - }, - { - "prim": "COMPARE" - }, - { - "prim": "EQ" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "DROP" - }, - { - "prim": "NONE", - "args": [ - { - "prim": "nat" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "UPDATE" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SOME" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "UPDATE" - } - ] - ] - } - ] - ] - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "APPLY" - }, - { - "prim": "LAMBDA", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "bool" - } - ] - }, - { - "prim": "option", - "args": [ - { - "prim": "address" - } - ] - } - ] - }, - { - "prim": "unit" - }, - [ - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "SENDER" - }, - { - "prim": "COMPARE" - }, - { - "prim": "NEQ" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "NOT_AN_ADMIN" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [] - ] - }, - { - "prim": "UNIT" - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "6" - } - ] - }, - { - "prim": "UNPAIR" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "DIG", - "args": [ - { - "int": "6" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "NO_PENDING_ADMIN" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [ - { - "prim": "SENDER" - }, - { - "prim": "COMPARE" - }, - { - "prim": "EQ" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "NONE", - "args": [ - { - "prim": "address" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SENDER" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "NOT_A_PENDING_ADMIN" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - } - ] - ] - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DROP" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - } - ], - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DROP" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "SOME" - }, - { - "prim": "SWAP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - }, - { - "prim": "UNPAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "PAUSED" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "MAP", - "args": [ - [ - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "MEM" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "7" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "DROP" - }, - { - "prim": "DUP", - "args": [ - { - "int": "6" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "CDR" - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "mutez" - }, - { - "int": "0" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "TRANSFER_TOKENS" - }, - { - "prim": "SWAP" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CONS" - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "LAMBDA", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "address" - } - ] - }, - { - "prim": "pair", - "args": [ - { - "prim": "nat" - }, - { - "prim": "big_map", - "args": [ - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "pair", - "args": [ - { - "prim": "address" - }, - { - "prim": "nat" - } - ] - } - ] - }, - { - "prim": "unit" - } - ] - } - ] - } - ] - }, - { - "prim": "unit" - }, - [ - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "DUP" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "COMPARE" - }, - { - "prim": "EQ" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "DROP", - "args": [ - { - "int": "3" - } - ] - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "MEM" - }, - { - "prim": "IF", - "args": [ - [], - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "FA2_NOT_OPERATOR" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - } - ] - ] - }, - { - "prim": "UNIT" - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "MEM" - }, - { - "prim": "IF", - "args": [ - [ - { - "prim": "DUP", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SENDER" - }, - { - "prim": "DUP", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "6" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "8" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "8" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - } - ], - [ - { - "prim": "DROP", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "8" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DROP" - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - }, - { - "prim": "SENDER" - }, - { - "prim": "SWAP" - }, - { - "prim": "UNPAIR" - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "IF_LEFT", - "args": [ - [], - [] - ] - }, - { - "prim": "CAR" - }, - { - "prim": "COMPARE" - }, - { - "prim": "EQ" - }, - { - "prim": "IF", - "args": [ - [], - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "FA2_NOT_OWNER" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "option", - "args": [ - { - "prim": "unit" - } - ] - }, - { - "prim": "Some", - "args": [ - { - "prim": "Unit" - } - ] - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "UPDATE" - } - ], - [ - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NONE", - "args": [ - { - "prim": "unit" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "UPDATE" - } - ] - ] - } - ] - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - }, - { - "prim": "UNPAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - } - ] - ] - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "IF_LEFT", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "DROP", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SUB" - }, - { - "prim": "ISNAT" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "DUP", - "args": [ - { - "int": "6" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SOME" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "UPDATE" - } - ] - ] - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DUP" - }, - { - "prim": "CAR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SOME" - }, - { - "prim": "SWAP" - }, - { - "prim": "UPDATE" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "PUSH", - "args": [ - { - "prim": "option", - "args": [ - { - "prim": "nat" - } - ] - }, - { - "prim": "Some", - "args": [ - { - "int": "0" - } - ] - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "UPDATE" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - } - ], - [ - { - "prim": "PUSH", - "args": [ - { - "prim": "string" - }, - { - "string": "FA2_DUP_TOKEN_ID" - } - ] - }, - { - "prim": "FAILWITH" - } - ] - ] - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - } - ], - [ - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "5" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "EXEC" - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "ITER", - "args": [ - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "GET" - }, - { - "prim": "IF_NONE", - "args": [ - [ - { - "prim": "DROP", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "FAILWITH" - } - ], - [ - { - "prim": "SWAP" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "ADD" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "SWAP" - }, - { - "prim": "SOME" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "UPDATE" - } - ] - ] - } - ] - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "4" - } - ] - }, - { - "prim": "DROP" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DUP" - }, - { - "prim": "CDR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "DUP" - }, - { - "prim": "DUG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "GET", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "NIL", - "args": [ - { - "prim": "operation" - } - ] - }, - { - "prim": "PAIR" - } - ] - ] - }, - { - "prim": "UNPAIR" - }, - { - "prim": "DUP", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CDR" - }, - { - "prim": "DIG", - "args": [ - { - "int": "2" - } - ] - }, - { - "prim": "DIG", - "args": [ - { - "int": "3" - } - ] - }, - { - "prim": "CAR" - }, - { - "prim": "CAR" - }, - { - "prim": "PAIR" - }, - { - "prim": "PAIR" - }, - { - "prim": "SWAP" - }, - { - "prim": "PAIR" - } - ] - ] - } - ] - ] - } -] \ No newline at end of file diff --git a/src/services/contracts/token/assets/fa2_single_asset_delegated.ts b/src/services/contracts/token/assets/fa2_single_asset_delegated.ts new file mode 100644 index 00000000..98f4d8f7 --- /dev/null +++ b/src/services/contracts/token/assets/fa2_single_asset_delegated.ts @@ -0,0 +1,938 @@ +export default `{ parameter + (or (or (or (or %admin (bool %pause) (address %set_admin)) + (or %assets + (or (pair %balance_of + (list %requests (pair (address %owner) (nat %token_id))) + (contract %callback + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))))) + (list %transfer + (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount)))))) + (list %update_operators + (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) + (pair %remove_operator (address %owner) (address %operator) (nat %token_id)))))) + (or (option %set_delegate address) (address %set_minter))) + (or %tokens + (list %burn_tokens (pair (address %owner) (nat %amount))) + (list %mint_tokens (pair (address %owner) (nat %amount))))) ; +storage + (pair (pair (pair %admin (address %admin) (bool %paused)) + (pair %assets + (pair (pair (big_map %delegates address address) (big_map %ledger address nat)) + (address %minter) + (big_map %operators (pair address address nat) unit)) + (pair (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (nat %total_supply)) + (big_map %voting_power_history + (pair address nat) + (pair (nat %amount) (nat %from_block))) + (big_map %voting_power_history_sizes address nat))) + (big_map %metadata string bytes)) ; +code { PUSH string "FA2_TOKEN_UNDEFINED" ; + PUSH string "FA2_INSUFFICIENT_BALANCE" ; + LAMBDA + int + nat + { ISNAT ; IF_NONE { PUSH string "NOT_A_NAT" ; FAILWITH } {} } ; + LAMBDA + (pair (lambda int nat) + (pair (pair address int) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat))) + (pair (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat)) + { UNPAIR ; + SWAP ; + UNPAIR ; + UNPAIR ; + DUP 3 ; + CDR ; + CDR ; + CDR ; + DUP 2 ; + GET ; + IF_NONE + { SWAP ; DIG 3 ; SWAP ; EXEC ; PUSH nat 0 } + { DUP 4 ; + CDR ; + CDR ; + CAR ; + PUSH int 1 ; + DUP 3 ; + SUB ; + DUP 7 ; + SWAP ; + EXEC ; + DUP 4 ; + PAIR ; + GET ; + IF_NONE { PUSH string "option is None" ; FAILWITH } {} ; + DIG 3 ; + DUP 2 ; + CAR ; + ADD ; + DUP 6 ; + SWAP ; + EXEC ; + LEVEL ; + DIG 2 ; + CDR ; + COMPARE ; + EQ ; + IF { PUSH int 1 ; DIG 2 ; SUB ; DIG 4 ; SWAP ; EXEC } + { DIG 4 ; DROP ; SWAP } } ; + LEVEL ; + DIG 2 ; + PAIR ; + DUP 4 ; + CDR ; + CDR ; + CDR ; + PUSH nat 1 ; + DUP 4 ; + ADD ; + SOME ; + DUP 5 ; + UPDATE ; + DUP 5 ; + CDR ; + CDR ; + CAR ; + PAIR ; + DUP 5 ; + CDR ; + CAR ; + PAIR ; + DUP 5 ; + CAR ; + PAIR ; + DUP ; + CDR ; + CDR ; + CDR ; + DIG 5 ; + CDR ; + CDR ; + CAR ; + DIG 3 ; + SOME ; + DIG 4 ; + DIG 5 ; + PAIR ; + UPDATE ; + PAIR ; + DUP 2 ; + CDR ; + CAR ; + PAIR ; + SWAP ; + CAR ; + PAIR } ; + DUP 2 ; + APPLY ; + SWAP ; + DROP ; + LAMBDA + (pair address (big_map address nat)) + nat + { UNPAIR ; GET ; IF_NONE { PUSH nat 0 } {} } ; + LAMBDA + (pair (pair (lambda (pair address (big_map address nat)) nat) + (lambda + (pair (pair address int) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat)) + (pair (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat))) + string) + (pair (pair address int) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat))) + (pair (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat)) + { UNPAIR ; + UNPAIR 3 ; + DIG 3 ; + UNPAIR ; + UNPAIR ; + DUP 3 ; + CAR ; + CAR ; + CDR ; + DUP 2 ; + PAIR ; + DIG 4 ; + SWAP ; + EXEC ; + DUP 3 ; + ADD ; + ISNAT ; + IF_NONE + { DIG 4 ; FAILWITH } + { DIG 5 ; + DROP ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + EQ ; + IF { DROP ; DUP 3 ; CAR ; CAR ; CDR ; DUP 2 ; NONE nat ; SWAP ; UPDATE } + { DUP 4 ; CAR ; CAR ; CDR ; SWAP ; SOME ; DUP 3 ; UPDATE } } ; + PUSH int 0 ; + DUP 4 ; + COMPARE ; + EQ ; + IF { SWAP ; DIG 2 ; DIG 4 ; DROP 3 ; SWAP } + { DUP 4 ; + DIG 3 ; + DIG 4 ; + CAR ; + CAR ; + CAR ; + DUP 5 ; + GET ; + IF_NONE { DIG 3 } { DIG 4 ; DROP } ; + PAIR ; + PAIR ; + DIG 2 ; + SWAP ; + EXEC } ; + DUP ; + CDR ; + DUP 2 ; + CAR ; + CDR ; + DIG 3 ; + DIG 3 ; + CAR ; + CAR ; + CAR ; + PAIR ; + PAIR ; + PAIR } ; + DUP 4 ; + DUP 4 ; + DUP 4 ; + PAIR 3 ; + APPLY ; + LAMBDA + (pair (pair (lambda + (pair (pair address int) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat)) + (pair (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat))) + string) + (pair (pair (list (pair (option address) (list (pair (option address) nat nat)))) + (lambda (pair (pair address address) nat (big_map (pair address address nat) unit)) unit)) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat))) + (pair (list operation) + (pair (pair (big_map address address) (big_map address nat)) + address + (big_map (pair address address nat) unit)) + (pair (big_map nat (pair nat (map string bytes))) nat) + (big_map (pair address nat) (pair nat nat)) + (big_map address nat)) + { UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + UNPAIR ; + DIG 2 ; + SWAP ; + ITER { SWAP ; + SENDER ; + SWAP ; + DUP 3 ; + CDR ; + ITER { SWAP ; + PUSH nat 0 ; + DUP 3 ; + GET 3 ; + COMPARE ; + NEQ ; + IF { DROP 2 ; DUP 5 ; FAILWITH } + { DUP 4 ; + CAR ; + IF_NONE + {} + { DUP 2 ; + CAR ; + CDR ; + CDR ; + DUP 4 ; + GET 3 ; + PAIR ; + DUP 5 ; + DUP 3 ; + PAIR ; + PAIR ; + DUP 7 ; + SWAP ; + EXEC ; + DROP ; + SWAP ; + DUP 3 ; + GET 4 ; + NEG ; + DIG 2 ; + PAIR ; + PAIR ; + DUP 6 ; + SWAP ; + EXEC } ; + DUP 2 ; + CAR ; + IF_NONE + { SWAP ; DROP } + { SWAP ; DIG 2 ; GET 4 ; INT ; DIG 2 ; PAIR ; PAIR ; DUP 5 ; SWAP ; EXEC } } } ; + SWAP ; + DIG 2 ; + DROP 2 } ; + SWAP ; + DIG 2 ; + DIG 3 ; + DROP 3 ; + NIL operation ; + PAIR } ; + DUP 6 ; + DUP 3 ; + PAIR ; + APPLY ; + SWAP ; + DROP ; + LAMBDA + (list (pair address nat)) + nat + { PUSH nat 0 ; SWAP ; ITER { CDR ; ADD } } ; + LAMBDA + (pair address bool) + unit + { CAR ; + SENDER ; + COMPARE ; + NEQ ; + IF { PUSH string "NOT_AN_ADMIN" ; FAILWITH } { UNIT } } ; + LAMBDA + (pair address bool) + unit + { CDR ; IF { PUSH string "PAUSED" ; FAILWITH } { UNIT } } ; + DIG 8 ; + UNPAIR ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { PUSH string "AMOUNT_NOT_ZERO" ; FAILWITH } {} ; + IF_LEFT + { DIG 4 ; + DIG 8 ; + DROP 2 ; + IF_LEFT + { DIG 6 ; + DROP ; + IF_LEFT + { DIG 2 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DROP 4 ; + DUP 2 ; + CAR ; + CAR ; + DIG 3 ; + SWAP ; + EXEC ; + DROP ; + DUP 2 ; + CAR ; + CAR ; + SWAP ; + IF_LEFT { SWAP ; CAR } { SWAP ; CDR ; SWAP } ; + PAIR ; + NIL operation ; + DUP 3 ; + CDR ; + DIG 3 ; + CAR ; + CDR ; + DIG 3 } + { DIG 3 ; + DROP ; + DUP 2 ; + CAR ; + CAR ; + DIG 3 ; + SWAP ; + EXEC ; + DROP ; + DUP 2 ; + CAR ; + CDR ; + SWAP ; + IF_LEFT + { IF_LEFT + { DIG 3 ; + DROP ; + DUP ; + CAR ; + MAP { PUSH nat 0 ; + DUP 2 ; + CDR ; + COMPARE ; + NEQ ; + IF { DROP ; DUP 5 ; FAILWITH } + { DUP 3 ; + CAR ; + CAR ; + CDR ; + DUP 2 ; + CAR ; + PAIR ; + DUP 6 ; + SWAP ; + EXEC ; + SWAP ; + PAIR } } ; + DIG 4 ; + DIG 5 ; + DROP 2 ; + SWAP ; + CDR ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + SWAP ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } + { DIG 4 ; + DIG 5 ; + DROP 2 ; + MAP { DUP ; + CDR ; + MAP { DUP ; GET 4 ; DUP 2 ; GET 3 ; DIG 2 ; CAR ; SOME ; PAIR 3 } ; + SWAP ; + CAR ; + SOME ; + PAIR } ; + SWAP ; + LAMBDA + (pair (pair address address) nat (big_map (pair address address nat) unit)) + unit + { UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + DUP 4 ; + DUP 4 ; + COMPARE ; + EQ ; + IF { DROP 4 ; UNIT } + { DIG 3 ; + PAIR ; + DIG 2 ; + PAIR ; + MEM ; + IF { UNIT } { PUSH string "FA2_NOT_OPERATOR" ; FAILWITH } } } ; + DIG 2 ; + PAIR ; + PAIR ; + DIG 2 ; + SWAP ; + EXEC } } + { DIG 3 ; + DIG 4 ; + DIG 5 ; + DROP 3 ; + SENDER ; + DUP 3 ; + CAR ; + CDR ; + CDR ; + DIG 2 ; + ITER { SWAP ; + DUP 3 ; + DUP 3 ; + IF_LEFT {} {} ; + CAR ; + COMPARE ; + EQ ; + IF {} { PUSH string "FA2_NOT_OWNER" ; FAILWITH } ; + SWAP ; + IF_LEFT + { SWAP ; + UNIT ; + SOME ; + DUP 3 ; + GET 4 ; + DUP 4 ; + GET 3 ; + PAIR ; + DIG 3 ; + CAR ; + PAIR ; + UPDATE } + { SWAP ; + DUP 2 ; + GET 4 ; + DUP 3 ; + GET 3 ; + PAIR ; + DIG 2 ; + CAR ; + PAIR ; + NONE unit ; + SWAP ; + UPDATE } } ; + SWAP ; + DROP ; + DUP 2 ; + CDR ; + SWAP ; + DUP 3 ; + CAR ; + CDR ; + CAR ; + PAIR ; + DIG 2 ; + CAR ; + CAR ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } ; + UNPAIR ; + DUP 3 ; + CDR ; + DIG 2 ; + DIG 3 ; + CAR ; + CAR } ; + PAIR ; + PAIR ; + SWAP } + { DIG 4 ; + DIG 7 ; + DROP 2 ; + IF_LEFT + { DIG 3 ; + DROP ; + DUP 2 ; + CAR ; + CAR ; + DIG 3 ; + SWAP ; + EXEC ; + DROP ; + DUP 2 ; + CAR ; + CDR ; + DUP ; + CAR ; + CAR ; + CDR ; + SENDER ; + PAIR ; + DIG 4 ; + SWAP ; + EXEC ; + DUP 3 ; + IF_NONE { SENDER } {} ; + DUP 3 ; + CAR ; + CAR ; + CAR ; + SENDER ; + GET ; + IF_NONE { SENDER } {} ; + PUSH nat 0 ; + DUP 4 ; + COMPARE ; + EQ ; + DUP 2 ; + DUP 4 ; + COMPARE ; + EQ ; + OR ; + IF { SWAP ; DIG 2 ; DIG 6 ; DROP 4 ; DUP } + { DUP 4 ; + DUP 4 ; + NEG ; + DIG 2 ; + PAIR ; + PAIR ; + DUP 7 ; + SWAP ; + EXEC ; + DIG 2 ; + INT ; + DIG 2 ; + PAIR ; + PAIR ; + DIG 4 ; + SWAP ; + EXEC } ; + DUP ; + CDR ; + DUP 2 ; + CAR ; + CDR ; + DIG 2 ; + CAR ; + CAR ; + CDR ; + DIG 3 ; + CAR ; + CAR ; + CAR ; + DIG 4 ; + SENDER ; + UPDATE ; + PAIR ; + PAIR ; + PAIR ; + DUP 2 ; + CDR ; + SWAP ; + DIG 2 ; + CAR ; + CAR } + { DIG 2 ; + DIG 4 ; + DIG 5 ; + DROP 3 ; + DUP 2 ; + CAR ; + CAR ; + DIG 3 ; + SWAP ; + EXEC ; + DROP ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + CDR ; + DUP ; + CDR ; + DUP 2 ; + CAR ; + CDR ; + CDR ; + DIG 4 ; + PAIR ; + DIG 2 ; + CAR ; + CAR ; + PAIR ; + PAIR ; + DIG 2 ; + CAR ; + CAR } ; + PAIR ; + PAIR ; + NIL operation } } + { DIG 3 ; + DIG 6 ; + DIG 7 ; + DIG 9 ; + DROP 4 ; + DUP 2 ; + CAR ; + CAR ; + DIG 3 ; + SWAP ; + EXEC ; + DROP ; + DUP 2 ; + CAR ; + CDR ; + CAR ; + CDR ; + CAR ; + SENDER ; + COMPARE ; + NEQ ; + IF { PUSH string "NOT_MINTER" ; FAILWITH } {} ; + DUP 2 ; + CAR ; + CDR ; + SWAP ; + IF_LEFT + { DUP ; + MAP { NIL (pair (option address) nat nat) ; + DUP 2 ; + CDR ; + PUSH nat 0 ; + NONE address ; + PAIR 3 ; + CONS ; + SWAP ; + CAR ; + SOME ; + PAIR } ; + DUP 3 ; + LAMBDA + (pair (pair address address) nat (big_map (pair address address nat) unit)) + unit + { DROP ; UNIT } ; + DIG 2 ; + PAIR ; + PAIR ; + DIG 5 ; + SWAP ; + EXEC ; + UNPAIR ; + DIG 2 ; + DIG 5 ; + SWAP ; + EXEC ; + DIG 3 ; + CDR ; + CAR ; + CDR ; + SUB ; + ISNAT ; + IF_NONE { DIG 3 ; FAILWITH } { DIG 4 ; DROP } ; + DUP 3 ; + CDR ; + CDR ; + SWAP ; + DUP 4 ; + CDR ; + CAR ; + CAR ; + PAIR ; + PAIR ; + DIG 2 ; + CAR } + { DIG 5 ; + DROP ; + DUP ; + MAP { DUP ; CDR ; PUSH nat 0 ; DIG 2 ; CAR ; SOME ; PAIR 3 } ; + DUP 3 ; + LAMBDA + (pair (pair address address) nat (big_map (pair address address nat) unit)) + unit + { DROP ; UNIT } ; + NIL (pair (option address) (list (pair (option address) nat nat))) ; + DIG 3 ; + NONE address ; + PAIR ; + CONS ; + PAIR ; + PAIR ; + DIG 5 ; + SWAP ; + EXEC ; + UNPAIR ; + DIG 2 ; + DIG 5 ; + SWAP ; + EXEC ; + DUP 3 ; + CDR ; + CDR ; + SWAP ; + DIG 4 ; + CDR ; + CAR ; + CDR ; + ADD ; + DUP 4 ; + CDR ; + CAR ; + CAR ; + PAIR ; + PAIR ; + DIG 2 ; + CAR } ; + PAIR ; + SWAP ; + DUP 3 ; + CDR ; + DIG 2 ; + DIG 3 ; + CAR ; + CAR ; + PAIR ; + PAIR ; + SWAP } ; + PAIR } ; +view "voting_power" + (pair (address %addr) (nat %block_level)) + nat + { LAMBDA + int + nat + { ISNAT ; IF_NONE { PUSH string "NOT_A_NAT" ; FAILWITH } {} } ; + SWAP ; + UNPAIR ; + SWAP ; + CAR ; + CDR ; + SWAP ; + UNPAIR ; + DUP 3 ; + CDR ; + CDR ; + CDR ; + DUP 2 ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + EQ ; + IF { DROP 5 ; PUSH nat 0 } + { DUP 4 ; + PUSH int 1 ; + DUP 3 ; + SUB ; + DUP 7 ; + SWAP ; + EXEC ; + DUP 4 ; + DIG 2 ; + CDR ; + CDR ; + CAR ; + DUG 2 ; + PAIR ; + GET ; + IF_NONE { PUSH string "option is None" ; FAILWITH } {} ; + DUP 4 ; + DUP 2 ; + CDR ; + COMPARE ; + LE ; + IF { SWAP ; DIG 2 ; DIG 3 ; DIG 4 ; DIG 5 ; DROP 5 ; CAR } + { DROP ; + DUP 4 ; + CDR ; + CDR ; + CAR ; + PUSH nat 0 ; + DUP 4 ; + PAIR ; + GET ; + IF_NONE { PUSH string "option is None" ; FAILWITH } {} ; + DUP 4 ; + SWAP ; + CDR ; + COMPARE ; + GT ; + IF { DROP 5 ; PUSH nat 0 } + { PUSH int 1 ; + SWAP ; + SUB ; + DUP 5 ; + SWAP ; + EXEC ; + PUSH nat 0 ; + PAIR ; + LEFT nat ; + LOOP_LEFT + { UNPAIR ; + DUP 2 ; + DUP 2 ; + COMPARE ; + EQ ; + IF { SWAP ; + DROP ; + DUP 4 ; + CDR ; + CDR ; + CAR ; + SWAP ; + DUP 3 ; + PAIR ; + GET ; + IF_NONE { PUSH string "option is None" ; FAILWITH } {} ; + CAR ; + RIGHT (pair nat nat) } + { PUSH int 2 ; + DUP 2 ; + DUP 4 ; + SUB ; + DUP 8 ; + SWAP ; + EXEC ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + SUB ; + DUP 7 ; + SWAP ; + EXEC ; + DUP 6 ; + CDR ; + CDR ; + CAR ; + DUP 2 ; + DUP 6 ; + PAIR ; + GET ; + IF_NONE { PUSH string "option is None" ; FAILWITH } {} ; + DUP 6 ; + DUP 2 ; + CDR ; + COMPARE ; + EQ ; + IF { SWAP ; DIG 2 ; DIG 3 ; DROP 3 ; CAR ; RIGHT (pair nat nat) } + { DUP 6 ; + SWAP ; + CDR ; + COMPARE ; + GT ; + IF { DIG 2 ; DROP ; PUSH int 1 ; SWAP ; SUB ; DUP 6 ; SWAP ; EXEC } + { SWAP ; DROP ; SWAP } ; + SWAP ; + PAIR ; + LEFT nat } } } ; + SWAP ; + DIG 2 ; + DIG 3 ; + DIG 4 ; + DROP 4 } } } } ; +view "total_supply" unit nat { CDR ; CAR ; CDR ; CDR ; CAR ; CDR } } + +` diff --git a/src/services/contracts/token/hooks/useToken.ts b/src/services/contracts/token/hooks/useToken.ts index 8c38d3c8..66526503 100644 --- a/src/services/contracts/token/hooks/useToken.ts +++ b/src/services/contracts/token/hooks/useToken.ts @@ -7,7 +7,8 @@ import { deployMetadataCarrier } from "services/contracts/metadataCarrier/deploy import { useTezos } from "services/beacon/hooks/useTezos" import mixpanel from "mixpanel-browser" import { TokenContractParams } from "modules/creator/deployment/state/types" -import { deployTokenContract } from ".." +import { getCurrentBlock } from "services/utils/utils" +import { deployTokenContract } from "services/contracts/token" export const useTokenOriginate = (tokenData: TokenContractParams) => { const queryClient = useQueryClient() @@ -33,10 +34,13 @@ export const useTokenOriginate = (tokenData: TokenContractParams) => { tokenSettings } + const currentBlock = await getCurrentBlock(network) + const contract = await deployTokenContract({ ...mutateTokenData, tezos: tezosToolkit, - account + account, + currentBlock }) if (!contract) { diff --git a/src/services/contracts/token/index.ts b/src/services/contracts/token/index.ts index 89545d59..b235a152 100644 --- a/src/services/contracts/token/index.ts +++ b/src/services/contracts/token/index.ts @@ -2,7 +2,7 @@ import { MichelsonMap, TezosToolkit } from "@taquito/taquito" import BigNumber from "bignumber.js" import { TokenContractParams } from "modules/creator/deployment/state/types" import { formatUnits } from "../utils" -import fa2MultiAsset from "./assets/MultiAsset.json" +import fa2_single_asset_delegated from "./assets/fa2_single_asset_delegated" interface Tezos { tezos: TezosToolkit @@ -13,8 +13,9 @@ export const deployTokenContract = async ({ tokenSettings, tokenDistribution, tezos, - account -}: TokenContractParams & Tezos) => { + account, + currentBlock +}: TokenContractParams & Tezos & any) => { try { const metadata = MichelsonMap.fromLiteral({ "": Buffer.from("tezos-storage:contents", "ascii").toString("hex"), @@ -23,7 +24,7 @@ export const deployTokenContract = async ({ version: "v0.0.1", name: tokenSettings.name, description: tokenSettings.description, - authors: ["FA2 Bakery"], + authors: ["Tezos Homebase"], source: { tools: ["Ligo"] }, @@ -35,14 +36,17 @@ export const deployTokenContract = async ({ const storage = { admin: { admin: account, - pending_admin: null, paused: false }, assets: { - token_total_supply: MichelsonMap.fromLiteral({}), - ledger: MichelsonMap.fromLiteral({}), - operators: MichelsonMap.fromLiteral({}), - token_metadata: MichelsonMap.fromLiteral({}) + ledger: new MichelsonMap(), + voting_power_history: new MichelsonMap(), + voting_power_history_sizes: new MichelsonMap(), + delegates: new MichelsonMap(), + operators: new MichelsonMap(), + token_metadata: new MichelsonMap(), + total_supply: 0, + minter: account }, metadata: metadata } @@ -52,14 +56,19 @@ export const deployTokenContract = async ({ tokenSettings.decimals && formatUnits(new BigNumber(tokenSettings.totalSupply), tokenSettings.decimals) - totalSupply && storage.assets.token_total_supply.set(index, totalSupply.toString()) - tokenDistribution.holders.map((holder, holderIndex) => { - holder.amount && - tokenSettings.decimals && + storage.assets.total_supply = totalSupply.toString() + tokenDistribution.holders.map((holder: { amount: BigNumber.Value; walletAddress: any }) => { + if (holder.amount && tokenSettings.decimals) { storage.assets.ledger.set( - [holder.walletAddress, index], + holder.walletAddress, formatUnits(new BigNumber(holder.amount), tokenSettings.decimals).toString() ) + storage.assets.voting_power_history.set([holder.walletAddress, 0], { + from_block: currentBlock, + amount: formatUnits(new BigNumber(holder.amount), tokenSettings.decimals).toString() + }) + storage.assets.voting_power_history_sizes.set(holder.walletAddress, 1) + } }) storage.assets.token_metadata.set(index, { token_id: index, @@ -73,7 +82,7 @@ export const deployTokenContract = async ({ }) }) const t = tezos.wallet.originate({ - code: fa2MultiAsset, + code: fa2_single_asset_delegated, storage }) const c = await t.send() diff --git a/src/theme/index.ts b/src/theme/index.ts index 239ee96a..376daa07 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -317,7 +317,8 @@ export const theme = createTheme({ "$checked$checked + &": { opacity: 1, backgroundColor: "#1C1F23", - color: "#81FEB7" + color: "#81FEB7", + border: "1px solid #1C1F23" } }, thumb: { @@ -387,7 +388,8 @@ export const theme = createTheme({ root: { "height": 70, "& th:first-child, & td:first-child": { - paddingLeft: 46 + paddingLeft: 46, + textAlign: "inherit" }, "& th:last-child, & td:last-child": { paddingRight: 46 diff --git a/src/theme/legacy.ts b/src/theme/legacy.ts index d792a299..e24bee3e 100644 --- a/src/theme/legacy.ts +++ b/src/theme/legacy.ts @@ -32,7 +32,7 @@ export const legacyTheme = createMuiTheme({ }, subtitle1: { fontSize: 18, - fontWeight: 400, + fontWeight: 300, lineHeight: "26.33px", letterSpacing: "-0.01em" }, @@ -43,7 +43,7 @@ export const legacyTheme = createMuiTheme({ letterSpacing: "-0.01em" }, h3: { - fontSize: 35, + fontSize: 32, fontWeight: 500, fontFamily: "Roboto Mono" }, @@ -239,6 +239,9 @@ export const legacyTheme = createMuiTheme({ input: { textAlign: "start", color: "#fff" + }, + root: { + fontWeight: 300 } }, MuiDivider: {