From f89e70aae5e8cdaf584916a218d68c72369b0db9 Mon Sep 17 00:00:00 2001 From: aeddaqqa Date: Thu, 12 Sep 2024 15:26:50 +0100 Subject: [PATCH] feat(suite): add CMAccount creation functionality and a new partners section partner profile --- package.json | 11 +- src/components/Alert.tsx | 71 + src/components/CamInput.tsx | 137 + src/components/Input.tsx | 81 + src/components/MainButton.tsx | 45 +- .../CMAccountManagerModule#CMAccount.json | 2396 +++++++++++++++++ .../ManagerProxyModule#CMAccountManager.json | 1118 ++++++++ src/helpers/partnerConfigurationContext.tsx | 393 +++ src/helpers/usePartnerConfig.tsx | 329 +++ src/helpers/useSmartContract.tsx | 179 ++ src/helpers/useWalletBalance.tsx | 38 + src/layout/PartnersLayout.tsx | 152 +- src/layout/RoutesSuite.tsx | 12 + src/redux/services/partners.ts | 13 +- src/redux/store.ts | 6 +- src/views/partners/ConfigurDistrubitor.tsx | 231 ++ src/views/partners/ConfigurSupplier.tsx | 238 ++ src/views/partners/Configuration.tsx | 939 +++++++ src/views/partners/ManageBots.tsx | 246 ++ src/views/settings/Links.tsx | 107 +- tsconfig.json | 10 +- webpack.common.js | 5 + webpack.dev.js | 5 + 23 files changed, 6702 insertions(+), 60 deletions(-) create mode 100644 src/components/Alert.tsx create mode 100644 src/components/CamInput.tsx create mode 100644 src/components/Input.tsx create mode 100644 src/helpers/CMAccountManagerModule#CMAccount.json create mode 100644 src/helpers/ManagerProxyModule#CMAccountManager.json create mode 100644 src/helpers/partnerConfigurationContext.tsx create mode 100644 src/helpers/usePartnerConfig.tsx create mode 100644 src/helpers/useSmartContract.tsx create mode 100644 src/helpers/useWalletBalance.tsx create mode 100644 src/views/partners/ConfigurDistrubitor.tsx create mode 100644 src/views/partners/ConfigurSupplier.tsx create mode 100644 src/views/partners/Configuration.tsx create mode 100644 src/views/partners/ManageBots.tsx diff --git a/package.json b/package.json index 9a649184..dda2a017 100644 --- a/package.json +++ b/package.json @@ -32,14 +32,16 @@ "@emotion/styled": "^11.10.5", "@mdi/js": "^7.0.96", "@mdi/react": "^1.6.1", - "@reduxjs/toolkit": "^1.8.1", - "@testing-library/dom": "^8.19.0", "@mui/icons-material": "^5.15.11", "@mui/material": "^5.15.11", "@mui/system": "^5.15.11", + "@reduxjs/toolkit": "^1.8.1", + "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.0.1", "@testing-library/user-event": "^14.1.1", + "@types/big.js": "^6.2.2", + "@types/ethereum-protocol": "^1.0.5", "@types/jest": "^27.4.1", "@types/lodash": "^4.14.189", "@types/node": "^17.0.25", @@ -61,6 +63,7 @@ "formik": "^2.2.9", "framer-motion": "^8.4.3", "html-webpack-plugin": "^5.3.2", + "json-loader": "^0.5.7", "lodash": "^4.17.21", "path": "^0.12.7", "postcss": "^8.2.1", @@ -79,9 +82,11 @@ "webpack-cli": "^5.0.0", "webpack-dev-server": "^4.3.1", "webpack-merge": "^5.8.0", - "yup": "^0.32.11" + "yup": "^0.32.11", + "ethers": "^6.13.2" }, "dependencies": { + "big.js": "^6.2.1", "react": "^18.2.0", "react-circle-flags": "^0.0.18", "react-dom": "^18.2.0" diff --git a/src/components/Alert.tsx b/src/components/Alert.tsx new file mode 100644 index 00000000..c2f315dc --- /dev/null +++ b/src/components/Alert.tsx @@ -0,0 +1,71 @@ +import { Box, Typography } from '@mui/material' +import React from 'react' + +const Alert = ({ + variant, + title, + content, +}: { + variant: 'info' | 'negative' + title?: string + content: string +}) => { + return ( + + + {variant === 'info' && ( + + + + )} + {variant === 'negative' && ( + + + + )} + + + {title && ( + + {title} + + )} + {content && {content}} + + + ) +} + +export default Alert diff --git a/src/components/CamInput.tsx b/src/components/CamInput.tsx new file mode 100644 index 00000000..2f2363a9 --- /dev/null +++ b/src/components/CamInput.tsx @@ -0,0 +1,137 @@ +import Big from 'big.js' +import BN from 'bn.js' +import React, { useCallback, useEffect, useState } from 'react' + +Big.PE = 32 + +function bnToBig(val, denomination) { + return new Big(val.toString()).div(Math.pow(10, denomination)) +} + +function bigToBN(val, denomination) { + return new BN(val.mul(Math.pow(10, denomination)).toString()) +} + +const DecimalInput = ({ + denomination = 0, + max = null, + min = 0, + step = null, + placeholder, + value, + initial = null, + onChange, +}) => { + const [val, setVal] = useState(bnToString(initial)) + + const bnToString = useCallback( + val => { + return val ? bnToBig(val, denomination).toString() : null + }, + [denomination], + ) + + const stringToBN = useCallback( + strVal => { + return bigToBN(new Big(strVal), denomination) + }, + [denomination], + ) + + const maxNumBN = max + const maxNumString = bnToString(maxNumBN) + + const stepNum = (() => { + if (!step) { + if (denomination >= 2) { + return 0.01 + } else { + return Math.pow(10, -denomination) + } + } + try { + return bnToString(step) + } catch (e) { + console.error(e) + return '0.01' + } + })() + + useEffect(() => { + if (!val) { + onChange(new BN(0)) + return + } + try { + let splitVal = val.toString().split('.') + let wholeVal = splitVal[0] + let denomVal = splitVal[1] + if (denomVal) { + if (denomVal.length > denomination) { + let newDenom = denomVal.substring(0, denomination) + setVal(`${wholeVal}.${newDenom}`) + return + } + } + } catch (e) { + console.log(e) + } + if (parseFloat(val) < min) { + setVal(min.toString()) + return + } + let valBn = stringToBN(val) + onChange(valBn) + }, [val, denomination, min, onChange, stringToBN]) + + useEffect(() => { + setVal(bnToString(value)) + }, [value, bnToString]) + + const handleChange = e => { + setVal(e.target.value) + } + + const handleBlur = () => { + // If number is above max amount, correct it + const valBig = Big(val || '0') + const valBN = bigToBN(valBig, denomination) + if (maxNumBN != null) { + if (valBN.gt(maxNumBN)) { + setVal(bnToString(maxNumBN)) + } + } + } + + const maxout = () => { + if (maxNumBN != null) { + setVal(bnToString(maxNumBN)) + } + } + + const clear = () => { + setVal(undefined) + } + + return ( + + ) +} + +export default DecimalInput diff --git a/src/components/Input.tsx b/src/components/Input.tsx new file mode 100644 index 00000000..75476493 --- /dev/null +++ b/src/components/Input.tsx @@ -0,0 +1,81 @@ +import { InputAdornment, Typography } from '@mui/material' +import TextField from '@mui/material/TextField' // Import TextField if using Material-UI +import React, { useMemo } from 'react' +import { actionTypes, usePartnerConfigurationContext } from '../helpers/partnerConfigurationContext' + +const Input = ({ variant = 'outlined', ...rest }) => { + const { state, dispatch } = usePartnerConfigurationContext() + const error = useMemo(() => { + if (!state.balance) return true + let balance = parseFloat(state.balance) + if (balance < 100) return true + else return false + }, [state]) + return ( + { + dispatch({ + type: actionTypes.UPDATE_BALANCE, + payload: { + newValue: e.target.value, + }, + }) + }} + type="number" + error={error} + InputProps={{ + sx: { + '& input': { + fontSize: '16px', + }, + }, + startAdornment: ( + theme.palette.text.primary, + }} + > + Prefund Amount: + + ), + endAdornment: error ? ( + + + + + + ) : ( + + + + + + ), + }} + {...rest} + /> + ) +} + +export default Input diff --git a/src/components/MainButton.tsx b/src/components/MainButton.tsx index a0070302..1f29b5f5 100644 --- a/src/components/MainButton.tsx +++ b/src/components/MainButton.tsx @@ -1,30 +1,40 @@ +import { Button, CircularProgress, SvgIconTypeMap, Typography } from '@mui/material' +import { OverridableComponent } from '@mui/material/OverridableComponent' import * as React from 'react' -import { Button } from '@mui/material' function MainButton({ variant, onClick, children, style, + disabled, + loading, + endIcon, }: { variant: 'contained' | 'outlined' onClick?: React.MouseEventHandler children: React.ReactNode style?: React.CSSProperties + disabled?: boolean + loading?: boolean + endIcon?: any }) { return ( ) } diff --git a/src/helpers/CMAccountManagerModule#CMAccount.json b/src/helpers/CMAccountManagerModule#CMAccount.json new file mode 100644 index 00000000..15f3682f --- /dev/null +++ b/src/helpers/CMAccountManagerModule#CMAccount.json @@ -0,0 +1,2396 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "latestImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "CMAccountImplementationMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "CMAccountNoUpgradeNeeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "ChequeExpired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "DepositorNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "chequeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastAmount", + "type": "uint256" + } + ], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "chequeCounter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastCounter", + "type": "uint256" + } + ], + "name": "InvalidCounter", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + } + ], + "name": "InvalidFromCMAccount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "use", + "type": "uint8" + } + ], + "name": "InvalidPublicKeyUseType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "toCMAccount", + "type": "address" + } + ], + "name": "InvalidToCMAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "NotAllowedToSignCheques", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "PaymentTokenAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "PaymentTokenDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawableAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "prefundLeft", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PrefundNotSpentYet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "PublicKeyAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "PublicKeyDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "TransferToZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "WantedServiceAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "WantedServiceDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalLimitExceededForPeriod", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ZeroValueDeposit", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "CMAccountUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "fromBot", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "developerFee", + "type": "uint256" + } + ], + "name": "ChequeCashedIn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toCMAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromBot", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payment", + "type": "uint256" + } + ], + "name": "ChequeVerified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "GasMoneyWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "name": "GasMoneyWithdrawalUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bot", + "type": "address" + } + ], + "name": "MessengerBotAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bot", + "type": "address" + } + ], + "name": "MessengerBotRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "supportsOffChainPayment", + "type": "bool" + } + ], + "name": "OffChainPaymentSupportUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "PaymentTokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "PaymentTokenRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "PublicKeyAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "PublicKeyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceCapabilitiesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "capability", + "type": "string" + } + ], + "name": "ServiceCapabilityAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "capability", + "type": "string" + } + ], + "name": "ServiceCapabilityRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "ServiceFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "restrictedRate", + "type": "bool" + } + ], + "name": "ServiceRestrictedRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "WantedServiceAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "WantedServiceRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BOOKING_OPERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BOT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CHEQUE_OPERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAS_WITHDRAWER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MESSENGER_CHEQUE_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SERVICE_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WITHDRAWER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bot", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gasMoney", + "type": "uint256" + } + ], + "name": "addMessengerBot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "addPublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "restrictedRate", + "type": "bool" + }, + { + "internalType": "string[]", + "name": "capabilities", + "type": "string[]" + } + ], + "name": "addService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "string", + "name": "capability", + "type": "string" + } + ], + "name": "addServiceCapability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_supportedToken", + "type": "address" + } + ], + "name": "addSupportedToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "serviceNames", + "type": "string[]" + } + ], + "name": "addWantedServices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "buyBookingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "createdAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "cashInCheque", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllServiceHashes", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "serviceHashes", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBookingTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGasMoneyWithdrawal", + "outputs": [ + { + "internalType": "uint256", + "name": "withdrawalLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawalPeriod", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getGasMoneyWithdrawalForAccount", + "outputs": [ + { + "internalType": "uint256", + "name": "periodStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawnAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromBot", + "type": "address" + }, + { + "internalType": "address", + "name": "toBot", + "type": "address" + } + ], + "name": "getLastCashIn", + "outputs": [ + { + "internalType": "uint256", + "name": "lastCounter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastCreatedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastExpiresAt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrefundAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "getPublicKey", + "outputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPublicKeysAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "pubKeyAddresses", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "getService", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_restrictedRate", + "type": "bool" + }, + { + "internalType": "string[]", + "name": "_capabilities", + "type": "string[]" + } + ], + "internalType": "struct PartnerConfiguration.Service", + "name": "service", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "getServiceCapabilities", + "outputs": [ + { + "internalType": "string[]", + "name": "capabilities", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "getServiceCapabilities", + "outputs": [ + { + "internalType": "string[]", + "name": "capabilities", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "getServiceFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "getServiceFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "getServiceRestrictedRate", + "outputs": [ + { + "internalType": "bool", + "name": "restrictedRate", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "getServiceRestrictedRate", + "outputs": [ + { + "internalType": "bool", + "name": "restrictedRate", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSupportedServices", + "outputs": [ + { + "internalType": "string[]", + "name": "serviceNames", + "type": "string[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_restrictedRate", + "type": "bool" + }, + { + "internalType": "string[]", + "name": "_capabilities", + "type": "string[]" + } + ], + "internalType": "struct PartnerConfiguration.Service[]", + "name": "services", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSupportedTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalChequePayments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWantedServiceHashes", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "serviceHashes", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWantedServices", + "outputs": [ + { + "internalType": "string[]", + "name": "serviceNames", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "createdAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "hashMessengerCheque", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "createdAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "hashTypedDataV4", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + }, + { + "internalType": "address", + "name": "bookingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "prefundAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "defaultAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "upgrader", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bot", + "type": "address" + } + ], + "name": "isBotAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reservedFor", + "type": "address" + }, + { + "internalType": "string", + "name": "uri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "expirationTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "paymentToken", + "type": "address" + } + ], + "name": "mintBookingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "offChainPaymentSupported", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bot", + "type": "address" + } + ], + "name": "removeMessengerBot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pubKeyAddress", + "type": "address" + } + ], + "name": "removePublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "removeService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "string", + "name": "capability", + "type": "string" + } + ], + "name": "removeServiceCapability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_supportedToken", + "type": "address" + } + ], + "name": "removeSupportedToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "serviceNames", + "type": "string[]" + } + ], + "name": "removeWantedServices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "name": "setGasMoneyWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isSupported", + "type": "bool" + } + ], + "name": "setOffChainPaymentSupported", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "string[]", + "name": "capabilities", + "type": "string[]" + } + ], + "name": "setServiceCapabilities", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setServiceFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "internalType": "bool", + "name": "restrictedRate", + "type": "bool" + } + ], + "name": "setServiceRestrictedRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC721", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toCMAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "toBot", + "type": "address" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "createdAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "verifyCheque", + "outputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "paymentAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawGasMoney", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/helpers/ManagerProxyModule#CMAccountManager.json b/src/helpers/ManagerProxyModule#CMAccountManager.json new file mode 100644 index 00000000..fc69798c --- /dev/null +++ b/src/helpers/ManagerProxyModule#CMAccountManager.json @@ -0,0 +1,1118 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "CMAccountManager", + "sourceName": "contracts/manager/CMAccountManager.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "CMAccountInvalidAdmin", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "CMAccountInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "EnforcedPause", + "type": "error" + }, + { + "inputs": [], + "name": "ExpectedPause", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sended", + "type": "uint256" + } + ], + "name": "IncorrectPrefundAmount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bookingToken", + "type": "address" + } + ], + "name": "InvalidBookingTokenAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "developerWallet", + "type": "address" + } + ], + "name": "InvalidDeveloperWallet", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "ServiceAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "ServiceNotRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldBookingToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newBookingToken", + "type": "address" + } + ], + "name": "BookingTokenAddressUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "CMAccountCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "CMAccountImplementationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "oldDeveloperFeeBp", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newDeveloperFeeBp", + "type": "uint256" + } + ], + "name": "DeveloperFeeBpUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldDeveloperWallet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newDeveloperWallet", + "type": "address" + } + ], + "name": "DeveloperWalletUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "serviceName", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "ServiceUnregistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "CMACCOUNT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEVELOPER_WALLET_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PREFUND_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SERVICE_REGISTRY_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSIONER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "upgrader", + "type": "address" + } + ], + "name": "createCMAccount", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getAccountImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllRegisteredServiceHashes", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "services", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllRegisteredServiceNames", + "outputs": [ + { + "internalType": "string[]", + "name": "services", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBookingTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getCMAccountCreator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeveloperFeeBp", + "outputs": [ + { + "internalType": "uint256", + "name": "developerFeeBp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeveloperWallet", + "outputs": [ + { + "internalType": "address", + "name": "developerWallet", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrefundAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "getRegisteredServiceHashByName", + "outputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "serviceHash", + "type": "bytes32" + } + ], + "name": "getRegisteredServiceNameByHash", + "outputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "defaultAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "pauser", + "type": "address" + }, + { + "internalType": "address", + "name": "upgrader", + "type": "address" + }, + { + "internalType": "address", + "name": "versioner", + "type": "address" + }, + { + "internalType": "address", + "name": "developerWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "developerFeeBp", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isCMAccount", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "registerService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "setAccountImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "setBookingTokenAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "bp", + "type": "uint256" + } + ], + "name": "setDeveloperFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "developerWallet", + "type": "address" + } + ], + "name": "setDeveloperWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newPrefundAmount", + "type": "uint256" + } + ], + "name": "setPrefundAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "serviceName", + "type": "string" + } + ], + "name": "unregisterService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000da565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000775760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d75780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051612f7462000104600039600081816115bf015281816115e901526117440152612f746000f3fe608060405260043610620002185760003560e01c806301601d2f146200021d57806301ffc9a714620002555780630470d3ac146200028b57806309766da214620002b25780630d6115d014620002d957806312b357b514620002fe5780631c2b3afc1462000323578063248a9ca314620003485780632cec1a06146200036d5780632f2ff15d1462000392578063352af39a14620003b757806336568abe14620003dc5780633c55593814620004015780633f4ba83a146200041957806340df8d8414620004315780634cba593a14620004565780634f1ef286146200047b5780634f3f4639146200049257806352d1902d14620004aa5780635a81a62614620004c25780635c975abb14620004f65780635e818619146200050e5780636cd5687814620005335780637fa3465714620005585780638127f465146200057d5780638456cb5914620005a45780639010d07c14620005bc57806391d1485414620005e157806392cf833f146200060657806395b6ef0c146200062b5780639d825bc51462000650578063a217fddf1462000668578063ad3cb1cc146200067f578063b289819c14620006b2578063c17e30bf14620006d7578063c2a1db7814620006fc578063c39409e11462000723578063ca15c873146200073b578063d547741f1462000760578063e63ab1e91462000785578063f72c0d8b14620007aa578063f85b4a9c14620007cf578063fd2fbd5214620007f4575b600080fd5b3480156200022a57600080fd5b506200024260008051602062002e1f83398151915281565b6040519081526020015b60405180910390f35b3480156200026257600080fd5b506200027a620002743660046200241c565b6200080b565b60405190151581526020016200024c565b3480156200029857600080fd5b50620002a362000839565b6040516200024c919062002448565b348015620002bf57600080fd5b50620002d7620002d136600462002479565b62000859565b005b348015620002e657600080fd5b50620002d7620002f836600462002529565b6200090b565b3480156200030b57600080fd5b506200027a6200031d36600462002479565b62000935565b3480156200033057600080fd5b50620002d76200034236600462002576565b62000967565b3480156200035557600080fd5b50620002426200036736600462002576565b62000999565b3480156200037a57600080fd5b50620002a36200038c36600462002479565b620009bb565b3480156200039f57600080fd5b50620002d7620003b136600462002590565b620009f3565b348015620003c457600080fd5b5062000242620003d636600462002529565b62000a1b565b348015620003e957600080fd5b50620002d7620003fb36600462002590565b62000aaa565b3480156200040e57600080fd5b506200024262000ae5565b3480156200042657600080fd5b50620002d762000afc565b3480156200043e57600080fd5b506200024260008051602062002eff83398151915281565b3480156200046357600080fd5b506200024260008051602062002e5f83398151915281565b620002d76200048c366004620025bf565b62000b24565b3480156200049f57600080fd5b50620002a362000b45565b348015620004b757600080fd5b506200024262000b65565b348015620004cf57600080fd5b50620004e7620004e136600462002576565b62000b85565b6040516200024c91906200267b565b3480156200050357600080fd5b506200027a62000c68565b3480156200051b57600080fd5b50620002d76200052d36600462002529565b62000c7f565b3480156200054057600080fd5b50620002d76200055236600462002479565b62000ca5565b3480156200056557600080fd5b506200024260008051602062002f1f83398151915281565b3480156200058a57600080fd5b506200059562000d4a565b6040516200024c919062002690565b348015620005b157600080fd5b50620002d762000d6b565b348015620005c957600080fd5b50620002a3620005db366004620026d6565b62000d90565b348015620005ee57600080fd5b506200027a6200060036600462002590565b62000dc2565b3480156200061357600080fd5b506200024260008051602062002e3f83398151915281565b3480156200063857600080fd5b50620002d76200064a366004620026f9565b62000dfa565b3480156200065d57600080fd5b50620002a362000fb8565b3480156200067557600080fd5b5062000242600081565b3480156200068c57600080fd5b50620004e7604051806040016040528060058152602001640352e302e360dc1b81525081565b348015620006bf57600080fd5b506200024260008051602062002e7f83398151915281565b348015620006e457600080fd5b50620002d7620006f636600462002479565b62000fd5565b3480156200070957600080fd5b50620007146200107e565b6040516200024c919062002771565b3480156200073057600080fd5b5062000242620011f3565b3480156200074857600080fd5b50620002426200075a36600462002576565b6200120a565b3480156200076d57600080fd5b50620002d76200077f36600462002590565b6200123a565b3480156200079257600080fd5b506200024260008051602062002edf83398151915281565b348015620007b757600080fd5b506200024260008051602062002e9f83398151915281565b348015620007dc57600080fd5b50620002d7620007ee36600462002576565b6200125c565b620002a362000805366004620027d9565b620012c2565b60006001600160e01b03198216635a05180f60e01b14806200083357506200083382620012f0565b92915050565b6000806200084662001327565b600201546001600160a01b031692915050565b60008051602062002e7f83398151915262000874816200134b565b816001600160a01b03163b600003620008ad57816040516337766f4360e11b8152600401620008a4919062002448565b60405180910390fd5b6000620008b962000fb8565b9050620008c68362001357565b826001600160a01b0316816001600160a01b03167fecd599290ada9c149ae0fb600bc6ada3c103a716eadb877b5341b7d298b62d9360405160405180910390a3505050565b60008051602062002e3f83398151915262000926816200134b565b620009318262001385565b5050565b6000806200094262001327565b6001600160a01b03909316600090815260059093016020525050604090205460ff1690565b60008051602062002e1f83398151915262000982816200134b565b60006200098e62001327565b600101929092555050565b600080620009a662001478565b60009384526020525050604090206001015490565b600080620009c862001327565b6001600160a01b03938416600090815260059091016020526040902054610100900490921692915050565b620009fe8262000999565b62000a09816200134b565b62000a1583836200149c565b50505050565b60008062000a28620014e5565b905062000a618360405160200162000a41919062002808565b60408051601f198184030181529190528051602090910120829062001509565b62000a7f5760405163162e926760e11b815260040160405180910390fd5b806003018360405162000a93919062002808565b908152602001604051809103902054915050919050565b6001600160a01b038116331462000ad45760405163334bd91960e11b815260040160405180910390fd5b62000ae0828262001517565b505050565b60008062000af262001327565b6003015492915050565b60008051602062002edf83398151915262000b17816200134b565b62000b2162001557565b50565b62000b2e620015b4565b62000b39826200165f565b6200093182826200167a565b60008062000b5262001327565b600401546001600160a01b031692915050565b600062000b7162001739565b5060008051602062002ebf83398151915290565b6060600062000b93620014e5565b905062000ba1818462001509565b62000bbf5760405163162e926760e11b815260040160405180910390fd5b60008381526002820160205260409020805462000bdc9062002826565b80601f016020809104026020016040519081016040528092919081815260200182805462000c0a9062002826565b801562000c5b5780601f1062000c2f5761010080835404028352916020019162000c5b565b820191906000526020600020905b81548152906001019060200180831162000c3d57829003601f168201915b5050505050915050919050565b60008062000c7562001783565b5460ff1692915050565b60008051602062002e3f83398151915262000c9a816200134b565b6200093182620017a7565b60008051602062002eff83398151915262000cc0816200134b565b6001600160a01b03821662000cec578160405163220b4f1160e11b8152600401620008a4919062002448565b600062000cf862000839565b905062000d058362001885565b826001600160a01b0316816001600160a01b03167f88bf70d4f3c446213b5064d7cfe95ec0ed196748f014c19a833117bac32468fd60405160405180910390a3505050565b6060600062000d58620014e5565b905062000d6581620018b6565b91505090565b60008051602062002edf83398151915262000d86816200134b565b62000b21620018c5565b60008062000d9d62001911565b600085815260208290526040902090915062000dba908462001935565b949350505050565b60008062000dcf62001478565b6000948552602090815260408086206001600160a01b03959095168652939052505090205460ff1690565b600062000e0662001943565b805490915060ff600160401b82041615906001600160401b031660008115801562000e2e5750825b90506000826001600160401b0316600114801562000e4b5750303b155b90508115801562000e5a575080155b1562000e795760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831562000ea357845460ff60401b1916600160401b1785555b62000ead62001967565b62000eb76200197b565b62000ec16200197b565b62000ece60008c6200149c565b5062000eea60008051602062002edf8339815191528b6200149c565b5062000f0660008051602062002e9f8339815191528a6200149c565b5062000f2260008051602062002e7f833981519152896200149c565b50600062000f2f62001327565b6002810180546001600160a01b0319166001600160a01b038b161790556003810188905568056bc75e2d6310000060019091015550831562000fab57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050505050565b60008062000fc562001327565b546001600160a01b031692915050565b60008051602062002e7f83398151915262000ff0816200134b565b816001600160a01b03163b60000362001020578160405163c9c10a6160e01b8152600401620008a4919062002448565b60006200102c62000b45565b9050620010398362001985565b826001600160a01b0316816001600160a01b03167f8752daf55fa0ccd919c149bbc809abaad4433f02ba7aa93ac6d5acfd2f8dc22c60405160405180910390a3505050565b606060006200108c620014e5565b905060006200109b82620018b6565b9050600081516001600160401b03811115620010bb57620010bb62002497565b604051908082528060200260200182016040528015620010f057816020015b6060815260200190600190039081620010da5790505b50905060005b8251811015620011eb578360020160008483815181106200111b576200111b62002862565b6020026020010151815260200190815260200160002080546200113e9062002826565b80601f01602080910402602001604051908101604052809291908181526020018280546200116c9062002826565b8015620011bd5780601f106200119157610100808354040283529160200191620011bd565b820191906000526020600020905b8154815290600101906020018083116200119f57829003601f168201915b5050505050828281518110620011d757620011d762002862565b6020908102919091010152600101620010f6565b509392505050565b6000806200120062001327565b6001015492915050565b6000806200121762001911565b60008481526020829052604090209091506200123390620019b6565b9392505050565b620012458262000999565b62001250816200134b565b62000a15838362001517565b60008051602062002e5f83398151915262001277816200134b565b60006200128362000ae5565b90506200129083620019c1565b604051839082907fc1fec27bbb8c533fedd3d449016c429341bfc0df21a9600e6162605e08f1c78f90600090a3505050565b6000620012ce620019d7565b620012d862001a10565b620012e4838362001a39565b90506200083362001c79565b60006001600160e01b03198216637965db0b60e01b14806200083357506301ffc9a760e01b6001600160e01b031983161462000833565b7f2b421af391835920c41e77b6810f6e715f5b713c17bc590f55de6a7d3912e80090565b62000b21813362001c8c565b60006200136362001327565b80546001600160a01b0319166001600160a01b03939093169290921790915550565b6000816040516020016200139a919062002808565b6040516020818303038152906040528051906020012090506000620013be620014e5565b90506000620013ce828462001cc9565b905080620013f35783604051633dad0df560e11b8152600401620008a491906200267b565b600083815260028301602052604090206200140f8582620028cc565b5082826003018560405162001425919062002808565b9081526020016040518091039020819055507fbad43a69707ac20dd539f3163b927e83baef6e967f2c95432129b1ded416645884846040516200146a92919062002998565b60405180910390a150505050565b7f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680090565b600080620014a962001911565b90506000620014b9858562001cd7565b9050801562000dba576000858152602083905260409020620014dc908562001d80565b50949350505050565b7f563e037355fff0507705f481e4b362e4c3996a3b57d07307deabfca3d816860090565b600062001233838362001d97565b6000806200152462001911565b9050600062001534858562001daf565b9050801562000dba576000858152602083905260409020620014dc908562001e2d565b6200156162001e44565b60006200156d62001783565b805460ff1916815590507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b604051620015a9919062002448565b60405180910390a150565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806200163e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166200163260008051602062002ebf833981519152546001600160a01b031690565b6001600160a01b031614155b156200165d5760405163703e46dd60e11b815260040160405180910390fd5b565b60008051602062002e9f83398151915262000931816200134b565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015620016d7575060408051601f3d908101601f19168201909252620016d491810190620029bc565b60015b620016f95781604051634c9c8ce360e01b8152600401620008a4919062002448565b60008051602062002ebf83398151915281146200172d57604051632a87526960e21b815260048101829052602401620008a4565b62000ae0838362001e6c565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146200165d5760405163703e46dd60e11b815260040160405180910390fd5b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330090565b600081604051602001620017bc919062002808565b6040516020818303038152906040528051906020012090506000620017e0620014e5565b90506000620017f0828462001ec9565b905080620018115760405163162e926760e11b815260040160405180910390fd5b600083815260028301602052604081206200182c91620023b4565b816003018460405162001840919062002808565b9081526020016040518091039020600090557f57158eaa7e642cefd761327d5cd6c147ddaad706ec257f90f4d8b59b3d365eb784846040516200146a92919062002998565b60006200189162001327565b60020180546001600160a01b0319166001600160a01b03939093169290921790915550565b60606000620012338362001ed7565b620018cf62001a10565b6000620018db62001783565b805460ff1916600117815590507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586200159a3390565b7fc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200090565b600062001233838362001f35565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0090565b6200197162001f62565b6200165d62001f8a565b6200165d62001f62565b60006200199162001327565b60040180546001600160a01b0319166001600160a01b03939093169290921790915550565b600062000833825490565b6000620019cd62001327565b6003019190915550565b6000620019e362001fab565b80549091506001190162001a0a57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b62001a1a62000c68565b156200165d5760405163d93c066560e01b815260040160405180910390fd5b60006001600160a01b03831662001a67578260405163715397cd60e11b8152600401620008a4919062002448565b600062001a73620011f3565b90508034101562001aa1576040516353f01c6360e11b815260048101829052346024820152604401620008a4565b600062001aad62000fb8565b9050806001600160a01b03163b60000362001adf57806040516337766f4360e11b8152600401620008a4919062002448565b600062001aeb62000b45565b9050806001600160a01b03163b60000362001b1d578060405163c9c10a6160e01b8152600401620008a4919062002448565b60008260405162001b2e90620023f3565b6001600160a01b039091168152604060208201819052600090820152606001604051809103906000f08015801562001b6a573d6000803e3d6000fd5b506040516333e1a22360e01b81523060048201526001600160a01b0384811660248301526044820187905289811660648301528881166084830152919250908216906333e1a2239060a401600060405180830381600087803b15801562001bd057600080fd5b505af115801562001be5573d6000803e3d6000fd5b5050604080518082019091526001815233602082015262001c0a925083915062001fcf565b62001c2560008051602062002f1f833981519152826200149c565b5062001c3b6001600160a01b0382163462002032565b6040516001600160a01b038216907f22de16ef21e3a33810fbcaf0e737ab9c9e2854fa565d8535041456c789afcd9390600090a29695505050505050565b600062001c8562001fab565b6001905550565b62001c98828262000dc2565b620009315760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401620008a4565b6000620012338383620020cf565b60008062001ce462001478565b905062001cf2848462000dc2565b62001d75576000848152602082815260408083206001600160a01b03871684529091529020805460ff1916600117905562001d2a3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600191505062000833565b600091505062000833565b600062001233836001600160a01b038416620020cf565b60009081526001919091016020526040902054151590565b60008062001dbc62001478565b905062001dca848462000dc2565b1562001d75576000848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4600191505062000833565b600062001233836001600160a01b0384166200211e565b62001e4e62000c68565b6200165d57604051638dfc202b60e01b815260040160405180910390fd5b62001e778262002217565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a280511562001ebf5762000ae0828262002277565b62000931620022f3565b60006200123383836200211e565b60608160000180548060200260200160405190810160405280929190818152602001828054801562001f2957602002820191906000526020600020905b81548152602001906001019080831162001f14575b50505050509050919050565b600082600001828154811062001f4f5762001f4f62002862565b9060005260206000200154905092915050565b62001f6c62002313565b6200165d57604051631afcd79f60e31b815260040160405180910390fd5b62001f9462001f62565b600062001fa062001783565b805460ff1916905550565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b600062001fdb62001327565b6001600160a01b03938416600090815260059091016020908152604090912083518154929094015190941661010002610100600160a81b0319931515939093166001600160a81b0319909116179190911790915550565b8047101562002058573060405163cd78605960e01b8152600401620008a4919062002448565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114620020a7576040519150601f19603f3d011682016040523d82523d6000602084013e620020ac565b606091505b505090508062000ae057604051630a12f52160e11b815260040160405180910390fd5b6000620020dd838362001d97565b620021155750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000833565b50600062000833565b6000818152600183016020526040812054801562001d7557600062002145600183620029d6565b85549091506000906200215b90600190620029d6565b9050808214620021c75760008660000182815481106200217f576200217f62002862565b9060005260206000200154905080876000018481548110620021a557620021a562002862565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620021db57620021db620029f8565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000833565b806001600160a01b03163b600003620022475780604051634c9c8ce360e01b8152600401620008a4919062002448565b60008051602062002ebf83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b03168460405162002296919062002808565b600060405180830381855af49150503d8060008114620022d3576040519150601f19603f3d011682016040523d82523d6000602084013e620022d8565b606091505b5091509150620022ea8583836200232f565b95945050505050565b34156200165d5760405163b398979f60e01b815260040160405180910390fd5b60006200231f62001943565b54600160401b900460ff16919050565b606082620023485762002342826200238a565b62001233565b81511580156200236057506001600160a01b0384163b155b15620023835783604051639996b31560e01b8152600401620008a4919062002448565b5092915050565b8051156200239b5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b508054620023c29062002826565b6000825580601f10620023d3575050565b601f01602090049060005260206000209081019062000b21919062002401565b6104108062002a0f83390190565b5b8082111562002418576000815560010162002402565b5090565b6000602082840312156200242f57600080fd5b81356001600160e01b0319811681146200123357600080fd5b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146200247457600080fd5b919050565b6000602082840312156200248c57600080fd5b62001233826200245c565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115620024ca57620024ca62002497565b604051601f8501601f19908116603f01168101908282118183101715620024f557620024f562002497565b816040528093508581528686860111156200250f57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156200253c57600080fd5b81356001600160401b038111156200255357600080fd5b8201601f810184136200256557600080fd5b62000dba84823560208401620024ad565b6000602082840312156200258957600080fd5b5035919050565b60008060408385031215620025a457600080fd5b82359150620025b6602084016200245c565b90509250929050565b60008060408385031215620025d357600080fd5b620025de836200245c565b915060208301356001600160401b03811115620025fa57600080fd5b8301601f810185136200260c57600080fd5b6200261d85823560208401620024ad565b9150509250929050565b60005b83811015620026445781810151838201526020016200262a565b50506000910152565b600081518084526200266781602086016020860162002627565b601f01601f19169290920160200192915050565b6020815260006200123360208301846200264d565b6020808252825182820181905260009190848201906040850190845b81811015620026ca57835183529284019291840191600101620026ac565b50909695505050505050565b60008060408385031215620026ea57600080fd5b50508035926020909101359150565b60008060008060008060c087890312156200271357600080fd5b6200271e876200245c565b95506200272e602088016200245c565b94506200273e604088016200245c565b93506200274e606088016200245c565b92506200275e608088016200245c565b915060a087013590509295509295509295565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015620027cc57603f19888603018452620027b98583516200264d565b945092850192908501906001016200279a565b5092979650505050505050565b60008060408385031215620027ed57600080fd5b620027f8836200245c565b9150620025b6602084016200245c565b600082516200281c81846020870162002627565b9190910192915050565b600181811c908216806200283b57607f821691505b6020821081036200285c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f82111562000ae0576000816000526020600020601f850160051c81016020861015620028a35750805b601f850160051c820191505b81811015620028c457828155600101620028af565b505050505050565b81516001600160401b03811115620028e857620028e862002497565b6200290081620028f9845462002826565b8462002878565b602080601f8311600181146200293857600084156200291f5750858301515b600019600386901b1c1916600185901b178555620028c4565b600085815260208120601f198616915b82811015620029695788860151825594840194600190910190840162002948565b5085821015620029885787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000620029ad60408301856200264d565b90508260208301529392505050565b600060208284031215620029cf57600080fd5b5051919050565b818103818111156200083357634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfe60806040526040516104103803806104108339810160408190526100229161025a565b61002c8282610033565b5050610358565b61003c82610092565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115610086576100818282610109565b505050565b61008e610180565b5050565b806001600160a01b03163b6000036100c85780604051634c9c8ce360e01b81526004016100bf9190610328565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051610126919061033c565b600060405180830381855af49150503d8060008114610161576040519150601f19603f3d011682016040523d82523d6000602084013e610166565b606091505b5090925090506101778583836101a1565b95945050505050565b341561019f5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b6576101b1826101f7565b6101f0565b81511580156101cd57506001600160a01b0384163b155b156101ed5783604051639996b31560e01b81526004016100bf9190610328565b50805b9392505050565b8051156102075780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b634e487b7160e01b600052604160045260246000fd5b60005b83811015610251578181015183820152602001610239565b50506000910152565b6000806040838503121561026d57600080fd5b82516001600160a01b038116811461028457600080fd5b60208401519092506001600160401b03808211156102a157600080fd5b818501915085601f8301126102b557600080fd5b8151818111156102c7576102c7610220565b604051601f8201601f19908116603f011681019083821181831017156102ef576102ef610220565b8160405282815288602084870101111561030857600080fd5b610319836020830160208801610236565b80955050505050509250929050565b6001600160a01b0391909116815260200190565b6000825161034e818460208701610236565b9190910192915050565b60aa806103666000396000f3fe6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220e704d381a2ce0387b276e1f01c87ad61ca30b2c8b219afb40e2ddf5bcf16086164736f6c6343000818003330f3325e23b502dce693b147d37de928d14dd5ab09bbc928fb79867329ac5b83dccfb718b018e1b06f849958baf67b0b252302f06a69871f72c5127ee92f659d349eec46d2c564a125684d1934a6120a70cc341d3a26d362e358a775e07dec176a42249708403f5ed28bf492facd11e85bc1054e6c27c155ed468f6ff4f7ecd0189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a819590c814c6d279357359f817d25adb06a7b9f6e493592b7d3b8bb268adb6764f22871c78b70c8896c7119179fc4e9b6f4cf323f8db6eadb7d79007d1e00c3fa26469706673582212204a7231d4ccf265a64d1dfd7340f540b8a8e32f79618d47ebe892505b2da3fab164736f6c63430008180033", + "deployedBytecode": "0x608060405260043610620002185760003560e01c806301601d2f146200021d57806301ffc9a714620002555780630470d3ac146200028b57806309766da214620002b25780630d6115d014620002d957806312b357b514620002fe5780631c2b3afc1462000323578063248a9ca314620003485780632cec1a06146200036d5780632f2ff15d1462000392578063352af39a14620003b757806336568abe14620003dc5780633c55593814620004015780633f4ba83a146200041957806340df8d8414620004315780634cba593a14620004565780634f1ef286146200047b5780634f3f4639146200049257806352d1902d14620004aa5780635a81a62614620004c25780635c975abb14620004f65780635e818619146200050e5780636cd5687814620005335780637fa3465714620005585780638127f465146200057d5780638456cb5914620005a45780639010d07c14620005bc57806391d1485414620005e157806392cf833f146200060657806395b6ef0c146200062b5780639d825bc51462000650578063a217fddf1462000668578063ad3cb1cc146200067f578063b289819c14620006b2578063c17e30bf14620006d7578063c2a1db7814620006fc578063c39409e11462000723578063ca15c873146200073b578063d547741f1462000760578063e63ab1e91462000785578063f72c0d8b14620007aa578063f85b4a9c14620007cf578063fd2fbd5214620007f4575b600080fd5b3480156200022a57600080fd5b506200024260008051602062002e1f83398151915281565b6040519081526020015b60405180910390f35b3480156200026257600080fd5b506200027a620002743660046200241c565b6200080b565b60405190151581526020016200024c565b3480156200029857600080fd5b50620002a362000839565b6040516200024c919062002448565b348015620002bf57600080fd5b50620002d7620002d136600462002479565b62000859565b005b348015620002e657600080fd5b50620002d7620002f836600462002529565b6200090b565b3480156200030b57600080fd5b506200027a6200031d36600462002479565b62000935565b3480156200033057600080fd5b50620002d76200034236600462002576565b62000967565b3480156200035557600080fd5b50620002426200036736600462002576565b62000999565b3480156200037a57600080fd5b50620002a36200038c36600462002479565b620009bb565b3480156200039f57600080fd5b50620002d7620003b136600462002590565b620009f3565b348015620003c457600080fd5b5062000242620003d636600462002529565b62000a1b565b348015620003e957600080fd5b50620002d7620003fb36600462002590565b62000aaa565b3480156200040e57600080fd5b506200024262000ae5565b3480156200042657600080fd5b50620002d762000afc565b3480156200043e57600080fd5b506200024260008051602062002eff83398151915281565b3480156200046357600080fd5b506200024260008051602062002e5f83398151915281565b620002d76200048c366004620025bf565b62000b24565b3480156200049f57600080fd5b50620002a362000b45565b348015620004b757600080fd5b506200024262000b65565b348015620004cf57600080fd5b50620004e7620004e136600462002576565b62000b85565b6040516200024c91906200267b565b3480156200050357600080fd5b506200027a62000c68565b3480156200051b57600080fd5b50620002d76200052d36600462002529565b62000c7f565b3480156200054057600080fd5b50620002d76200055236600462002479565b62000ca5565b3480156200056557600080fd5b506200024260008051602062002f1f83398151915281565b3480156200058a57600080fd5b506200059562000d4a565b6040516200024c919062002690565b348015620005b157600080fd5b50620002d762000d6b565b348015620005c957600080fd5b50620002a3620005db366004620026d6565b62000d90565b348015620005ee57600080fd5b506200027a6200060036600462002590565b62000dc2565b3480156200061357600080fd5b506200024260008051602062002e3f83398151915281565b3480156200063857600080fd5b50620002d76200064a366004620026f9565b62000dfa565b3480156200065d57600080fd5b50620002a362000fb8565b3480156200067557600080fd5b5062000242600081565b3480156200068c57600080fd5b50620004e7604051806040016040528060058152602001640352e302e360dc1b81525081565b348015620006bf57600080fd5b506200024260008051602062002e7f83398151915281565b348015620006e457600080fd5b50620002d7620006f636600462002479565b62000fd5565b3480156200070957600080fd5b50620007146200107e565b6040516200024c919062002771565b3480156200073057600080fd5b5062000242620011f3565b3480156200074857600080fd5b50620002426200075a36600462002576565b6200120a565b3480156200076d57600080fd5b50620002d76200077f36600462002590565b6200123a565b3480156200079257600080fd5b506200024260008051602062002edf83398151915281565b348015620007b757600080fd5b506200024260008051602062002e9f83398151915281565b348015620007dc57600080fd5b50620002d7620007ee36600462002576565b6200125c565b620002a362000805366004620027d9565b620012c2565b60006001600160e01b03198216635a05180f60e01b14806200083357506200083382620012f0565b92915050565b6000806200084662001327565b600201546001600160a01b031692915050565b60008051602062002e7f83398151915262000874816200134b565b816001600160a01b03163b600003620008ad57816040516337766f4360e11b8152600401620008a4919062002448565b60405180910390fd5b6000620008b962000fb8565b9050620008c68362001357565b826001600160a01b0316816001600160a01b03167fecd599290ada9c149ae0fb600bc6ada3c103a716eadb877b5341b7d298b62d9360405160405180910390a3505050565b60008051602062002e3f83398151915262000926816200134b565b620009318262001385565b5050565b6000806200094262001327565b6001600160a01b03909316600090815260059093016020525050604090205460ff1690565b60008051602062002e1f83398151915262000982816200134b565b60006200098e62001327565b600101929092555050565b600080620009a662001478565b60009384526020525050604090206001015490565b600080620009c862001327565b6001600160a01b03938416600090815260059091016020526040902054610100900490921692915050565b620009fe8262000999565b62000a09816200134b565b62000a1583836200149c565b50505050565b60008062000a28620014e5565b905062000a618360405160200162000a41919062002808565b60408051601f198184030181529190528051602090910120829062001509565b62000a7f5760405163162e926760e11b815260040160405180910390fd5b806003018360405162000a93919062002808565b908152602001604051809103902054915050919050565b6001600160a01b038116331462000ad45760405163334bd91960e11b815260040160405180910390fd5b62000ae0828262001517565b505050565b60008062000af262001327565b6003015492915050565b60008051602062002edf83398151915262000b17816200134b565b62000b2162001557565b50565b62000b2e620015b4565b62000b39826200165f565b6200093182826200167a565b60008062000b5262001327565b600401546001600160a01b031692915050565b600062000b7162001739565b5060008051602062002ebf83398151915290565b6060600062000b93620014e5565b905062000ba1818462001509565b62000bbf5760405163162e926760e11b815260040160405180910390fd5b60008381526002820160205260409020805462000bdc9062002826565b80601f016020809104026020016040519081016040528092919081815260200182805462000c0a9062002826565b801562000c5b5780601f1062000c2f5761010080835404028352916020019162000c5b565b820191906000526020600020905b81548152906001019060200180831162000c3d57829003601f168201915b5050505050915050919050565b60008062000c7562001783565b5460ff1692915050565b60008051602062002e3f83398151915262000c9a816200134b565b6200093182620017a7565b60008051602062002eff83398151915262000cc0816200134b565b6001600160a01b03821662000cec578160405163220b4f1160e11b8152600401620008a4919062002448565b600062000cf862000839565b905062000d058362001885565b826001600160a01b0316816001600160a01b03167f88bf70d4f3c446213b5064d7cfe95ec0ed196748f014c19a833117bac32468fd60405160405180910390a3505050565b6060600062000d58620014e5565b905062000d6581620018b6565b91505090565b60008051602062002edf83398151915262000d86816200134b565b62000b21620018c5565b60008062000d9d62001911565b600085815260208290526040902090915062000dba908462001935565b949350505050565b60008062000dcf62001478565b6000948552602090815260408086206001600160a01b03959095168652939052505090205460ff1690565b600062000e0662001943565b805490915060ff600160401b82041615906001600160401b031660008115801562000e2e5750825b90506000826001600160401b0316600114801562000e4b5750303b155b90508115801562000e5a575080155b1562000e795760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831562000ea357845460ff60401b1916600160401b1785555b62000ead62001967565b62000eb76200197b565b62000ec16200197b565b62000ece60008c6200149c565b5062000eea60008051602062002edf8339815191528b6200149c565b5062000f0660008051602062002e9f8339815191528a6200149c565b5062000f2260008051602062002e7f833981519152896200149c565b50600062000f2f62001327565b6002810180546001600160a01b0319166001600160a01b038b161790556003810188905568056bc75e2d6310000060019091015550831562000fab57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050505050565b60008062000fc562001327565b546001600160a01b031692915050565b60008051602062002e7f83398151915262000ff0816200134b565b816001600160a01b03163b60000362001020578160405163c9c10a6160e01b8152600401620008a4919062002448565b60006200102c62000b45565b9050620010398362001985565b826001600160a01b0316816001600160a01b03167f8752daf55fa0ccd919c149bbc809abaad4433f02ba7aa93ac6d5acfd2f8dc22c60405160405180910390a3505050565b606060006200108c620014e5565b905060006200109b82620018b6565b9050600081516001600160401b03811115620010bb57620010bb62002497565b604051908082528060200260200182016040528015620010f057816020015b6060815260200190600190039081620010da5790505b50905060005b8251811015620011eb578360020160008483815181106200111b576200111b62002862565b6020026020010151815260200190815260200160002080546200113e9062002826565b80601f01602080910402602001604051908101604052809291908181526020018280546200116c9062002826565b8015620011bd5780601f106200119157610100808354040283529160200191620011bd565b820191906000526020600020905b8154815290600101906020018083116200119f57829003601f168201915b5050505050828281518110620011d757620011d762002862565b6020908102919091010152600101620010f6565b509392505050565b6000806200120062001327565b6001015492915050565b6000806200121762001911565b60008481526020829052604090209091506200123390620019b6565b9392505050565b620012458262000999565b62001250816200134b565b62000a15838362001517565b60008051602062002e5f83398151915262001277816200134b565b60006200128362000ae5565b90506200129083620019c1565b604051839082907fc1fec27bbb8c533fedd3d449016c429341bfc0df21a9600e6162605e08f1c78f90600090a3505050565b6000620012ce620019d7565b620012d862001a10565b620012e4838362001a39565b90506200083362001c79565b60006001600160e01b03198216637965db0b60e01b14806200083357506301ffc9a760e01b6001600160e01b031983161462000833565b7f2b421af391835920c41e77b6810f6e715f5b713c17bc590f55de6a7d3912e80090565b62000b21813362001c8c565b60006200136362001327565b80546001600160a01b0319166001600160a01b03939093169290921790915550565b6000816040516020016200139a919062002808565b6040516020818303038152906040528051906020012090506000620013be620014e5565b90506000620013ce828462001cc9565b905080620013f35783604051633dad0df560e11b8152600401620008a491906200267b565b600083815260028301602052604090206200140f8582620028cc565b5082826003018560405162001425919062002808565b9081526020016040518091039020819055507fbad43a69707ac20dd539f3163b927e83baef6e967f2c95432129b1ded416645884846040516200146a92919062002998565b60405180910390a150505050565b7f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680090565b600080620014a962001911565b90506000620014b9858562001cd7565b9050801562000dba576000858152602083905260409020620014dc908562001d80565b50949350505050565b7f563e037355fff0507705f481e4b362e4c3996a3b57d07307deabfca3d816860090565b600062001233838362001d97565b6000806200152462001911565b9050600062001534858562001daf565b9050801562000dba576000858152602083905260409020620014dc908562001e2d565b6200156162001e44565b60006200156d62001783565b805460ff1916815590507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b604051620015a9919062002448565b60405180910390a150565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806200163e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166200163260008051602062002ebf833981519152546001600160a01b031690565b6001600160a01b031614155b156200165d5760405163703e46dd60e11b815260040160405180910390fd5b565b60008051602062002e9f83398151915262000931816200134b565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015620016d7575060408051601f3d908101601f19168201909252620016d491810190620029bc565b60015b620016f95781604051634c9c8ce360e01b8152600401620008a4919062002448565b60008051602062002ebf83398151915281146200172d57604051632a87526960e21b815260048101829052602401620008a4565b62000ae0838362001e6c565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146200165d5760405163703e46dd60e11b815260040160405180910390fd5b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330090565b600081604051602001620017bc919062002808565b6040516020818303038152906040528051906020012090506000620017e0620014e5565b90506000620017f0828462001ec9565b905080620018115760405163162e926760e11b815260040160405180910390fd5b600083815260028301602052604081206200182c91620023b4565b816003018460405162001840919062002808565b9081526020016040518091039020600090557f57158eaa7e642cefd761327d5cd6c147ddaad706ec257f90f4d8b59b3d365eb784846040516200146a92919062002998565b60006200189162001327565b60020180546001600160a01b0319166001600160a01b03939093169290921790915550565b60606000620012338362001ed7565b620018cf62001a10565b6000620018db62001783565b805460ff1916600117815590507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586200159a3390565b7fc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200090565b600062001233838362001f35565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0090565b6200197162001f62565b6200165d62001f8a565b6200165d62001f62565b60006200199162001327565b60040180546001600160a01b0319166001600160a01b03939093169290921790915550565b600062000833825490565b6000620019cd62001327565b6003019190915550565b6000620019e362001fab565b80549091506001190162001a0a57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b62001a1a62000c68565b156200165d5760405163d93c066560e01b815260040160405180910390fd5b60006001600160a01b03831662001a67578260405163715397cd60e11b8152600401620008a4919062002448565b600062001a73620011f3565b90508034101562001aa1576040516353f01c6360e11b815260048101829052346024820152604401620008a4565b600062001aad62000fb8565b9050806001600160a01b03163b60000362001adf57806040516337766f4360e11b8152600401620008a4919062002448565b600062001aeb62000b45565b9050806001600160a01b03163b60000362001b1d578060405163c9c10a6160e01b8152600401620008a4919062002448565b60008260405162001b2e90620023f3565b6001600160a01b039091168152604060208201819052600090820152606001604051809103906000f08015801562001b6a573d6000803e3d6000fd5b506040516333e1a22360e01b81523060048201526001600160a01b0384811660248301526044820187905289811660648301528881166084830152919250908216906333e1a2239060a401600060405180830381600087803b15801562001bd057600080fd5b505af115801562001be5573d6000803e3d6000fd5b5050604080518082019091526001815233602082015262001c0a925083915062001fcf565b62001c2560008051602062002f1f833981519152826200149c565b5062001c3b6001600160a01b0382163462002032565b6040516001600160a01b038216907f22de16ef21e3a33810fbcaf0e737ab9c9e2854fa565d8535041456c789afcd9390600090a29695505050505050565b600062001c8562001fab565b6001905550565b62001c98828262000dc2565b620009315760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401620008a4565b6000620012338383620020cf565b60008062001ce462001478565b905062001cf2848462000dc2565b62001d75576000848152602082815260408083206001600160a01b03871684529091529020805460ff1916600117905562001d2a3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600191505062000833565b600091505062000833565b600062001233836001600160a01b038416620020cf565b60009081526001919091016020526040902054151590565b60008062001dbc62001478565b905062001dca848462000dc2565b1562001d75576000848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4600191505062000833565b600062001233836001600160a01b0384166200211e565b62001e4e62000c68565b6200165d57604051638dfc202b60e01b815260040160405180910390fd5b62001e778262002217565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a280511562001ebf5762000ae0828262002277565b62000931620022f3565b60006200123383836200211e565b60608160000180548060200260200160405190810160405280929190818152602001828054801562001f2957602002820191906000526020600020905b81548152602001906001019080831162001f14575b50505050509050919050565b600082600001828154811062001f4f5762001f4f62002862565b9060005260206000200154905092915050565b62001f6c62002313565b6200165d57604051631afcd79f60e31b815260040160405180910390fd5b62001f9462001f62565b600062001fa062001783565b805460ff1916905550565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b600062001fdb62001327565b6001600160a01b03938416600090815260059091016020908152604090912083518154929094015190941661010002610100600160a81b0319931515939093166001600160a81b0319909116179190911790915550565b8047101562002058573060405163cd78605960e01b8152600401620008a4919062002448565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114620020a7576040519150601f19603f3d011682016040523d82523d6000602084013e620020ac565b606091505b505090508062000ae057604051630a12f52160e11b815260040160405180910390fd5b6000620020dd838362001d97565b620021155750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000833565b50600062000833565b6000818152600183016020526040812054801562001d7557600062002145600183620029d6565b85549091506000906200215b90600190620029d6565b9050808214620021c75760008660000182815481106200217f576200217f62002862565b9060005260206000200154905080876000018481548110620021a557620021a562002862565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620021db57620021db620029f8565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000833565b806001600160a01b03163b600003620022475780604051634c9c8ce360e01b8152600401620008a4919062002448565b60008051602062002ebf83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b03168460405162002296919062002808565b600060405180830381855af49150503d8060008114620022d3576040519150601f19603f3d011682016040523d82523d6000602084013e620022d8565b606091505b5091509150620022ea8583836200232f565b95945050505050565b34156200165d5760405163b398979f60e01b815260040160405180910390fd5b60006200231f62001943565b54600160401b900460ff16919050565b606082620023485762002342826200238a565b62001233565b81511580156200236057506001600160a01b0384163b155b15620023835783604051639996b31560e01b8152600401620008a4919062002448565b5092915050565b8051156200239b5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b508054620023c29062002826565b6000825580601f10620023d3575050565b601f01602090049060005260206000209081019062000b21919062002401565b6104108062002a0f83390190565b5b8082111562002418576000815560010162002402565b5090565b6000602082840312156200242f57600080fd5b81356001600160e01b0319811681146200123357600080fd5b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146200247457600080fd5b919050565b6000602082840312156200248c57600080fd5b62001233826200245c565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115620024ca57620024ca62002497565b604051601f8501601f19908116603f01168101908282118183101715620024f557620024f562002497565b816040528093508581528686860111156200250f57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156200253c57600080fd5b81356001600160401b038111156200255357600080fd5b8201601f810184136200256557600080fd5b62000dba84823560208401620024ad565b6000602082840312156200258957600080fd5b5035919050565b60008060408385031215620025a457600080fd5b82359150620025b6602084016200245c565b90509250929050565b60008060408385031215620025d357600080fd5b620025de836200245c565b915060208301356001600160401b03811115620025fa57600080fd5b8301601f810185136200260c57600080fd5b6200261d85823560208401620024ad565b9150509250929050565b60005b83811015620026445781810151838201526020016200262a565b50506000910152565b600081518084526200266781602086016020860162002627565b601f01601f19169290920160200192915050565b6020815260006200123360208301846200264d565b6020808252825182820181905260009190848201906040850190845b81811015620026ca57835183529284019291840191600101620026ac565b50909695505050505050565b60008060408385031215620026ea57600080fd5b50508035926020909101359150565b60008060008060008060c087890312156200271357600080fd5b6200271e876200245c565b95506200272e602088016200245c565b94506200273e604088016200245c565b93506200274e606088016200245c565b92506200275e608088016200245c565b915060a087013590509295509295509295565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015620027cc57603f19888603018452620027b98583516200264d565b945092850192908501906001016200279a565b5092979650505050505050565b60008060408385031215620027ed57600080fd5b620027f8836200245c565b9150620025b6602084016200245c565b600082516200281c81846020870162002627565b9190910192915050565b600181811c908216806200283b57607f821691505b6020821081036200285c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f82111562000ae0576000816000526020600020601f850160051c81016020861015620028a35750805b601f850160051c820191505b81811015620028c457828155600101620028af565b505050505050565b81516001600160401b03811115620028e857620028e862002497565b6200290081620028f9845462002826565b8462002878565b602080601f8311600181146200293857600084156200291f5750858301515b600019600386901b1c1916600185901b178555620028c4565b600085815260208120601f198616915b82811015620029695788860151825594840194600190910190840162002948565b5085821015620029885787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000620029ad60408301856200264d565b90508260208301529392505050565b600060208284031215620029cf57600080fd5b5051919050565b818103818111156200083357634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfe60806040526040516104103803806104108339810160408190526100229161025a565b61002c8282610033565b5050610358565b61003c82610092565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115610086576100818282610109565b505050565b61008e610180565b5050565b806001600160a01b03163b6000036100c85780604051634c9c8ce360e01b81526004016100bf9190610328565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051610126919061033c565b600060405180830381855af49150503d8060008114610161576040519150601f19603f3d011682016040523d82523d6000602084013e610166565b606091505b5090925090506101778583836101a1565b95945050505050565b341561019f5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b6576101b1826101f7565b6101f0565b81511580156101cd57506001600160a01b0384163b155b156101ed5783604051639996b31560e01b81526004016100bf9190610328565b50805b9392505050565b8051156102075780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b634e487b7160e01b600052604160045260246000fd5b60005b83811015610251578181015183820152602001610239565b50506000910152565b6000806040838503121561026d57600080fd5b82516001600160a01b038116811461028457600080fd5b60208401519092506001600160401b03808211156102a157600080fd5b818501915085601f8301126102b557600080fd5b8151818111156102c7576102c7610220565b604051601f8201601f19908116603f011681019083821181831017156102ef576102ef610220565b8160405282815288602084870101111561030857600080fd5b610319836020830160208801610236565b80955050505050509250929050565b6001600160a01b0391909116815260200190565b6000825161034e818460208701610236565b9190910192915050565b60aa806103666000396000f3fe6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220e704d381a2ce0387b276e1f01c87ad61ca30b2c8b219afb40e2ddf5bcf16086164736f6c6343000818003330f3325e23b502dce693b147d37de928d14dd5ab09bbc928fb79867329ac5b83dccfb718b018e1b06f849958baf67b0b252302f06a69871f72c5127ee92f659d349eec46d2c564a125684d1934a6120a70cc341d3a26d362e358a775e07dec176a42249708403f5ed28bf492facd11e85bc1054e6c27c155ed468f6ff4f7ecd0189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a819590c814c6d279357359f817d25adb06a7b9f6e493592b7d3b8bb268adb6764f22871c78b70c8896c7119179fc4e9b6f4cf323f8db6eadb7d79007d1e00c3fa26469706673582212204a7231d4ccf265a64d1dfd7340f540b8a8e32f79618d47ebe892505b2da3fab164736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/helpers/partnerConfigurationContext.tsx b/src/helpers/partnerConfigurationContext.tsx new file mode 100644 index 00000000..8825ba05 --- /dev/null +++ b/src/helpers/partnerConfigurationContext.tsx @@ -0,0 +1,393 @@ +import { ethers } from 'ethers' +import React, { createContext, useContext, useEffect, useReducer } from 'react' +import { usePartnerConfig } from './usePartnerConfig' +import { useSmartContract } from './useSmartContract' + +// Initial state +const initialState = { + stepsConfig: [ + { + step: 0, + title: 'Messenger configuration', + services: [], + paragraph: + 'This wizard will help you create and activate your Camino Messenger Account with Camino Messenger address. Once set up, your Camino Messenger address will be displayed on your partner detail page, enabling direct communication with other Camino Messenger users.', + distributor: { isDistributor: true, services: [] }, + }, + { + step: 1, + title: 'Supplier configuration', + type: 'supplier', + paragraph: + 'Configure services, set fees, and add specific details. Customize your setup by selecting or removing services below.', + isSupplier: false, + services: [], + }, + { + step: 2, + type: 'distributor', + title: 'Distributor configuration', + paragraph: + 'Configure wanted services. Customize your setup by selecting or removing services below.', + services: [], + isDistributor: false, + }, + { step: 3, title: 'Accepted currencies', isOffChain: false, isCam: false }, + { + step: 4, + title: 'Review data', + paragraph: + 'Please take a moment to review the data we got from you and check if everything is correct. If needed you can change them now or later in your Camino Messenger preferences', + }, + ], + balance: '0', + step: 0, + isAbleToCreateCMAccount: false, + registredServices: [], +} + +// Action types +export const actionTypes = { + ADD_SERVICE: 'ADD_SERVICE', + UPDATE_SUPPORTED_SERVICES: 'UPDATE_SUPPORTED_SERVICES', + UPDATE_WANTED_SERVICES: 'UPDATE_WANTED_SERVICES', + REMOVE_SERVICE: 'REMOVE_SERVICE', + UPDATE_STEP: 'UPDATE_STEP', + UPDATE_IS_SUPPLIER: 'UPDATE_IS_SUPPLIER', + ADD_CAPABILITIES: 'ADD_CAPABILITIES', + UPDATE_CAPABILITY: 'UPDATE_CAPABILITY', + UPDATE_RACK_RATES: 'UPDATE_RACK_RATES', + UPDATE_FEE: 'UPDATE_FEE', + UPDATE_IS_OFF_CHAIN: 'UPDATE_IS_OFF_CHAIN', + UPDATE_IS_CAM: 'UPDATE_IS_CAM', + UPDATE_IS_ABLE_TO_CREATE_MESSENGER_ACCOUNT: 'UPDATE_IS_ABLE_TO_CREATE_MESSENGER_ACCOUNT', + GET_ALL_REGISTRED_SERVICES: 'GET_ALL_REGISTRED_SERVICES', + UPDATE_BALANCE: 'UPDATE_BALANCE', + RESET_STATE: 'RESET_STATE', +} + +// Reducer function +export function reducer(state = initialState, action) { + switch (action.type) { + case actionTypes.ADD_SERVICE: { + const { step, newService } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === step + ? { + ...item, + services: [...item.services, newService], + } + : item, + ), + } + } + case actionTypes.RESET_STATE: + const { initialState } = action.payload + return { ...state, ...initialState } + case actionTypes.UPDATE_SUPPORTED_SERVICES: { + const { services } = action.payload + if (!services || services.length < 1) return state + let parsedServices = services[0].map((service, index) => { + return { + name: service, + fee: ethers.formatEther(services[1][index][0]), + rackRates: services[1][index][1], + capabilities: services[1][index][2], + } + }) + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === 1 + ? { + ...item, + isSupplier: parsedServices.length > 0 ? true : false, + services: parsedServices, + } + : item, + ), + } + } + + case actionTypes.UPDATE_WANTED_SERVICES: { + const { wantedServices } = action.payload + if (!wantedServices || wantedServices.length < 1) return state + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === 2 + ? { + ...item, + isDistributor: wantedServices.length > 0 ? true : false, + services: wantedServices.map(elem => { + return { name: elem } + }), + } + : item, + ), + } + } + + case actionTypes.REMOVE_SERVICE: { + const { step, serviceIndex } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === step + ? { + ...item, + services: item.services.filter((_, index) => index !== serviceIndex), + } + : item, + ), + } + } + + case actionTypes.UPDATE_IS_ABLE_TO_CREATE_MESSENGER_ACCOUNT: { + const { isAbleToCreateCMAccount } = action.payload + return { + ...state, + isAbleToCreateCMAccount, + } + } + + case actionTypes.UPDATE_STEP: { + const { step } = action.payload + return { + ...state, + step, + } + } + + case actionTypes.UPDATE_IS_OFF_CHAIN: { + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === state.step + ? { + ...item, + isOffChain: !state.stepsConfig[state.step].isOffChain, + } + : item, + ), + } + } + + case actionTypes.GET_ALL_REGISTRED_SERVICES: { + const { registredServices } = action.payload + return { + ...state, + registredServices, + } + } + + case actionTypes.UPDATE_IS_CAM: { + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === state.step + ? { + ...item, + isCam: !state.stepsConfig[state.step].isCam, + } + : item, + ), + } + } + + case actionTypes.UPDATE_IS_SUPPLIER: { + if (state.step === 2) { + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === state.step + ? { + ...item, + services: state.stepsConfig[state.step].isDistributor + ? [] + : item.services, + isDistributor: !state.stepsConfig[state.step].isDistributor, + } + : item, + ), + } + } + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === state.step + ? { + ...item, + services: state.stepsConfig[state.step].isSupplier + ? [] + : item.services, + isSupplier: !state.stepsConfig[state.step].isSupplier, + } + : item, + ), + } + } + + case actionTypes.UPDATE_RACK_RATES: { + const { step, serviceIndex } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map(item => + item.step === state.step + ? { + ...item, + services: item.services.map((service, sIndex) => + sIndex === serviceIndex + ? { + ...service, + rackRates: + !state.stepsConfig[step].services[serviceIndex] + .rackRates, + } + : service, + ), + } + : item, + ), + } + } + + case actionTypes.ADD_CAPABILITIES: { + const { step, serviceIndex } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map((item, index) => + index === step + ? { + ...item, + services: item.services.map((service, sIndex) => + sIndex === serviceIndex + ? { + ...service, + capabilities: [...service.capabilities, ''], + } + : service, + ), + } + : item, + ), + } + } + + case actionTypes.UPDATE_CAPABILITY: { + const { step, serviceIndex, capabilityIndex, newValue } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map((item, itemIndex) => + itemIndex === step + ? { + ...item, + services: item.services.map((service, sIndex) => + sIndex === serviceIndex + ? { + ...service, + capabilities: service.capabilities.map( + (capability, capIndex) => + capIndex === capabilityIndex + ? newValue + : capability, + ), + } + : service, + ), + } + : item, + ), + } + } + + case actionTypes.UPDATE_FEE: { + const { step, serviceIndex, newValue } = action.payload + return { + ...state, + stepsConfig: state.stepsConfig.map((item, itemIndex) => + itemIndex === step + ? { + ...item, + services: item.services.map((service, sIndex) => + sIndex === serviceIndex + ? { + ...service, + fee: newValue, + } + : service, + ), + } + : item, + ), + } + } + case actionTypes.UPDATE_BALANCE: { + const { newValue } = action.payload + return { + ...state, + balance: newValue, + } + } + + default: + return state + } +} + +// Create context +const PartnerConfigContext = createContext() + +// Context provider component +export const PartnerConfigurationProvider = ({ children }) => { + const [state, dispatch] = useReducer(reducer, initialState) + const partnerConfig = usePartnerConfig() + const { accountReadContract } = useSmartContract() + + useEffect(() => { + if (partnerConfig.account) { + partnerConfig.getAllServices().then(result => { + dispatch({ + type: actionTypes.GET_ALL_REGISTRED_SERVICES, + payload: { + registredServices: result, + }, + }) + }) + } + }, [partnerConfig.account]) + + useEffect(() => { + if (accountReadContract) { + partnerConfig.getSupportedServices().then(res => { + dispatch({ + type: actionTypes.UPDATE_SUPPORTED_SERVICES, + payload: { services: res }, + }) + }) + partnerConfig.getWantedServices().then(res => { + dispatch({ + type: actionTypes.UPDATE_WANTED_SERVICES, + payload: { wantedServices: res }, + }) + }) + } + }, [accountReadContract]) + + return ( + + {children} + + ) +} + +// Custom hook to use the Messenger context +export const usePartnerConfigurationContext = () => { + const context = useContext(PartnerConfigContext) + if (context === undefined) { + throw new Error('useMessengerContext must be used within a MessengerProvider') + } + return context +} diff --git a/src/helpers/usePartnerConfig.tsx b/src/helpers/usePartnerConfig.tsx new file mode 100644 index 00000000..df264c12 --- /dev/null +++ b/src/helpers/usePartnerConfig.tsx @@ -0,0 +1,329 @@ +import { ethers } from 'ethers' +import { useCallback, useEffect } from 'react' +import { useAppDispatch } from '../hooks/reduxHooks' +import { updateCMAcocuntContract } from '../redux/slices/partner' +import { useSmartContract } from './useSmartContract' + +export const usePartnerConfig = () => { + const { + readFromContract, + writeToContract, + account, + managerWriteContract, + setContractCMAccountAddress, + accountWriteContract, + managerReadContract, + wallet, + CMAccountCreated, + accountReadContract, + } = useSmartContract() + + const dispatch = useAppDispatch() + + async function CreateConfiguration(state) { + if (!account) { + console.error('Account is not initialized') + return + } + try { + let balance = ethers.parseEther(state.balance ? state.balance : '0') + let services = state.stepsConfig[1].services.map(elem => { + return { + ...elem, + fee: ethers.parseEther(elem.fee ? elem.fee : '0'), + capabilities: elem.capabilities.filter(item => item !== ''), + } + }) + let wantedServices = state.stepsConfig[2].services.map(elem => elem.name) + let isOffChainPayement = state.stepsConfig[3].isOffChain + let isCam = state.stepsConfig[3].isCam + + const tx = await writeToContract('manager', 'createCMAccount', account, account, { + value: balance, + }) + const event = tx.logs.find(log => { + try { + return managerWriteContract.interface.parseLog(log).name === 'CMAccountCreated' + } catch (e) { + return false + } + }) + + const parsedEvent = managerWriteContract.interface.parseLog(event) + const cmAccountAddress = parsedEvent.args.account + setContractCMAccountAddress(cmAccountAddress) + await CMAccountCreated( + { services, wantedServices, isOffChainPayement }, + cmAccountAddress, + ) + return tx + } catch (error) { + console.error(error) + throw error + } + } + + const getAllServices = useCallback(async () => { + if (!account) { + console.error('Account is not initialized') + return + } + + try { + const services = await readFromContract('manager', 'getAllRegisteredServiceNames') + return services + } catch (error) { + console.error('Error getting All Services:', error) + throw error + } + }, [account, readFromContract]) + + const getSupportedServices = useCallback(async () => { + if (!account) { + console.error('Account is not initialized') + return + } + + try { + const services = await readFromContract('account', 'getSupportedServices') + return services + } catch (error) { + console.error('Error getting Supported Services:', error) + throw error + } + }, [account, readFromContract]) + + const getWantedServices = useCallback(async () => { + if (!account) { + console.error('Account is not initialized') + return + } + + try { + const wantedServices = await readFromContract('account', 'getWantedServices') + return wantedServices + } catch (error) { + console.error('Error getting All Wanted Services:', error) + throw error + } + }, [account, readFromContract]) + + const getListOfBots = useCallback(async () => { + try { + const CHEQUE_OPERATOR_ROLE = await readFromContract('account', 'CHEQUE_OPERATOR_ROLE') + const roleMemberCount = await readFromContract( + 'account', + 'getRoleMemberCount', + CHEQUE_OPERATOR_ROLE, + ) + + const botPromises = [] + for (let i = 0; i < roleMemberCount; i++) { + botPromises.push(accountReadContract.getRoleMember(CHEQUE_OPERATOR_ROLE, i)) + } + + const bots = await Promise.all(botPromises) + return bots + } catch (error) { + throw error + } + }, [account, managerReadContract]) + + const isCMAccount = useCallback(async () => { + try { + const CMACCOUNT_ROLE = await readFromContract('manager', 'CMACCOUNT_ROLE') + const roleMemberCount = await readFromContract( + 'manager', + 'getRoleMemberCount', + CMACCOUNT_ROLE, + ) + let i = 0 + while (i < roleMemberCount) { + managerReadContract.getRoleMember(CMACCOUNT_ROLE, i).then(async role => { + readFromContract('manager', 'getCMAccountCreator', role).then(creator => { + if (creator === wallet.address) { + setContractCMAccountAddress(role) + dispatch(updateCMAcocuntContract(role)) + } + }) + }) + i++ + } + + return + } catch (error) { + throw error + } + }, [account, managerReadContract]) + + useEffect(() => { + isCMAccount() + }, [wallet]) + + const addServices = useCallback( + async services => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + for (const service of services) { + const tx = await accountWriteContract.addService( + service.name, + ethers.parseEther(service.fee ? service.fee : '0'), + service.rackRates, + service.capabilities.filter(item => item !== ''), + ) + const receipt = await tx.wait() + return receipt + } + } catch (error) { + console.error(error) + throw error + } + }, + [account, writeToContract], + ) + const removeServices = useCallback( + async services => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + for (const service of services) { + const tx = await accountWriteContract.removeService(service.name) + const receipt = await tx.wait() + return receipt + } + } catch (error) { + console.error(error) + throw error + } + }, + [account, writeToContract], + ) + + const addMessengerBot = useCallback( + async address => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const addMessengerBotTx = await accountWriteContract.addMessengerBot(address, 0n) + await addMessengerBotTx.wait() + return addMessengerBotTx + } catch (error) { + console.error(error) + throw error + } + }, + [account, accountWriteContract], + ) + + const removeMessengerBot = useCallback( + async address => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const removeMessengerBotTx = await accountWriteContract.removeMessengerBot(address) + await removeMessengerBotTx.wait() + return removeMessengerBotTx + } catch (error) { + console.error(error) + throw error + } + }, + [account, accountWriteContract], + ) + + const addWantedServices = useCallback( + async services => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const wantedServicesTx = await accountWriteContract.addWantedServices(services) + await wantedServicesTx.wait() + return wantedServicesTx + } catch (error) { + console.error(error) + throw error + } + }, + [account, accountWriteContract], + ) + const removeWantedServices = useCallback( + async services => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const wantedServicesTx = await accountWriteContract.removeWantedServices(services) + await wantedServicesTx.wait() + return wantedServicesTx + } catch (error) { + console.error(error) + throw error + } + }, + [account, writeToContract], + ) + + const setOffChainPaymentSupported = useCallback( + async value => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const tx = await accountWriteContract.setOffChainPaymentSupported(value) + return tx + } catch (error) { + console.error(error) + throw error + } + }, + [account, accountWriteContract], + ) + + const getOffChainPaymentSupported = useCallback(async () => { + if (!account) { + console.error('Account is not initialized') + return + } + try { + const offChainPaymentSupported = await readFromContract( + 'account', + 'offChainPaymentSupported', + ) + return offChainPaymentSupported + } catch (error) { + console.error(error) + throw error + } + }, [account, readFromContract]) + + return { + CreateConfiguration, + account, + removeWantedServices, + getOffChainPaymentSupported, + setOffChainPaymentSupported, + getWantedServices, + addWantedServices, + getSupportedServices, + addServices, + removeServices, + getAllServices, + isCMAccount, + addMessengerBot, + getListOfBots, + removeMessengerBot, + } +} diff --git a/src/helpers/useSmartContract.tsx b/src/helpers/useSmartContract.tsx new file mode 100644 index 00000000..eb7b19ab --- /dev/null +++ b/src/helpers/useSmartContract.tsx @@ -0,0 +1,179 @@ +import { ethers } from 'ethers' +import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react' +import store from 'wallet/store' +import { useAppSelector } from '../hooks/reduxHooks' +import { getActiveNetwork } from '../redux/slices/network' +import CMAccount from './CMAccountManagerModule#CMAccount.json' +import CMAccountManager from './ManagerProxyModule#CMAccountManager.json' + +const SmartContractContext = createContext(null) + +export const useSmartContract = () => useContext(SmartContractContext) + +type SmartContractProviderProps = { + children?: ReactNode +} + +export const SmartContractProvider: React.FC = ({ children }) => { + const [provider, setProvider] = useState(null) + const [managerReadContract, setManagerReadContract] = useState(null) + const [managerWriteContract, setManagerWriteContract] = useState(null) + const [accountReadContract, setAccountReadContract] = useState(null) + const [accountWriteContract, setAccountWriteContract] = useState(null) + const [wallet, setWallet] = useState(null) + const [account, setAccount] = useState(null) + const [contractCMAccountAddress, setContractCMAccountAddress] = useState('') + const auth = useAppSelector(state => state.appConfig.isAuth) + const contractCMAccountManagerAddress = '0xE5B2f76C778D082b07BDd7D51FFe83E3E055B47F' + + const CMAccountCreated = async (state, cmAccountAddress) => { + const accountWritableContract = new ethers.Contract(cmAccountAddress, CMAccount, wallet) + const accountReadOnlyContract = new ethers.Contract(cmAccountAddress, CMAccount, provider) + setContractCMAccountAddress(cmAccountAddress) + setAccountReadContract(accountReadOnlyContract) + setAccountWriteContract(accountWritableContract) + if (!account) { + console.error('Account is not initialized') + return { success: false, error: 'Account is not initialized' } + } + try { + for (const service of state.services) { + const tx = await accountWritableContract.addService( + service.name, + parseInt(service.fee), + service.rackRates, + service.capabilities, + ) + const receipt = await tx.wait() + } + + if (state.wantedServices.length > 0) { + const wantedServicesTx = await accountWritableContract.addWantedServices( + state.wantedServices, + ) + await wantedServicesTx.wait() + } + + const offChainPaymentTx = await accountWritableContract.setOffChainPaymentSupported( + state.isOffChainPayement, + ) + await offChainPaymentTx.wait() + + return { success: true, message: 'All operations completed successfully' } + } catch (error) { + console.error('Error in CMAccountCreated:', error) + return { success: false, error: error.message } + } + } + + const initializeCMAccountContract = async () => { + if (!provider) return + try { + const accountWritableContract = new ethers.Contract( + contractCMAccountAddress, + CMAccount, + wallet, + ) + const accountReadOnlyContract = new ethers.Contract( + contractCMAccountAddress, + CMAccount, + provider, + ) + setAccountReadContract(accountReadOnlyContract) + setAccountWriteContract(accountWritableContract) + } catch (error) { + console.error('User denied account access:', error) + } + } + const initializeEthers = async () => { + const selectedNetwork = store.getters['Network/selectedNetwork'] + const ethersProvider = new ethers.JsonRpcProvider( + `${selectedNetwork.protocol}://${selectedNetwork.ip}:${selectedNetwork.port}/ext/bc/C/rpc`, + ) + try { + const wallet = new ethers.Wallet(store.state.activeWallet?.ethKey, ethersProvider) + const managerWritableContract = new ethers.Contract( + contractCMAccountManagerAddress, + CMAccountManager.abi, + wallet, + ) + const managerReadOnlyContract = new ethers.Contract( + contractCMAccountManagerAddress, + CMAccountManager.abi, + ethersProvider, + ) + setWallet(wallet) + setProvider(ethersProvider) + setManagerReadContract(managerReadOnlyContract) + setManagerWriteContract(managerWritableContract) + setAccount(wallet.address) + } catch (error) { + console.error('User denied account access:', error) + } + } + const activeNetwork = useAppSelector(getActiveNetwork) + + useEffect(() => { + if (auth) initializeEthers() + }, [activeNetwork, auth]) + + useEffect(() => { + if (contractCMAccountAddress) initializeCMAccountContract() + }, [provider, contractCMAccountAddress]) + + const readFromContract = async ( + contractType: 'manager' | 'account', + method: string, + ...args: any[] + ) => { + const contract = contractType === 'manager' ? managerReadContract : accountReadContract + if (!contract) { + return + } + + try { + const result = await contract[method](...args) + return result + } catch (error) { + console.error(`Error reading from ${contractType} contract (method: ${method}):`, error) + throw error + } + } + + const writeToContract = async ( + contractType: 'manager' | 'account', + method: string, + ...args: any[] + ) => { + const contract = contractType === 'manager' ? managerWriteContract : accountWriteContract + if (!contract) { + return + } + + try { + const tx = await contract[method](...args) + const receipt = await tx.wait() + return receipt + } catch (error) { + console.error(`Error writing to ${contractType} contract (method: ${method}):`, error) + throw error + } + } + + const value = { + contractCMAccountAddress, + setContractCMAccountAddress, + wallet, + provider, + managerReadContract, + managerWriteContract, + accountReadContract, + accountWriteContract, + account, + readFromContract, + writeToContract, + CMAccountCreated, + } + + return {children} +} diff --git a/src/helpers/useWalletBalance.tsx b/src/helpers/useWalletBalance.tsx new file mode 100644 index 00000000..80fd289c --- /dev/null +++ b/src/helpers/useWalletBalance.tsx @@ -0,0 +1,38 @@ +import { ethers } from 'ethers' +import { useEffect, useState } from 'react' +import store from 'wallet/store' +import { useSmartContract } from './useSmartContract' +const useWalletBalance = () => { + const [balance, setBalance] = useState('') + const [balanceOfAnAddress, setBalanceOfAnAddress] = useState('') + const [error, setError] = useState(null) + const { provider } = useSmartContract() + + async function getBalanceOfAnAddress(address: string) { + const fetchedBalance = await provider.getBalance(address) + setBalanceOfAnAddress(ethers.formatEther(fetchedBalance)) + } + useEffect(() => { + const fetchBalance = async () => { + if (!provider) { + setBalance(null) + return + } + + try { + const fetchedBalance = await provider.getBalance( + '0x' + store.state.activeWallet.ethAddress, + ) + setBalance(ethers.formatEther(fetchedBalance)) + } catch (err) { + console.error('Error fetching balance:', err) + setError(err.message) + } + } + + fetchBalance() + }, [provider]) + return { balance, error, balanceOfAnAddress, getBalanceOfAnAddress } +} + +export default useWalletBalance diff --git a/src/layout/PartnersLayout.tsx b/src/layout/PartnersLayout.tsx index 467a7c32..de69b03f 100644 --- a/src/layout/PartnersLayout.tsx +++ b/src/layout/PartnersLayout.tsx @@ -1,51 +1,131 @@ -import { Box, Toolbar } from '@mui/material' +import { Box, Toolbar, Typography } from '@mui/material' -import React from 'react' -import { Outlet } from 'react-router' +import React, { useEffect } from 'react' +import { Navigate, Outlet, useNavigate } from 'react-router' +import store from 'wallet/store' +import { PartnerConfigurationProvider } from '../helpers/partnerConfigurationContext' +import { SmartContractProvider } from '../helpers/useSmartContract' +import { useAppSelector } from '../hooks/reduxHooks' +import { useIsPartnerQuery } from '../redux/services/partners' +import { getWalletName } from '../redux/slices/app-config' import Links from '../views/settings/Links' -const PartnersLayout = () => { +const ClaimProfile = () => { return ( - theme.palette.background.paper, - flexGrow: 1, - p: '1.5rem', - zIndex: 9, - position: 'fixed', - top: '65px', - width: '100vw', - height: '61px', - display: 'flex', - justifyContent: 'center', - right: 0, - }} - > - - - theme.customWidth.layoutMaxWitdh, - }} - > - - + Claim a profile + + Get in touch with the Camino Foundation to claim a Partner page and be then be able + to edit it and to create/manage a Camino Messenger configuration + ) } +const PartnersLayout = () => { + const path = window.location.pathname + const { data, isLoading } = useIsPartnerQuery({ + pChainAddress: 'P-camino1avxc8uyqzf9hzwa9eacgg2x8y473j85sd2jwdt', + }) + const walletName = useAppSelector(getWalletName) + const navigate = useNavigate() + useEffect(() => { + if ( + walletName && + path.includes('partners/messenger-configuration') && + store.state.activeWallet?.type === 'multisig' + ) { + navigate('/') + } + }, [walletName]) + if (isLoading) return <> + if (path.includes('partners/messenger-configuration') && !store.state.isAuth) { + return + } + return ( + + + + theme.palette.background.paper, + flexGrow: 1, + p: '1.5rem', + zIndex: 9, + position: 'fixed', + top: '65px', + width: '100vw', + height: '61px', + display: 'flex', + justifyContent: 'center', + right: 0, + }} + > + + + {path.includes('partners/messenger-configuration') && !!data && ( + theme.palette.background.paper, + flexGrow: 1, + p: '1.5rem', + zIndex: 9, + position: 'fixed', + top: '129px', + width: '100vw', + height: '61px', + display: 'flex', + justifyContent: 'center', + right: 0, + }} + > + + + )} + theme.customWidth.layoutMaxWitdh, + mb: '2rem', + }} + > + {!path.includes('partners/messenger-configuration') || + (path.includes('partners/messenger-configuration') && !!data) ? ( + + ) : ( + + )} + + + + + ) +} + export default PartnersLayout diff --git a/src/layout/RoutesSuite.tsx b/src/layout/RoutesSuite.tsx index 575e5086..f9eb1f11 100644 --- a/src/layout/RoutesSuite.tsx +++ b/src/layout/RoutesSuite.tsx @@ -13,8 +13,12 @@ import ExplorerApp from '../views/explorer/ExplorerApp' import LandingPage from '../views/landing/LandingPage' import LoginPage from '../views/login/LoginPage' import Partners from '../views/partners' +import ConfigurDistrubitor from '../views/partners/ConfigurDistrubitor' +import ConfigurSupplier from '../views/partners/ConfigurSupplier' +import Overreview from '../views/partners/Configuration' import CreatedOffers from '../views/partners/CreatedOffers' import Foundation from '../views/partners/Foundation' +import ManageBots from '../views/partners/ManageBots' import Partner from '../views/partners/Partner' import MultisigWallet from '../views/settings/MultisigWallet' import VerifyWallet from '../views/settings/VerifyWallet' @@ -110,7 +114,15 @@ export default function RoutesSuite() { }> } /> }> + + } /> + } /> + } /> + } /> + } /> + + }> } /> } /> }> diff --git a/src/redux/services/partners.ts b/src/redux/services/partners.ts index 50a9de24..d19509f6 100644 --- a/src/redux/services/partners.ts +++ b/src/redux/services/partners.ts @@ -45,7 +45,18 @@ export const partnersApi = createApi({ return response.data[0] }, }), + isPartner: build.query({ + query: ({ pChainAddress }) => { + let query = + '?populate=*&sort[0]=companyName:asc&pagination[page]=1&pagination[pageSize]=12' + query += `&filters[pChainAddress][$contains]=${pChainAddress}` + return query + }, + transformResponse: (response: PartnersResponseType) => { + return response.data[0] + }, + }), }), }) -export const { useListPartnersQuery, useFetchPartnerDataQuery } = partnersApi +export const { useListPartnersQuery, useFetchPartnerDataQuery, useIsPartnerQuery } = partnersApi diff --git a/src/redux/store.ts b/src/redux/store.ts index 421f2315..30f562c2 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -1,8 +1,8 @@ -import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit' +import { Action, configureStore, ThunkAction } from '@reduxjs/toolkit' +import { partnersApi } from './services/partners' import appConfigReducer from './slices/app-config' -import themeReducer from './slices/theme' import network from './slices/network' -import { partnersApi } from './services/partners' +import themeReducer from './slices/theme' export type AppDispatch = typeof store.dispatch export type RootState = ReturnType export type AppThunk = ThunkAction< diff --git a/src/views/partners/ConfigurDistrubitor.tsx b/src/views/partners/ConfigurDistrubitor.tsx new file mode 100644 index 00000000..48ed588d --- /dev/null +++ b/src/views/partners/ConfigurDistrubitor.tsx @@ -0,0 +1,231 @@ +import { Box, Divider, FormControl, MenuItem, Select, Typography } from '@mui/material' +import React, { useEffect, useReducer, useState } from 'react' +import MainButton from '../../components/MainButton' +import { + actionTypes, + reducer, + usePartnerConfigurationContext, +} from '../../helpers/partnerConfigurationContext' +import { usePartnerConfig } from '../../helpers/usePartnerConfig' +import { Configuration } from './Configuration' + +const ConfigurDistrubitor = () => { + const { removeWantedServices, addWantedServices, getWantedServices } = usePartnerConfig() + const { state, dispatch } = usePartnerConfigurationContext() + const [distrubitorState, dispatchDistrubitorState] = useReducer(reducer, { ...state, step: 2 }) + const [editing, setEditing] = useState(false) + const [loading, setLoading] = useState(false) + + const handleChange = event => { + addService(event.target.value) + } + const addService = service => { + if ( + !distrubitorState.stepsConfig[distrubitorState.step].services.find( + elem => elem.name === service, + ) + ) + dispatchDistrubitorState({ + type: actionTypes.ADD_SERVICE, + payload: { + step: distrubitorState.step, + newService: { + name: distrubitorState.registredServices.find(elem => elem === service), + fee: '0', + capabilities: [''], + rackRates: true, + }, + }, + }) + } + + async function confirmEditing() { + setLoading(true) + const originalNames = new Set(state.stepsConfig[2].services.map(item => item.name)) + const updatedNames = new Set( + distrubitorState.stepsConfig[2].services.map(item => item.name), + ) + + const removed = state.stepsConfig[2].services.filter(item => !updatedNames.has(item.name)) + const added = distrubitorState.stepsConfig[2].services.filter( + item => !originalNames.has(item.name), + ) + await removeWantedServices(removed.map(elem => elem.name)) + await addWantedServices(added.map(elem => elem.name)) + let res = await getWantedServices() + dispatch({ + type: actionTypes.UPDATE_WANTED_SERVICES, + payload: { wantedServices: res }, + }) + setLoading(false) + setEditing(false) + console.log({ + removed, + added, + }) + } + + function cancelEditing() { + dispatchDistrubitorState({ + type: actionTypes.RESET_STATE, + payload: { initialState: { ...state, step: 2 } }, + }) + console.log({ state: distrubitorState.stepsConfig[2].services }) + setEditing(false) + } + useEffect(() => { + dispatchDistrubitorState({ + type: actionTypes.RESET_STATE, + payload: { initialState: { ...state, step: 2 } }, + }) + }, [state]) + return ( + + + Wanted Services + {state.stepsConfig[2].paragraph && ( + + {state.stepsConfig[2].paragraph} + + )} + + + services + + + + + + + + + + {!editing ? ( + { + setEditing(true) + }} + > + Edit configuration + + ) : ( + <> + { + cancelEditing() + }} + > + Cancel Editing + + { + confirmEditing() + }} + > + Confirm Editing + + + )} + + + + + + + ) +} + +export default ConfigurDistrubitor diff --git a/src/views/partners/ConfigurSupplier.tsx b/src/views/partners/ConfigurSupplier.tsx new file mode 100644 index 00000000..96a91c03 --- /dev/null +++ b/src/views/partners/ConfigurSupplier.tsx @@ -0,0 +1,238 @@ +import { Box, Divider, FormControl, MenuItem, Select, Typography } from '@mui/material' +import React, { useEffect, useReducer, useState } from 'react' +import MainButton from '../../components/MainButton' +import { + actionTypes, + reducer, + usePartnerConfigurationContext, +} from '../../helpers/partnerConfigurationContext' +import { usePartnerConfig } from '../../helpers/usePartnerConfig' +import { Configuration } from './Configuration' + +const ConfigurSupplier = () => { + const { state, dispatch } = usePartnerConfigurationContext() + const [supplierState, dispatchSupplierState] = useReducer(reducer, { ...state, step: 1 }) + const [editing, setEditing] = useState(false) + const [loading, setLoading] = useState(false) + const { removeServices, addServices, getSupportedServices } = usePartnerConfig() + const handleChange = event => { + addService(event.target.value) + } + const addService = service => { + if ( + !supplierState.stepsConfig[supplierState.step].services.find( + elem => elem.name === service, + ) + ) + dispatchSupplierState({ + type: actionTypes.ADD_SERVICE, + payload: { + step: supplierState.step, + newService: { + name: supplierState.registredServices.find(elem => elem === service), + fee: '0', + capabilities: [''], + rackRates: true, + }, + }, + }) + } + const isEqual = (a, b) => { + return ( + a.name === b.name && + a.fee === b.fee && + a.rackRates === b.rackRates && + JSON.stringify(a.capabilities) === JSON.stringify(b.capabilities) + ) + } + async function confirmEditing() { + setLoading(true) + const removed = state.stepsConfig[supplierState.step].services.filter( + origItem => + !supplierState.stepsConfig[supplierState.step].services.some(updatedItem => + isEqual(origItem, updatedItem), + ), + ) + + const added = supplierState.stepsConfig[supplierState.step].services.filter( + updatedItem => + !state.stepsConfig[supplierState.step].services.some(origItem => + isEqual(origItem, updatedItem), + ), + ) + await removeServices(removed) + await addServices(added) + let res = await getSupportedServices() + dispatch({ + type: actionTypes.UPDATE_SUPPORTED_SERVICES, + payload: { services: res }, + }) + setLoading(false) + setEditing(false) + } + + function cancelEditing() { + dispatchSupplierState({ + type: actionTypes.RESET_STATE, + payload: { initialState: { ...state, step: 1 } }, + }) + setEditing(false) + } + + useEffect(() => { + dispatchSupplierState({ + type: actionTypes.RESET_STATE, + payload: { initialState: { ...state, step: 1 } }, + }) + }, [state]) + + return ( + + + Offered Services + {state.stepsConfig[1].paragraph && ( + + {state.stepsConfig[1].paragraph} + + )} + + + services + + + + + + + + + + {!editing ? ( + { + setEditing(true) + }} + > + Edit configuration + + ) : ( + <> + { + cancelEditing() + }} + > + Cancel Editing + + { + confirmEditing() + }} + > + Confirm Editing + + + )} + + + + + + + ) +} + +export default ConfigurSupplier diff --git a/src/views/partners/Configuration.tsx b/src/views/partners/Configuration.tsx new file mode 100644 index 00000000..fb5e4480 --- /dev/null +++ b/src/views/partners/Configuration.tsx @@ -0,0 +1,939 @@ +import { ContentCopy, RefreshOutlined } from '@mui/icons-material' +import { + Box, + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + InputAdornment, + MenuItem, + Select, + TextField, + Typography, +} from '@mui/material' +import React, { useEffect, useState } from 'react' +import store from 'wallet/store' +import Alert from '../../components/Alert' +import Input from '../../components/Input' +import MainButton from '../../components/MainButton' +import { + actionTypes, + usePartnerConfigurationContext, +} from '../../helpers/partnerConfigurationContext' +import { usePartnerConfig } from '../../helpers/usePartnerConfig' +import { useSmartContract } from '../../helpers/useSmartContract' +import useWalletBalance from '../../helpers/useWalletBalance' + +const Content = () => { + const { contractCMAccountAddress } = useSmartContract() + const { state, dispatch } = usePartnerConfigurationContext() + const [loading, setLoading] = useState(false) + const handleChange = event => { + addService(event.target.value) + } + const partnerConfig = usePartnerConfig() + const nextStep = () => { + if (state.step < state.stepsConfig.length - 1) + dispatch({ type: actionTypes.UPDATE_STEP, payload: { step: state.step + 1 } }) + } + const prevStep = () => { + if (state.step > 0) + dispatch({ type: actionTypes.UPDATE_STEP, payload: { step: state.step - 1 } }) + } + const addService = service => { + if (!state.stepsConfig[state.step].services.find(elem => elem.name === service)) + dispatch({ + type: actionTypes.ADD_SERVICE, + payload: { + step: state.step, + newService: { + name: state.registredServices.find(elem => elem === service), + fee: '0', + capabilities: [''], + rackRates: true, + }, + }, + }) + } + + async function submit() { + setLoading(true) + await partnerConfig.CreateConfiguration(state) + setLoading(false) + } + + const { balance, getBalanceOfAnAddress, balanceOfAnAddress } = useWalletBalance() + useEffect(() => { + if (contractCMAccountAddress) getBalanceOfAnAddress(contractCMAccountAddress) + }, [contractCMAccountAddress]) + if (contractCMAccountAddress) + return ( + <> + + + Messenger setup + Add funds to CM address + + First you need to top up the CM Account with CAM, EURSH or USDC to work + properly. Transfer it to the newly generated CM address below. + + theme.palette.text.primary, + WebkitTextFillColor: theme => theme.palette.text.primary, + }, + }, + endAdornment: ( + + `${theme.palette.text.primary} !important`, + }} + /> + } + variant="outlined" + onClick={() => { + navigator.clipboard.writeText(contractCMAccountAddress) + }} + > + Copy + + ), + }} + /> + + When the necessary balance has arrived you can continue to the next + step. + + + theme.palette.text.primary, + WebkitTextFillColor: theme => theme.palette.text.primary, + }, + }, + startAdornment: ( + theme.palette.text.primary, + }} + > + CM Balance: + + ), + endAdornment: ( + + {balanceOfAnAddress < 100 ? ( + + + + + + ) : ( + + + + + + )} + + `${theme.palette.text.primary} !important`, + }} + /> + } + variant="outlined" + onClick={() => { + getBalanceOfAnAddress(contractCMAccountAddress) + }} + > + Refresh + + + ), + }} + /> + {balanceOfAnAddress !== '' && parseFloat(balanceOfAnAddress) < 100 && ( + + )} + + Min. 100 CAM / 50 EURSH / 100.30 USDC + + + + + + + + ) + return ( + + + Messenger setup + {state.stepsConfig[state.step].title} + {state.stepsConfig[state.step].paragraph && ( + + {state.stepsConfig[state.step].paragraph} + + )} + {state.step === 0 && ( + <> + + {balance !== '' && parseFloat(balance) < 100 && ( + + )} + {!store.getters['Accounts/kycStatus'] && ( + + )} + + )} + {(state.step === 1 || state.step === 2) && ( + + + Are you a {state.stepsConfig[state.step].type}? + + } + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + }} + checked={ + state.step === 1 + ? state.stepsConfig[state.step].isSupplier + : state.stepsConfig[state.step].isDistributor + } + onChange={() => + dispatch({ type: actionTypes.UPDATE_IS_SUPPLIER }) + } + /> + } + /> + {((state.step === 1 && state.stepsConfig[state.step].isSupplier) || + (state.step === 2 && state.stepsConfig[state.step].isDistributor)) && ( + <> + + services + + + + + + + )} + + )} + {state.step === 3 && ( + <> + Offchain} + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + p: '0 8px', + }} + checked={state.stepsConfig[state.step].isOffChain} + onChange={() => + dispatch({ type: actionTypes.UPDATE_IS_OFF_CHAIN }) + } + /> + } + /> + CAM} + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + p: '0 8px', + }} + checked={state.stepsConfig[state.step].isCam} + onChange={() => dispatch({ type: actionTypes.UPDATE_IS_CAM })} + /> + } + /> + USDC* (coming soon) } + disabled + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + p: '0 8px', + }} + checked={state.stepsConfig[state.step].isCam} + onChange={() => dispatch({ type: actionTypes.UPDATE_IS_CAM })} + /> + } + /> + EURC* (coming soon)} + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => theme.palette.secondary.main, + }, + p: '0 8px', + }} + checked={state.stepsConfig[state.step].isCam} + onChange={() => dispatch({ type: actionTypes.UPDATE_IS_CAM })} + /> + } + /> + + )} + {state.step === 4 && ( + + {(state.stepsConfig[3].isOffChain || state.stepsConfig[3].isCam) && ( + + Payment methods + {state.stepsConfig[3].isOffChain && !state.stepsConfig[3].isCam && ( + Offchain + )} + {!state.stepsConfig[3].isOffChain && state.stepsConfig[3].isCam && ( + CAM + )} + {state.stepsConfig[3].isOffChain && state.stepsConfig[3].isCam && ( + Offchain, CAM + )} + + )} + {state.stepsConfig[1].isSupplier && ( + + + Type + Supplier + + {state.stepsConfig[1].services.map((elem, index) => { + return ( + + {elem.name} + + Fee: + {elem.fee + (elem.rackRates ? ', Rack Rates' : '')} + + {!elem.capabilities.filter(str => str.trim() !== '') + .length ? ( + + Capabilities: No Capabilities + + ) : ( + elem.capabilities + .filter(str => str.trim() !== '') + .map((capability, cp) => { + return capability ? ( + + Capability: {capability} + + ) : null + }) + )} + + ) + })} + + )} + {state.stepsConfig[2].isDistributor && ( + + + Type + Distributor + + {state.stepsConfig[2].services.map((elem, index) => { + return ( + + {elem.name} + + ) + })} + + )} + + )} + + + + Previous Step + + {(state.step === 1 && !state.stepsConfig[state.step].isSupplier) || + (state.step === 2 && !state.stepsConfig[state.step].isDistributor) ? ( + + Skip this step + + ) : state.step !== 4 ? ( + + Next Step + + ) : ( + + Create Configuration + + )} + + + + {state.step === 0 && ( + + )} + + + + ) +} + +export function Configuration({ children, ...restProps }) { + return ( + + {children} + + ) +} + +Configuration.SubTitle = function SubTitle({ children }) { + return ( + + {children} + + ) +} + +Configuration.Title = function Title({ children }) { + return ( + + {children} + + ) +} + +Configuration.Paragraphe = function Paragraphe({ children }) { + return {children} +} + +Configuration.Buttons = function Buttons({ children }) { + return {children} +} + +Configuration.Services = function Services({ + state, + dispatch, + disabled, +}: { + state: any + dispatch: any + disabled?: boolean +}) { + const removeService = serviceIndex => { + dispatch({ + type: actionTypes.REMOVE_SERVICE, + payload: { + step: state.step, + serviceIndex, + }, + }) + } + + const addCapability = serviceIndex => { + dispatch({ + type: actionTypes.ADD_CAPABILITIES, + payload: { + step: state.step, + serviceIndex, + }, + }) + } + + const handleCapabilityChange = (event, serviceIndex, capabilityIndex) => { + dispatch({ + type: actionTypes.UPDATE_CAPABILITY, + payload: { + step: state.step, + serviceIndex: serviceIndex, + capabilityIndex: capabilityIndex, + newValue: event.target.value, + }, + }) + } + + const handleFeeChange = (event, serviceIndex) => { + dispatch({ + type: actionTypes.UPDATE_FEE, + payload: { + step: state.step, + serviceIndex: serviceIndex, + newValue: event.target.value, + }, + }) + } + + return ( + + {state.stepsConfig[state.step].services.map((service, index) => ( + + theme.palette.mode === 'dark' ? '#0F182A' : '#F1F5F9', + }} + > + + {service.name} + + {state.step === 1 && ( + + )} + + + + {state.step === 1 && ( + <> + + + FEE + + + handleFeeChange(e, index)} + sx={{ + flex: '1', + '& .MuiInputBase-root': { + height: '40px', + }, + '& input': { + fontSize: '14px', + height: '100%', + padding: '8px 14px', + }, + }} + type="number" + InputProps={{ + sx: { + '& input': { + fontSize: '14px', + }, + }, + }} + /> + Rack Rates + } + control={ + theme.palette.secondary.main, + '&.Mui-checked': { + color: theme => + theme.palette.secondary.main, + }, + '&.MuiCheckbox-colorSecondary.Mui-checked': { + color: theme => + theme.palette.secondary.main, + }, + }} + checked={ + state.stepsConfig[state.step].services[index] + .rackRates + } + onChange={() => + dispatch({ + type: actionTypes.UPDATE_RACK_RATES, + payload: { + step: state.step, + serviceIndex: index, + }, + }) + } + /> + } + /> + + + + + + + + {state.stepsConfig[state.step].services[index].capabilities.map( + (elem, key) => { + return ( + + + Capabilities + + + handleCapabilityChange(e, index, key) + } + sx={{ + flex: '1', + '& .MuiInputBase-root': { + height: '40px', + }, + '& input': { + fontSize: '14px', + height: '100%', + padding: '8px 14px', + }, + }} + type="string" + InputProps={{ + sx: { + '& input': { + fontSize: '14px', + }, + }, + }} + placeholder="Describe your capabilities..." + /> + + + + + + + ) + }, + )} + + )} + + ))} + + ) +} + +Configuration.Infos = function Infos({ rackRates, information }) { + return ( + + + information + {information} + + + + rack rates + {rackRates} + + + ) +} + +const Overreview = () => { + return ( + <> + + + ) +} +export default Overreview diff --git a/src/views/partners/ManageBots.tsx b/src/views/partners/ManageBots.tsx new file mode 100644 index 00000000..ae1f501d --- /dev/null +++ b/src/views/partners/ManageBots.tsx @@ -0,0 +1,246 @@ +import { Box, Button, CircularProgress, TextField, Typography } from '@mui/material' +import { ethers } from 'ethers' +import React, { useEffect, useState } from 'react' +import Alert from '../../components/Alert' +import { usePartnerConfig } from '../../helpers/usePartnerConfig' +import { Configuration } from './Configuration' + +const ManageBots = () => { + const [isValidAddress, setIsValidAddress] = useState(false) + const [address, setAddress] = useState('') + const [bots, setBots] = useState([]) + const [loading, setLoading] = useState(false) + const handleAddressChange = e => { + const newAddress = e.target.value + setAddress(newAddress) + setIsValidAddress(ethers.isAddress(newAddress)) + } + const { addMessengerBot, getListOfBots, removeMessengerBot } = usePartnerConfig() + + async function fetchBots() { + setLoading(true) + const res = await getListOfBots() + setLoading(false) + setBots(res) + } + useEffect(() => { + fetchBots() + }, []) + const handleAddBot = () => { + if (isValidAddress) { + setLoading(true) + addMessengerBot(address).then(() => { + setAddress('') + fetchBots() + }) + } + } + const handleRemoveBot = address => { + setLoading(true) + removeMessengerBot(address).then(() => fetchBots()) + } + return ( + + + Manage Bots + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula + eget dolor. Aenean massa. Donec sociis natoque penatibus. + + {loading && ( + + + + )} + {bots && + bots.length > 0 && + bots.map((bot, index) => { + return ( + + + + theme.palette.mode === 'dark' + ? '#0F182A' + : '#F1F5F9', + borderWidth: '1px', + '&:hover': { + borderWidth: '1px', + boxShadow: 'none', + }, + }} + variant="caption" + > + Bot + + theme.palette.text.primary, + WebkitTextFillColor: theme => + theme.palette.text.primary, + }, + }, + }} + onChange={handleAddressChange} + /> + + + + ) + })} + + + + theme.palette.mode === 'dark' ? '#0F182A' : '#F1F5F9', + borderWidth: '1px', + '&:hover': { + borderWidth: '1px', + boxShadow: 'none', + }, + }} + variant="caption" + > + Bot + + + + + {address !== '' && !isValidAddress && ( + + )} + + + + + + + ) +} + +export default ManageBots diff --git a/src/views/settings/Links.tsx b/src/views/settings/Links.tsx index ba5631d3..a4e0b117 100644 --- a/src/views/settings/Links.tsx +++ b/src/views/settings/Links.tsx @@ -4,7 +4,9 @@ import Box from '@mui/material/Box' import Tab from '@mui/material/Tab' import Tabs from '@mui/material/Tabs' import { useNavigate } from 'react-router' -import { useAppDispatch } from '../../hooks/reduxHooks' +import store from 'wallet/store' +import { useSmartContract } from '../../helpers/useSmartContract' +import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' import { changeActiveApp } from '../../redux/slices/app-config' function a11yProps(index: number) { @@ -14,20 +16,31 @@ function a11yProps(index: number) { } } -export default function Links() { +export default function Links({ type = 'else' }: { type?: string }) { const dispatch = useAppDispatch() const [value, setValue] = useState(0) + const [secondValue, setSecondValue] = useState(0) const navigate = useNavigate() const path = window.location.pathname - const handleChange = (event: React.SyntheticEvent, newValue: number) => setValue(newValue) + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + if (type === 'subtabs') { + setSecondValue(newValue) + } else setValue(newValue) + } useEffect(() => { if (path === '/settings') setValue(0) else if (path === '/settings/manage-multisig') setValue(1) else if (path === '/settings/verify-wallet') setValue(2) + else if (path === '/partners') setValue(0) + else if (path.includes('partners/messenger-configuration')) setValue(1) + else if (path.includes('overview')) setSecondValue(0) + else if (path.includes('distribution')) setSecondValue(1) + else if (path.includes('supply')) setSecondValue(2) else setValue(0) dispatch(changeActiveApp('Network')) }, [path]) // eslint-disable-line react-hooks/exhaustive-deps - + const auth = useAppSelector(state => state.appConfig.isAuth) + const sc = useSmartContract() const settingsTabs = [ navigate('/partners')} className="tab" disableRipple label="Partner showroom" @@ -67,21 +81,96 @@ export default function Links() { key={0} sx={{ '&::after': { display: value === 0 ? 'block' : 'none' } }} />, + auth && store.state.activeWallet?.type !== 'multisig' && ( + navigate('/partners/messenger-configuration')} + className="tab" + disableRipple + label="My Partners Profile" + {...a11yProps(1)} + key={1} + sx={{ '&::after': { display: value === 1 ? 'block' : 'none' } }} + /> + ), + ] + + const partnersSubTabs = [ + navigate('/partners/messenger-configuration/messenger')} + className="tab" + disableRipple + label="My Messenger Account" + {...a11yProps(0)} + key={0} + sx={{ '&::after': { display: secondValue === 0 ? 'block' : 'none' } }} + />, + navigate('/partners/messenger-configuration/supplier')} + className="tab" + disableRipple + label="Offered Services" + {...a11yProps(1)} + key={1} + sx={{ '&::after': { display: secondValue === 1 ? 'block' : 'none' } }} + />, + navigate('/partners/messenger-configuration/distribution')} + className="tab" + disableRipple + label="Wanted Services" + {...a11yProps(2)} + key={2} + sx={{ '&::after': { display: secondValue === 2 ? 'block' : 'none' } }} + />, + navigate('/partners/messenger-configuration/bots')} + className="tab" + disableRipple + label="Manage Bots" + {...a11yProps(3)} + key={3} + sx={{ '&::after': { display: secondValue === 3 ? 'block' : 'none' } }} + />, ] + if (type === 'subtabs') + return ( + + + {partnersSubTabs.map((tab, index) => (tab ? tab : null))} + + + ) return ( - {path.includes('/partners') - ? partnersTabs.map((tab, index) => (tab ? tab : null)) + {type === 'subtabs' + ? partnersSubTabs.map((tab, index) => (tab ? tab : null)) + : path.includes('/partners') + ? partnersTabs.map((tab, index) => { + return tab + }) : settingsTabs.map((tab, index) => (tab ? tab : null))} diff --git a/tsconfig.json b/tsconfig.json index 25236f17..c70fc070 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,15 @@ { "compilerOptions": { + "target": "ES2020", "jsx": "react", - "esModuleInterop": true + "resolveJsonModule": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "typeRoots": ["node_modules/@types"], + "paths": { + "ethers": ["./node_modules/ethers"] + } }, "include": ["src"], "ts-node": { diff --git a/webpack.common.js b/webpack.common.js index 25722f98..9a3744e1 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -36,6 +36,11 @@ module.exports = { fullySpecified: false, }, }, + { + test: /\.json$/, + loader: 'json-loader', + type: 'javascript/auto', + }, { test: /\.(css|s[ac]ss)$/i, use: ['style-loader', 'css-loader', 'postcss-loader'], diff --git a/webpack.dev.js b/webpack.dev.js index 8384ced6..f655a06e 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -36,6 +36,11 @@ module.exports = merge(common, { singleton: true, requiredVersion: deps['react-dom'], }, + ethers: { + singleton: true, + eager: true, + requiredVersion: deps['ethers'], + }, }, }), ],