diff --git a/.gitignore b/.gitignore index 3b6d22e7..eaf0cc15 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ yarn-error.log* # Ignore for yarn.lock bun.lockb -package-lock.json \ No newline at end of file +package-lock.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c0b790fe..479e9dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- Etherlink ERC20 Token Deployer - Migration tool for V2 contracts - Sending XTZ directly to DAO address - Delegating DAO's XTZ to baker diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 00000000..8cc4c015 Binary files /dev/null and b/bun.lockb differ diff --git a/package.json b/package.json index 1aa71d10..e6c60081 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@types/react-paginate": "^7.1.2", "@types/react-router-hash-link": "^2.4.5", "@types/valid-url": "^1.0.4", + "@web3modal/wagmi": "^5.0.6", "assert": "^2.0.0", "bignumber.js": "^9.0.1", "blockies-ts": "^1.0.0", diff --git a/src/App.tsx b/src/App.tsx index bc93cdcc..8cad6798 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,6 +16,8 @@ import { DAOExplorerRouter } from "modules/explorer/router" import { CreatorProvider } from "modules/creator/state" import ScrollToTop from "modules/common/ScrollToTop" import { theme } from "theme" +import { WagmiProvider } from "wagmi" +import { config as wagmiConfig } from "services/wagmi/config" import { TZKTSubscriptionsProvider } from "services/bakingBad/context/TZKTSubscriptions" import { WarningFooter } from "modules/common/WarningFooter" @@ -98,57 +100,61 @@ const App: React.FC = () => { variantInfo: classes.info }} > - - - - - - - - - - - - - - {/* + {/* */} + + + + + + + + + + + + + + {/* */} - - - - - - - - - - + + + + + + + + + + - {window.location.href.indexOf(HUMANITEZ_DAO) !== -1 ? ( - <> - {/* Special case for this DAO which was created before FA1.2 fix was created for the smart contract */} - - - ) : null} - - - - - - - - - - - - + {window.location.href.indexOf(HUMANITEZ_DAO) !== -1 ? ( + <> + {/* Special case for this DAO which was created before FA1.2 fix was created for the smart contract */} + + + ) : null} + + + + + + + + + + + + + {/* */} + ) diff --git a/src/assets/abis/TODO.md b/src/assets/abis/TODO.md new file mode 100644 index 00000000..842619dc --- /dev/null +++ b/src/assets/abis/TODO.md @@ -0,0 +1,4 @@ + +# TODO + +We can directly fetch the ABI from https://github.com/dOrgTech/homebase-evm-contracts/ once this is ready instead of defining it here as a JSON \ No newline at end of file diff --git a/src/assets/abis/hb_evm.json b/src/assets/abis/hb_evm.json new file mode 100644 index 00000000..2b22d7b6 --- /dev/null +++ b/src/assets/abis/hb_evm.json @@ -0,0 +1,905 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "HBEVM_token", + "sourceName": "contracts/Token.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "address[]", + "name": "initialMembers", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "initialAmounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CheckpointUnorderedInsertion", + "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": "uint256", + "name": "increasedSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "cap", + "type": "uint256" + } + ], + "name": "ERC20ExceededSafeSupply", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ERC2612ExpiredSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC2612InvalidSigner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + }, + { + "internalType": "uint48", + "name": "clock", + "type": "uint48" + } + ], + "name": "ERC5805FutureLookup", + "type": "error" + }, + { + "inputs": [], + "name": "ERC6372InconsistentClock", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentNonce", + "type": "uint256" + } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidShortString", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "str", + "type": "string" + } + ], + "name": "StringTooLong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + } + ], + "name": "VotesExpiredSignature", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousVotes", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVotes", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "CLOCK_MODE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "_key", + "type": "uint48" + }, + { + "internalType": "uint208", + "name": "_value", + "type": "uint208" + } + ], + "internalType": "struct Checkpoints.Checkpoint208", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clock", + "outputs": [ + { + "internalType": "uint48", + "name": "", + "type": "uint48" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x6101606040523480156200001257600080fd5b506040516200583b3803806200583b8339818101604052810190620000389190620014eb565b83806040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250868681600390816200008391906200181a565b5080600490816200009591906200181a565b505050620000ae6005836200021c60201b90919060201c565b6101208181525050620000cc6006826200021c60201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506200010b6200027460201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1681525050505050805182511462000190576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001879062001988565b60405180910390fd5b60005b82518163ffffffff1610156200021157620001fb838263ffffffff1681518110620001c357620001c2620019aa565b5b6020026020010151838363ffffffff1681518110620001e757620001e6620019aa565b5b6020026020010151620002d160201b60201c565b8080620002089062001a18565b91505062000193565b505050505062001ec1565b600060208351101562000242576200023a836200035e60201b60201c565b90506200026e565b826200025483620003cb60201b60201c565b60000190816200026591906200181a565b5060ff60001b90505b92915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e051610100514630604051602001620002b695949392919062001a86565b60405160208183030381529060405280519060200120905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620003465760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016200033d919062001ae3565b60405180910390fd5b6200035a60008383620003d560201b60201c565b5050565b600080829050601f81511115620003ae57826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401620003a5919062001b41565b60405180910390fd5b805181620003bc9062001b97565b60001c1760001b915050919050565b6000819050919050565b620003e8838383620003ed60201b60201c565b505050565b62000400838383620004c260201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620004aa57600062000447620006f260201b60201c565b905060006200045b620006fc60201b60201c565b905080821115620004a75781816040517f1cb15d260000000000000000000000000000000000000000000000000000000081526004016200049e92919062001c07565b60405180910390fd5b50505b620004bd8383836200072060201b60201c565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620005185780600260008282546200050b919062001c34565b92505081905550620005ee565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015620005a7578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016200059e9392919062001c6f565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000639578060026000828254039250508190555062000686565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620006e5919062001cac565b60405180910390a3505050565b6000600254905090565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620007875762000784600a6200082660201b62000d971762000778846200083e60201b60201c565b620008af60201b60201c565b50505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620007ee57620007eb600a620008ff60201b62000dad17620007df846200083e60201b60201c565b620008af60201b60201c565b50505b6200082162000803846200091760201b60201c565b62000814846200091760201b60201c565b836200098060201b60201c565b505050565b6000818362000836919062001cef565b905092915050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115620008a75760d0826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016200089e92919062001d94565b60405180910390fd5b819050919050565b600080620008f3620008c662000c3360201b60201c565b620008e2620008db8862000c4a60201b60201c565b868860201c565b8762000cbe60201b9092919060201c565b91509150935093915050565b600081836200090f919062001dc1565b905092915050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015620009bd5750600081115b1562000c2e57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000af85760008062000a67600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020620008ff60201b62000dad1762000a5b866200083e60201b60201c565b620008af60201b60201c565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000aed92919062001c07565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000c2d5760008062000b9c600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206200082660201b62000d971762000b90866200083e60201b60201c565b620008af60201b60201c565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000c2292919062001c07565b60405180910390a250505b5b505050565b600062000c4562000ce360201b60201c565b905090565b600080826000018054905090506000811462000cb35762000c838360000160018362000c77919062001e16565b62000cfb60201b60201c565b60000160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1662000cb6565b60005b915050919050565b60008062000cd785600001858562000d1060201b60201c565b91509150935093915050565b600062000cf643620010aa60201b60201c565b905090565b60008260005281602060002001905092915050565b600080600085805490509050600081111562000fba57600062000d488760018462000d3c919062001e16565b62000cfb60201b60201c565b6040518060400160405290816000820160009054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16816000015165ffffffffffff16111562000e38576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16816000015165ffffffffffff160362000ec8578462000e758860018562000e69919062001e16565b62000cfb60201b60201c565b60000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555062000fa8565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050620010a2565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b600065ffffffffffff8016821115620010ff576030826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401620010f692919062001e94565b60405180910390fd5b819050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620011708262001125565b810181811067ffffffffffffffff8211171562001192576200119162001136565b5b80604052505050565b6000620011a762001107565b9050620011b5828262001165565b919050565b600067ffffffffffffffff821115620011d857620011d762001136565b5b620011e38262001125565b9050602081019050919050565b60005b8381101562001210578082015181840152602081019050620011f3565b60008484015250505050565b6000620012336200122d84620011ba565b6200119b565b90508281526020810184848401111562001252576200125162001120565b5b6200125f848285620011f0565b509392505050565b600082601f8301126200127f576200127e6200111b565b5b8151620012918482602086016200121c565b91505092915050565b600067ffffffffffffffff821115620012b857620012b762001136565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620012fb82620012ce565b9050919050565b6200130d81620012ee565b81146200131957600080fd5b50565b6000815190506200132d8162001302565b92915050565b60006200134a62001344846200129a565b6200119b565b9050808382526020820190506020840283018581111562001370576200136f620012c9565b5b835b818110156200139d57806200138888826200131c565b84526020840193505060208101905062001372565b5050509392505050565b600082601f830112620013bf57620013be6200111b565b5b8151620013d184826020860162001333565b91505092915050565b600067ffffffffffffffff821115620013f857620013f762001136565b5b602082029050602081019050919050565b6000819050919050565b6200141e8162001409565b81146200142a57600080fd5b50565b6000815190506200143e8162001413565b92915050565b60006200145b6200145584620013da565b6200119b565b90508083825260208201905060208402830185811115620014815762001480620012c9565b5b835b81811015620014ae57806200149988826200142d565b84526020840193505060208101905062001483565b5050509392505050565b600082601f830112620014d057620014cf6200111b565b5b8151620014e284826020860162001444565b91505092915050565b6000806000806080858703121562001508576200150762001111565b5b600085015167ffffffffffffffff81111562001529576200152862001116565b5b620015378782880162001267565b945050602085015167ffffffffffffffff8111156200155b576200155a62001116565b5b620015698782880162001267565b935050604085015167ffffffffffffffff8111156200158d576200158c62001116565b5b6200159b87828801620013a7565b925050606085015167ffffffffffffffff811115620015bf57620015be62001116565b5b620015cd87828801620014b8565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200162c57607f821691505b602082108103620016425762001641620015e4565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620016ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200166d565b620016b886836200166d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620016fb620016f5620016ef8462001409565b620016d0565b62001409565b9050919050565b6000819050919050565b6200171783620016da565b6200172f620017268262001702565b8484546200167a565b825550505050565b600090565b6200174662001737565b620017538184846200170c565b505050565b5b818110156200177b576200176f6000826200173c565b60018101905062001759565b5050565b601f821115620017ca57620017948162001648565b6200179f846200165d565b81016020851015620017af578190505b620017c7620017be856200165d565b83018262001758565b50505b505050565b600082821c905092915050565b6000620017ef60001984600802620017cf565b1980831691505092915050565b60006200180a8383620017dc565b9150826002028217905092915050565b6200182582620015d9565b67ffffffffffffffff81111562001841576200184062001136565b5b6200184d825462001613565b6200185a8282856200177f565b600060209050601f8311600181146200189257600084156200187d578287015190505b620018898582620017fc565b865550620018f9565b601f198416620018a28662001648565b60005b82811015620018cc57848901518255600182019150602085019450602081019050620018a5565b86831015620018ec5784890151620018e8601f891682620017dc565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f696e697469616c416d6f756e7473206d757374206265206173206d616e79206160008201527f7320696e697469616c4d656d6265727300000000000000000000000000000000602082015250565b60006200197060308362001901565b91506200197d8262001912565b604082019050919050565b60006020820190508181036000830152620019a38162001961565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff82169050919050565b600062001a258262001a08565b915063ffffffff820362001a3e5762001a3d620019d9565b5b600182019050919050565b6000819050919050565b62001a5e8162001a49565b82525050565b62001a6f8162001409565b82525050565b62001a8081620012ee565b82525050565b600060a08201905062001a9d600083018862001a53565b62001aac602083018762001a53565b62001abb604083018662001a53565b62001aca606083018562001a64565b62001ad9608083018462001a75565b9695505050505050565b600060208201905062001afa600083018462001a75565b92915050565b600062001b0d82620015d9565b62001b19818562001901565b935062001b2b818560208601620011f0565b62001b368162001125565b840191505092915050565b6000602082019050818103600083015262001b5d818462001b00565b905092915050565b600081519050919050565b6000819050602082019050919050565b600062001b8e825162001a49565b80915050919050565b600062001ba48262001b65565b8262001bb08462001b70565b905062001bbd8162001b80565b9250602082101562001c005762001bfb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026200166d565b831692505b5050919050565b600060408201905062001c1e600083018562001a64565b62001c2d602083018462001a64565b9392505050565b600062001c418262001409565b915062001c4e8362001409565b925082820190508082111562001c695762001c68620019d9565b5b92915050565b600060608201905062001c86600083018662001a75565b62001c95602083018562001a64565b62001ca4604083018462001a64565b949350505050565b600060208201905062001cc3600083018462001a64565b92915050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001cfc8262001cc9565b915062001d098362001cc9565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff81111562001d3e5762001d3d620019d9565b5b92915050565b6000819050919050565b600060ff82169050919050565b600062001d7c62001d7662001d708462001d44565b620016d0565b62001d4e565b9050919050565b62001d8e8162001d5b565b82525050565b600060408201905062001dab600083018562001d83565b62001dba602083018462001a64565b9392505050565b600062001dce8262001cc9565b915062001ddb8362001cc9565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff81111562001e105762001e0f620019d9565b5b92915050565b600062001e238262001409565b915062001e308362001409565b925082820390508181111562001e4b5762001e4a620019d9565b5b92915050565b6000819050919050565b600062001e7c62001e7662001e708462001e51565b620016d0565b62001d4e565b9050919050565b62001e8e8162001e5b565b82525050565b600060408201905062001eab600083018562001e83565b62001eba602083018462001a64565b9392505050565b60805160a05160c05160e05161010051610120516101405161391f62001f1c60003960006113c401526000611389015260006117e5015260006117c401526000610f6901526000610fbf01526000610fe8015261391f6000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c35780639ab24eb01161007c5780639ab24eb01461040b578063a9059cbb1461043b578063c3cda5201461046b578063d505accf14610487578063dd62ed3e146104a3578063f1127ed8146104d357610158565b806370a082311461031b5780637ecebe001461034b57806384b0196e1461037b5780638e539e8c1461039f57806391ddadf4146103cf57806395d89b41146103ed57610158565b80633a46b1a8116101155780633a46b1a81461023557806340c10f19146102655780634bf5d7e914610281578063587cde1e1461029f5780635c19a95c146102cf5780636fcfff45146102eb57610158565b806306fdde031461015d578063095ea7b31461017b57806318160ddd146101ab57806323b872dd146101c9578063313ce567146101f95780633644e51514610217575b600080fd5b610165610503565b6040516101729190612bc9565b60405180910390f35b61019560048036038101906101909190612c84565b610595565b6040516101a29190612cdf565b60405180910390f35b6101b36105b8565b6040516101c09190612d09565b60405180910390f35b6101e360048036038101906101de9190612d24565b6105c2565b6040516101f09190612cdf565b60405180910390f35b6102016105f1565b60405161020e9190612d93565b60405180910390f35b61021f6105fa565b60405161022c9190612dc7565b60405180910390f35b61024f600480360381019061024a9190612c84565b610609565b60405161025c9190612d09565b60405180910390f35b61027f600480360381019061027a9190612c84565b6106e2565b005b6102896106f0565b6040516102969190612bc9565b60405180910390f35b6102b960048036038101906102b49190612de2565b610784565b6040516102c69190612e1e565b60405180910390f35b6102e960048036038101906102e49190612de2565b6107ed565b005b61030560048036038101906103009190612de2565b610807565b6040516103129190612e58565b60405180910390f35b61033560048036038101906103309190612de2565b610819565b6040516103429190612d09565b60405180910390f35b61036560048036038101906103609190612de2565b610861565b6040516103729190612d09565b60405180910390f35b610383610873565b6040516103969796959493929190612f6c565b60405180910390f35b6103b960048036038101906103b49190612ff0565b61091d565b6040516103c69190612d09565b60405180910390f35b6103d76109b8565b6040516103e4919061303e565b60405180910390f35b6103f56109c7565b6040516104029190612bc9565b60405180910390f35b61042560048036038101906104209190612de2565b610a59565b6040516104329190612d09565b60405180910390f35b61045560048036038101906104509190612c84565b610ac5565b6040516104629190612cdf565b60405180910390f35b610485600480360381019061048091906130b1565b610ae8565b005b6104a1600480360381019061049c919061313e565b610bae565b005b6104bd60048036038101906104b891906131e0565b610cf6565b6040516104ca9190612d09565b60405180910390f35b6104ed60048036038101906104e8919061324c565b610d7d565b6040516104fa91906132ff565b60405180910390f35b60606003805461051290613349565b80601f016020809104026020016040519081016040528092919081815260200182805461053e90613349565b801561058b5780601f106105605761010080835404028352916020019161058b565b820191906000526020600020905b81548152906001019060200180831161056e57829003601f168201915b5050505050905090565b6000806105a0610dc3565b90506105ad818585610dcb565b600191505092915050565b6000600254905090565b6000806105cd610dc3565b90506105da858285610ddd565b6105e5858585610e71565b60019150509392505050565b60006012905090565b6000610604610f65565b905090565b6000806106146109b8565b90508065ffffffffffff1683106106645782816040517fecd3f81e00000000000000000000000000000000000000000000000000000000815260040161065b92919061337a565b60405180910390fd5b6106bd6106708461101c565b600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061107690919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1691505092915050565b6106ec8282611170565b5050565b60606106fa6111f2565b65ffffffffffff1661070a6109b8565b65ffffffffffff1614610749576040517f6ff0714000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280601d81526020017f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000815250905090565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107f7610dc3565b90506108038183611202565b5050565b600061081282611316565b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061086c8261136e565b9050919050565b600060608060008060006060610887611380565b61088f6113bb565b46306000801b600067ffffffffffffffff8111156108b0576108af6133a3565b5b6040519080825280602002602001820160405280156108de5781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b6000806109286109b8565b90508065ffffffffffff1683106109785782816040517fecd3f81e00000000000000000000000000000000000000000000000000000000815260040161096f92919061337a565b60405180910390fd5b6109946109848461101c565b600a61107690919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b60006109c26111f2565b905090565b6060600480546109d690613349565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290613349565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b5050505050905090565b6000610aa2600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113f6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b600080610ad0610dc3565b9050610add818585610e71565b600191505092915050565b83421115610b2d57836040517f4683af0e000000000000000000000000000000000000000000000000000000008152600401610b249190612d09565b60405180910390fd5b6000610b8f610b877fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610b6c94939291906133d2565b6040516020818303038152906040528051906020012061145e565b858585611478565b9050610b9b81876114a8565b610ba58188611202565b50505050505050565b83421115610bf357836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610bea9190612d09565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610c228c611500565b89604051602001610c3896959493929190613417565b6040516020818303038152906040528051906020012090506000610c5b8261145e565b90506000610c6b82878787611478565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cdf57808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401610cd6929190613478565b60405180910390fd5b610cea8a8a8a610dcb565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610d85612afb565b610d8f8383611557565b905092915050565b60008183610da591906134d0565b905092915050565b60008183610dbb919061351e565b905092915050565b600033905090565b610dd883838360016115b8565b505050565b6000610de98484610cf6565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e6b5781811015610e5b578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610e529392919061356c565b60405180910390fd5b610e6a848484840360006115b8565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ee35760006040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610eda9190612e1e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f555760006040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610f4c9190612e1e565b60405180910390fd5b610f6083838361178f565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610fe157507f000000000000000000000000000000000000000000000000000000000000000046145b1561100e577f00000000000000000000000000000000000000000000000000000000000000009050611019565b61101661179f565b90505b90565b600065ffffffffffff801682111561106e576030826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016110659291906135e8565b60405180910390fd5b819050919050565b6000808360000180549050905060008082905060058311156110fe57600061109d84611835565b846110a89190613611565b90506110b7876000018261192e565b60000160009054906101000a900465ffffffffffff1665ffffffffffff168665ffffffffffff1610156110ec578091506110fc565b6001816110f99190613645565b92505b505b600061110f87600001878585611943565b905060008114611161576111328760000160018361112d9190613611565b61192e565b60000160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611164565b60005b94505050505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111e25760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016111d99190612e1e565b60405180910390fd5b6111ee6000838361178f565b5050565b60006111fd4361101c565b905090565b600061120d83610784565b905081600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a4611311818361130c866119bc565b6119ce565b505050565b6000611367611362600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611c47565b611c58565b9050919050565b600061137982611cb0565b9050919050565b60606113b660057f0000000000000000000000000000000000000000000000000000000000000000611cf990919063ffffffff16565b905090565b60606113f160067f0000000000000000000000000000000000000000000000000000000000000000611cf990919063ffffffff16565b905090565b6000808260000180549050905060008114611453576114248360000160018361141f9190613611565b61192e565b60000160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611456565b60005b915050919050565b600061147161146b610f65565b83611da9565b9050919050565b60008060008061148a88888888611dea565b92509250925061149a8282611ede565b829350505050949350505050565b60006114b383611500565b90508082146114fb5782816040517f752d88c00000000000000000000000000000000000000000000000000000000081526004016114f2929190613679565b60405180910390fd5b505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050559050919050565b61155f612afb565b6115b082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061204290919063ffffffff16565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361162a5760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016116219190612e1e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169c5760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016116939190612e1e565b60405180910390fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508015611789578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516117809190612d09565b60405180910390a35b50505050565b61179a838383612117565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000463060405160200161181a9594939291906136a2565b60405160208183030381529060405280519060200120905090565b60008082036118475760009050611929565b60006001611854846121c8565b901c6001901b9050600181848161186e5761186d6136f5565b5b048201901c90506001818481611887576118866136f5565b5b048201901c905060018184816118a05761189f6136f5565b5b048201901c905060018184816118b9576118b86136f5565b5b048201901c905060018184816118d2576118d16136f5565b5b048201901c905060018184816118eb576118ea6136f5565b5b048201901c90506001818481611904576119036136f5565b5b048201901c90506119258182858161191f5761191e6136f5565b5b046122a9565b9150505b919050565b60008260005281602060002001905092915050565b60005b818310156119b157600061195a84846122c2565b90508465ffffffffffff1661196f878361192e565b60000160009054906101000a900465ffffffffffff1665ffffffffffff16111561199b578092506119ab565b6001816119a89190613645565b93505b50611946565b819050949350505050565b60006119c782610819565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611a0a5750600081115b15611c4257600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b2857600080611a99600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610dad611a94866122e8565b612356565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611b1d929190613724565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611c4157600080611bb2600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610d97611bad866122e8565b612356565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611c36929190613724565b60405180910390a250505b5b505050565b600081600001805490509050919050565b600063ffffffff8016821115611ca8576020826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401611c9f929190613788565b60405180910390fd5b819050919050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060ff60001b8314611d1657611d0f83612396565b9050611da3565b818054611d2290613349565b80601f0160208091040260200160405190810160405280929190818152602001828054611d4e90613349565b8015611d9b5780601f10611d7057610100808354040283529160200191611d9b565b820191906000526020600020905b815481529060010190602001808311611d7e57829003601f168201915b505050505090505b92915050565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b60008060007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08460001c1115611e2a576000600385925092509250611ed4565b600060018888888860405160008152602001604052604051611e4f94939291906137b1565b6020604051602081039080840390855afa158015611e71573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ec557600060016000801b93509350935050611ed4565b8060008060001b935093509350505b9450945094915050565b60006003811115611ef257611ef16137f6565b5b826003811115611f0557611f046137f6565b5b031561203e5760016003811115611f1f57611f1e6137f6565b5b826003811115611f3257611f316137f6565b5b03611f69576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611f7d57611f7c6137f6565b5b826003811115611f9057611f8f6137f6565b5b03611fd5578060001c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611fcc9190612d09565b60405180910390fd5b600380811115611fe857611fe76137f6565b5b826003811115611ffb57611ffa6137f6565b5b0361203d57806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016120349190612dc7565b60405180910390fd5b5b5050565b61204a612afb565b826000018263ffffffff168154811061206657612065613825565b5b906000526020600020016040518060400160405290816000820160009054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b61212283838361240a565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036121b85760006121606105b8565b9050600061216c61262f565b9050808211156121b55781816040517f1cb15d260000000000000000000000000000000000000000000000000000000081526004016121ac929190613724565b60405180910390fd5b50505b6121c3838383612653565b505050565b600080600090506000608084901c11156121ea57608083901c92506080810190505b6000604084901c111561220557604083901c92506040810190505b6000602084901c111561222057602083901c92506020810190505b6000601084901c111561223b57601083901c92506010810190505b6000600884901c111561225657600883901c92506008810190505b6000600484901c111561227157600483901c92506004810190505b6000600284901c111561228c57600283901c92506002810190505b6000600184901c11156122a0576001810190505b80915050919050565b60008183106122b857816122ba565b825b905092915050565b600060028284186122d39190613854565b8284166122e09190613645565b905092915050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff801682111561234e5760d0826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016123459291906138c0565b60405180910390fd5b819050919050565b60008061238a6123646109b8565b61237a612370886113f6565b868863ffffffff16565b8761270d9092919063ffffffff16565b91509150935093915050565b606060006123a38361272a565b90506000602067ffffffffffffffff8111156123c2576123c16133a3565b5b6040519080825280601f01601f1916602001820160405280156123f45781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361245c5780600260008282546124509190613645565b9250508190555061252f565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156124e8578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016124df9392919061356c565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361257857806002600082825403925050819055506125c5565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126229190612d09565b60405180910390a3505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126a05761269d600a610d97612698846122e8565b612356565b50505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126ed576126ea600a610dad6126e5846122e8565b612356565b50505b6127086126f984610784565b61270284610784565b836119ce565b505050565b60008061271e85600001858561277a565b91509150935093915050565b60008060ff8360001c169050601f811115612771576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b6000806000858054905090506000811115612a0b5760006127a7876001846127a29190613611565b61192e565b6040518060400160405290816000820160009054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16816000015165ffffffffffff161115612896576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16816000015165ffffffffffff160361291a57846128c8886001856128c39190613611565b61192e565b60000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506129fa565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050612af3565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b6040518060400160405280600065ffffffffffff168152602001600079ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600081519050919050565b600082825260208201905092915050565b60005b83811015612b73578082015181840152602081019050612b58565b60008484015250505050565b6000601f19601f8301169050919050565b6000612b9b82612b39565b612ba58185612b44565b9350612bb5818560208601612b55565b612bbe81612b7f565b840191505092915050565b60006020820190508181036000830152612be38184612b90565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612c1b82612bf0565b9050919050565b612c2b81612c10565b8114612c3657600080fd5b50565b600081359050612c4881612c22565b92915050565b6000819050919050565b612c6181612c4e565b8114612c6c57600080fd5b50565b600081359050612c7e81612c58565b92915050565b60008060408385031215612c9b57612c9a612beb565b5b6000612ca985828601612c39565b9250506020612cba85828601612c6f565b9150509250929050565b60008115159050919050565b612cd981612cc4565b82525050565b6000602082019050612cf46000830184612cd0565b92915050565b612d0381612c4e565b82525050565b6000602082019050612d1e6000830184612cfa565b92915050565b600080600060608486031215612d3d57612d3c612beb565b5b6000612d4b86828701612c39565b9350506020612d5c86828701612c39565b9250506040612d6d86828701612c6f565b9150509250925092565b600060ff82169050919050565b612d8d81612d77565b82525050565b6000602082019050612da86000830184612d84565b92915050565b6000819050919050565b612dc181612dae565b82525050565b6000602082019050612ddc6000830184612db8565b92915050565b600060208284031215612df857612df7612beb565b5b6000612e0684828501612c39565b91505092915050565b612e1881612c10565b82525050565b6000602082019050612e336000830184612e0f565b92915050565b600063ffffffff82169050919050565b612e5281612e39565b82525050565b6000602082019050612e6d6000830184612e49565b92915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b612ea881612e73565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612ee381612c4e565b82525050565b6000612ef58383612eda565b60208301905092915050565b6000602082019050919050565b6000612f1982612eae565b612f238185612eb9565b9350612f2e83612eca565b8060005b83811015612f5f578151612f468882612ee9565b9750612f5183612f01565b925050600181019050612f32565b5085935050505092915050565b600060e082019050612f81600083018a612e9f565b8181036020830152612f938189612b90565b90508181036040830152612fa78188612b90565b9050612fb66060830187612cfa565b612fc36080830186612e0f565b612fd060a0830185612db8565b81810360c0830152612fe28184612f0e565b905098975050505050505050565b60006020828403121561300657613005612beb565b5b600061301484828501612c6f565b91505092915050565b600065ffffffffffff82169050919050565b6130388161301d565b82525050565b6000602082019050613053600083018461302f565b92915050565b61306281612d77565b811461306d57600080fd5b50565b60008135905061307f81613059565b92915050565b61308e81612dae565b811461309957600080fd5b50565b6000813590506130ab81613085565b92915050565b60008060008060008060c087890312156130ce576130cd612beb565b5b60006130dc89828a01612c39565b96505060206130ed89828a01612c6f565b95505060406130fe89828a01612c6f565b945050606061310f89828a01613070565b935050608061312089828a0161309c565b92505060a061313189828a0161309c565b9150509295509295509295565b600080600080600080600060e0888a03121561315d5761315c612beb565b5b600061316b8a828b01612c39565b975050602061317c8a828b01612c39565b965050604061318d8a828b01612c6f565b955050606061319e8a828b01612c6f565b94505060806131af8a828b01613070565b93505060a06131c08a828b0161309c565b92505060c06131d18a828b0161309c565b91505092959891949750929550565b600080604083850312156131f7576131f6612beb565b5b600061320585828601612c39565b925050602061321685828601612c39565b9150509250929050565b61322981612e39565b811461323457600080fd5b50565b60008135905061324681613220565b92915050565b6000806040838503121561326357613262612beb565b5b600061327185828601612c39565b925050602061328285828601613237565b9150509250929050565b6132958161301d565b82525050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6132ca8161329b565b82525050565b6040820160008201516132e6600085018261328c565b5060208201516132f960208501826132c1565b50505050565b600060408201905061331460008301846132d0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061336157607f821691505b6020821081036133745761337361331a565b5b50919050565b600060408201905061338f6000830185612cfa565b61339c602083018461302f565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080820190506133e76000830187612db8565b6133f46020830186612e0f565b6134016040830185612cfa565b61340e6060830184612cfa565b95945050505050565b600060c08201905061342c6000830189612db8565b6134396020830188612e0f565b6134466040830187612e0f565b6134536060830186612cfa565b6134606080830185612cfa565b61346d60a0830184612cfa565b979650505050505050565b600060408201905061348d6000830185612e0f565b61349a6020830184612e0f565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006134db8261329b565b91506134e68361329b565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613518576135176134a1565b5b92915050565b60006135298261329b565b91506135348361329b565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613566576135656134a1565b5b92915050565b60006060820190506135816000830186612e0f565b61358e6020830185612cfa565b61359b6040830184612cfa565b949350505050565b6000819050919050565b6000819050919050565b60006135d26135cd6135c8846135a3565b6135ad565b612d77565b9050919050565b6135e2816135b7565b82525050565b60006040820190506135fd60008301856135d9565b61360a6020830184612cfa565b9392505050565b600061361c82612c4e565b915061362783612c4e565b925082820390508181111561363f5761363e6134a1565b5b92915050565b600061365082612c4e565b915061365b83612c4e565b9250828201905080821115613673576136726134a1565b5b92915050565b600060408201905061368e6000830185612e0f565b61369b6020830184612cfa565b9392505050565b600060a0820190506136b76000830188612db8565b6136c46020830187612db8565b6136d16040830186612db8565b6136de6060830185612cfa565b6136eb6080830184612e0f565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006040820190506137396000830185612cfa565b6137466020830184612cfa565b9392505050565b6000819050919050565b600061377261376d6137688461374d565b6135ad565b612d77565b9050919050565b61378281613757565b82525050565b600060408201905061379d6000830185613779565b6137aa6020830184612cfa565b9392505050565b60006080820190506137c66000830187612db8565b6137d36020830186612d84565b6137e06040830185612db8565b6137ed6060830184612db8565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061385f82612c4e565b915061386a83612c4e565b92508261387a576138796136f5565b5b828204905092915050565b6000819050919050565b60006138aa6138a56138a084613885565b6135ad565b612d77565b9050919050565b6138ba8161388f565b82525050565b60006040820190506138d560008301856138b1565b6138e26020830184612cfa565b939250505056fea26469706673582212207a8acb8aebf0ca70a2a2ca038f649d366444e8ce4565803973e3ab0a015303d364736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c35780639ab24eb01161007c5780639ab24eb01461040b578063a9059cbb1461043b578063c3cda5201461046b578063d505accf14610487578063dd62ed3e146104a3578063f1127ed8146104d357610158565b806370a082311461031b5780637ecebe001461034b57806384b0196e1461037b5780638e539e8c1461039f57806391ddadf4146103cf57806395d89b41146103ed57610158565b80633a46b1a8116101155780633a46b1a81461023557806340c10f19146102655780634bf5d7e914610281578063587cde1e1461029f5780635c19a95c146102cf5780636fcfff45146102eb57610158565b806306fdde031461015d578063095ea7b31461017b57806318160ddd146101ab57806323b872dd146101c9578063313ce567146101f95780633644e51514610217575b600080fd5b610165610503565b6040516101729190612bc9565b60405180910390f35b61019560048036038101906101909190612c84565b610595565b6040516101a29190612cdf565b60405180910390f35b6101b36105b8565b6040516101c09190612d09565b60405180910390f35b6101e360048036038101906101de9190612d24565b6105c2565b6040516101f09190612cdf565b60405180910390f35b6102016105f1565b60405161020e9190612d93565b60405180910390f35b61021f6105fa565b60405161022c9190612dc7565b60405180910390f35b61024f600480360381019061024a9190612c84565b610609565b60405161025c9190612d09565b60405180910390f35b61027f600480360381019061027a9190612c84565b6106e2565b005b6102896106f0565b6040516102969190612bc9565b60405180910390f35b6102b960048036038101906102b49190612de2565b610784565b6040516102c69190612e1e565b60405180910390f35b6102e960048036038101906102e49190612de2565b6107ed565b005b61030560048036038101906103009190612de2565b610807565b6040516103129190612e58565b60405180910390f35b61033560048036038101906103309190612de2565b610819565b6040516103429190612d09565b60405180910390f35b61036560048036038101906103609190612de2565b610861565b6040516103729190612d09565b60405180910390f35b610383610873565b6040516103969796959493929190612f6c565b60405180910390f35b6103b960048036038101906103b49190612ff0565b61091d565b6040516103c69190612d09565b60405180910390f35b6103d76109b8565b6040516103e4919061303e565b60405180910390f35b6103f56109c7565b6040516104029190612bc9565b60405180910390f35b61042560048036038101906104209190612de2565b610a59565b6040516104329190612d09565b60405180910390f35b61045560048036038101906104509190612c84565b610ac5565b6040516104629190612cdf565b60405180910390f35b610485600480360381019061048091906130b1565b610ae8565b005b6104a1600480360381019061049c919061313e565b610bae565b005b6104bd60048036038101906104b891906131e0565b610cf6565b6040516104ca9190612d09565b60405180910390f35b6104ed60048036038101906104e8919061324c565b610d7d565b6040516104fa91906132ff565b60405180910390f35b60606003805461051290613349565b80601f016020809104026020016040519081016040528092919081815260200182805461053e90613349565b801561058b5780601f106105605761010080835404028352916020019161058b565b820191906000526020600020905b81548152906001019060200180831161056e57829003601f168201915b5050505050905090565b6000806105a0610dc3565b90506105ad818585610dcb565b600191505092915050565b6000600254905090565b6000806105cd610dc3565b90506105da858285610ddd565b6105e5858585610e71565b60019150509392505050565b60006012905090565b6000610604610f65565b905090565b6000806106146109b8565b90508065ffffffffffff1683106106645782816040517fecd3f81e00000000000000000000000000000000000000000000000000000000815260040161065b92919061337a565b60405180910390fd5b6106bd6106708461101c565b600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061107690919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1691505092915050565b6106ec8282611170565b5050565b60606106fa6111f2565b65ffffffffffff1661070a6109b8565b65ffffffffffff1614610749576040517f6ff0714000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280601d81526020017f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000815250905090565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107f7610dc3565b90506108038183611202565b5050565b600061081282611316565b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061086c8261136e565b9050919050565b600060608060008060006060610887611380565b61088f6113bb565b46306000801b600067ffffffffffffffff8111156108b0576108af6133a3565b5b6040519080825280602002602001820160405280156108de5781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b6000806109286109b8565b90508065ffffffffffff1683106109785782816040517fecd3f81e00000000000000000000000000000000000000000000000000000000815260040161096f92919061337a565b60405180910390fd5b6109946109848461101c565b600a61107690919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b60006109c26111f2565b905090565b6060600480546109d690613349565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290613349565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b5050505050905090565b6000610aa2600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113f6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b600080610ad0610dc3565b9050610add818585610e71565b600191505092915050565b83421115610b2d57836040517f4683af0e000000000000000000000000000000000000000000000000000000008152600401610b249190612d09565b60405180910390fd5b6000610b8f610b877fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610b6c94939291906133d2565b6040516020818303038152906040528051906020012061145e565b858585611478565b9050610b9b81876114a8565b610ba58188611202565b50505050505050565b83421115610bf357836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610bea9190612d09565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610c228c611500565b89604051602001610c3896959493929190613417565b6040516020818303038152906040528051906020012090506000610c5b8261145e565b90506000610c6b82878787611478565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cdf57808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401610cd6929190613478565b60405180910390fd5b610cea8a8a8a610dcb565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610d85612afb565b610d8f8383611557565b905092915050565b60008183610da591906134d0565b905092915050565b60008183610dbb919061351e565b905092915050565b600033905090565b610dd883838360016115b8565b505050565b6000610de98484610cf6565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e6b5781811015610e5b578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610e529392919061356c565b60405180910390fd5b610e6a848484840360006115b8565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ee35760006040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610eda9190612e1e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f555760006040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610f4c9190612e1e565b60405180910390fd5b610f6083838361178f565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610fe157507f000000000000000000000000000000000000000000000000000000000000000046145b1561100e577f00000000000000000000000000000000000000000000000000000000000000009050611019565b61101661179f565b90505b90565b600065ffffffffffff801682111561106e576030826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016110659291906135e8565b60405180910390fd5b819050919050565b6000808360000180549050905060008082905060058311156110fe57600061109d84611835565b846110a89190613611565b90506110b7876000018261192e565b60000160009054906101000a900465ffffffffffff1665ffffffffffff168665ffffffffffff1610156110ec578091506110fc565b6001816110f99190613645565b92505b505b600061110f87600001878585611943565b905060008114611161576111328760000160018361112d9190613611565b61192e565b60000160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611164565b60005b94505050505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111e25760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016111d99190612e1e565b60405180910390fd5b6111ee6000838361178f565b5050565b60006111fd4361101c565b905090565b600061120d83610784565b905081600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a4611311818361130c866119bc565b6119ce565b505050565b6000611367611362600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611c47565b611c58565b9050919050565b600061137982611cb0565b9050919050565b60606113b660057f0000000000000000000000000000000000000000000000000000000000000000611cf990919063ffffffff16565b905090565b60606113f160067f0000000000000000000000000000000000000000000000000000000000000000611cf990919063ffffffff16565b905090565b6000808260000180549050905060008114611453576114248360000160018361141f9190613611565b61192e565b60000160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611456565b60005b915050919050565b600061147161146b610f65565b83611da9565b9050919050565b60008060008061148a88888888611dea565b92509250925061149a8282611ede565b829350505050949350505050565b60006114b383611500565b90508082146114fb5782816040517f752d88c00000000000000000000000000000000000000000000000000000000081526004016114f2929190613679565b60405180910390fd5b505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050559050919050565b61155f612afb565b6115b082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061204290919063ffffffff16565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361162a5760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016116219190612e1e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169c5760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016116939190612e1e565b60405180910390fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508015611789578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516117809190612d09565b60405180910390a35b50505050565b61179a838383612117565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000463060405160200161181a9594939291906136a2565b60405160208183030381529060405280519060200120905090565b60008082036118475760009050611929565b60006001611854846121c8565b901c6001901b9050600181848161186e5761186d6136f5565b5b048201901c90506001818481611887576118866136f5565b5b048201901c905060018184816118a05761189f6136f5565b5b048201901c905060018184816118b9576118b86136f5565b5b048201901c905060018184816118d2576118d16136f5565b5b048201901c905060018184816118eb576118ea6136f5565b5b048201901c90506001818481611904576119036136f5565b5b048201901c90506119258182858161191f5761191e6136f5565b5b046122a9565b9150505b919050565b60008260005281602060002001905092915050565b60005b818310156119b157600061195a84846122c2565b90508465ffffffffffff1661196f878361192e565b60000160009054906101000a900465ffffffffffff1665ffffffffffff16111561199b578092506119ab565b6001816119a89190613645565b93505b50611946565b819050949350505050565b60006119c782610819565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611a0a5750600081115b15611c4257600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b2857600080611a99600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610dad611a94866122e8565b612356565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611b1d929190613724565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611c4157600080611bb2600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610d97611bad866122e8565b612356565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611c36929190613724565b60405180910390a250505b5b505050565b600081600001805490509050919050565b600063ffffffff8016821115611ca8576020826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401611c9f929190613788565b60405180910390fd5b819050919050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060ff60001b8314611d1657611d0f83612396565b9050611da3565b818054611d2290613349565b80601f0160208091040260200160405190810160405280929190818152602001828054611d4e90613349565b8015611d9b5780601f10611d7057610100808354040283529160200191611d9b565b820191906000526020600020905b815481529060010190602001808311611d7e57829003601f168201915b505050505090505b92915050565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b60008060007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08460001c1115611e2a576000600385925092509250611ed4565b600060018888888860405160008152602001604052604051611e4f94939291906137b1565b6020604051602081039080840390855afa158015611e71573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ec557600060016000801b93509350935050611ed4565b8060008060001b935093509350505b9450945094915050565b60006003811115611ef257611ef16137f6565b5b826003811115611f0557611f046137f6565b5b031561203e5760016003811115611f1f57611f1e6137f6565b5b826003811115611f3257611f316137f6565b5b03611f69576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611f7d57611f7c6137f6565b5b826003811115611f9057611f8f6137f6565b5b03611fd5578060001c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611fcc9190612d09565b60405180910390fd5b600380811115611fe857611fe76137f6565b5b826003811115611ffb57611ffa6137f6565b5b0361203d57806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016120349190612dc7565b60405180910390fd5b5b5050565b61204a612afb565b826000018263ffffffff168154811061206657612065613825565b5b906000526020600020016040518060400160405290816000820160009054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b61212283838361240a565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036121b85760006121606105b8565b9050600061216c61262f565b9050808211156121b55781816040517f1cb15d260000000000000000000000000000000000000000000000000000000081526004016121ac929190613724565b60405180910390fd5b50505b6121c3838383612653565b505050565b600080600090506000608084901c11156121ea57608083901c92506080810190505b6000604084901c111561220557604083901c92506040810190505b6000602084901c111561222057602083901c92506020810190505b6000601084901c111561223b57601083901c92506010810190505b6000600884901c111561225657600883901c92506008810190505b6000600484901c111561227157600483901c92506004810190505b6000600284901c111561228c57600283901c92506002810190505b6000600184901c11156122a0576001810190505b80915050919050565b60008183106122b857816122ba565b825b905092915050565b600060028284186122d39190613854565b8284166122e09190613645565b905092915050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff801682111561234e5760d0826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016123459291906138c0565b60405180910390fd5b819050919050565b60008061238a6123646109b8565b61237a612370886113f6565b868863ffffffff16565b8761270d9092919063ffffffff16565b91509150935093915050565b606060006123a38361272a565b90506000602067ffffffffffffffff8111156123c2576123c16133a3565b5b6040519080825280601f01601f1916602001820160405280156123f45781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361245c5780600260008282546124509190613645565b9250508190555061252f565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156124e8578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016124df9392919061356c565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361257857806002600082825403925050819055506125c5565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126229190612d09565b60405180910390a3505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126a05761269d600a610d97612698846122e8565b612356565b50505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126ed576126ea600a610dad6126e5846122e8565b612356565b50505b6127086126f984610784565b61270284610784565b836119ce565b505050565b60008061271e85600001858561277a565b91509150935093915050565b60008060ff8360001c169050601f811115612771576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b6000806000858054905090506000811115612a0b5760006127a7876001846127a29190613611565b61192e565b6040518060400160405290816000820160009054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16816000015165ffffffffffff161115612896576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16816000015165ffffffffffff160361291a57846128c8886001856128c39190613611565b61192e565b60000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506129fa565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050612af3565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b6040518060400160405280600065ffffffffffff168152602001600079ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600081519050919050565b600082825260208201905092915050565b60005b83811015612b73578082015181840152602081019050612b58565b60008484015250505050565b6000601f19601f8301169050919050565b6000612b9b82612b39565b612ba58185612b44565b9350612bb5818560208601612b55565b612bbe81612b7f565b840191505092915050565b60006020820190508181036000830152612be38184612b90565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612c1b82612bf0565b9050919050565b612c2b81612c10565b8114612c3657600080fd5b50565b600081359050612c4881612c22565b92915050565b6000819050919050565b612c6181612c4e565b8114612c6c57600080fd5b50565b600081359050612c7e81612c58565b92915050565b60008060408385031215612c9b57612c9a612beb565b5b6000612ca985828601612c39565b9250506020612cba85828601612c6f565b9150509250929050565b60008115159050919050565b612cd981612cc4565b82525050565b6000602082019050612cf46000830184612cd0565b92915050565b612d0381612c4e565b82525050565b6000602082019050612d1e6000830184612cfa565b92915050565b600080600060608486031215612d3d57612d3c612beb565b5b6000612d4b86828701612c39565b9350506020612d5c86828701612c39565b9250506040612d6d86828701612c6f565b9150509250925092565b600060ff82169050919050565b612d8d81612d77565b82525050565b6000602082019050612da86000830184612d84565b92915050565b6000819050919050565b612dc181612dae565b82525050565b6000602082019050612ddc6000830184612db8565b92915050565b600060208284031215612df857612df7612beb565b5b6000612e0684828501612c39565b91505092915050565b612e1881612c10565b82525050565b6000602082019050612e336000830184612e0f565b92915050565b600063ffffffff82169050919050565b612e5281612e39565b82525050565b6000602082019050612e6d6000830184612e49565b92915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b612ea881612e73565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612ee381612c4e565b82525050565b6000612ef58383612eda565b60208301905092915050565b6000602082019050919050565b6000612f1982612eae565b612f238185612eb9565b9350612f2e83612eca565b8060005b83811015612f5f578151612f468882612ee9565b9750612f5183612f01565b925050600181019050612f32565b5085935050505092915050565b600060e082019050612f81600083018a612e9f565b8181036020830152612f938189612b90565b90508181036040830152612fa78188612b90565b9050612fb66060830187612cfa565b612fc36080830186612e0f565b612fd060a0830185612db8565b81810360c0830152612fe28184612f0e565b905098975050505050505050565b60006020828403121561300657613005612beb565b5b600061301484828501612c6f565b91505092915050565b600065ffffffffffff82169050919050565b6130388161301d565b82525050565b6000602082019050613053600083018461302f565b92915050565b61306281612d77565b811461306d57600080fd5b50565b60008135905061307f81613059565b92915050565b61308e81612dae565b811461309957600080fd5b50565b6000813590506130ab81613085565b92915050565b60008060008060008060c087890312156130ce576130cd612beb565b5b60006130dc89828a01612c39565b96505060206130ed89828a01612c6f565b95505060406130fe89828a01612c6f565b945050606061310f89828a01613070565b935050608061312089828a0161309c565b92505060a061313189828a0161309c565b9150509295509295509295565b600080600080600080600060e0888a03121561315d5761315c612beb565b5b600061316b8a828b01612c39565b975050602061317c8a828b01612c39565b965050604061318d8a828b01612c6f565b955050606061319e8a828b01612c6f565b94505060806131af8a828b01613070565b93505060a06131c08a828b0161309c565b92505060c06131d18a828b0161309c565b91505092959891949750929550565b600080604083850312156131f7576131f6612beb565b5b600061320585828601612c39565b925050602061321685828601612c39565b9150509250929050565b61322981612e39565b811461323457600080fd5b50565b60008135905061324681613220565b92915050565b6000806040838503121561326357613262612beb565b5b600061327185828601612c39565b925050602061328285828601613237565b9150509250929050565b6132958161301d565b82525050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6132ca8161329b565b82525050565b6040820160008201516132e6600085018261328c565b5060208201516132f960208501826132c1565b50505050565b600060408201905061331460008301846132d0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061336157607f821691505b6020821081036133745761337361331a565b5b50919050565b600060408201905061338f6000830185612cfa565b61339c602083018461302f565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080820190506133e76000830187612db8565b6133f46020830186612e0f565b6134016040830185612cfa565b61340e6060830184612cfa565b95945050505050565b600060c08201905061342c6000830189612db8565b6134396020830188612e0f565b6134466040830187612e0f565b6134536060830186612cfa565b6134606080830185612cfa565b61346d60a0830184612cfa565b979650505050505050565b600060408201905061348d6000830185612e0f565b61349a6020830184612e0f565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006134db8261329b565b91506134e68361329b565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613518576135176134a1565b5b92915050565b60006135298261329b565b91506135348361329b565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613566576135656134a1565b5b92915050565b60006060820190506135816000830186612e0f565b61358e6020830185612cfa565b61359b6040830184612cfa565b949350505050565b6000819050919050565b6000819050919050565b60006135d26135cd6135c8846135a3565b6135ad565b612d77565b9050919050565b6135e2816135b7565b82525050565b60006040820190506135fd60008301856135d9565b61360a6020830184612cfa565b9392505050565b600061361c82612c4e565b915061362783612c4e565b925082820390508181111561363f5761363e6134a1565b5b92915050565b600061365082612c4e565b915061365b83612c4e565b9250828201905080821115613673576136726134a1565b5b92915050565b600060408201905061368e6000830185612e0f565b61369b6020830184612cfa565b9392505050565b600060a0820190506136b76000830188612db8565b6136c46020830187612db8565b6136d16040830186612db8565b6136de6060830185612cfa565b6136eb6080830184612e0f565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006040820190506137396000830185612cfa565b6137466020830184612cfa565b9392505050565b6000819050919050565b600061377261376d6137688461374d565b6135ad565b612d77565b9050919050565b61378281613757565b82525050565b600060408201905061379d6000830185613779565b6137aa6020830184612cfa565b9392505050565b60006080820190506137c66000830187612db8565b6137d36020830186612d84565b6137e06040830185612db8565b6137ed6060830184612db8565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061385f82612c4e565b915061386a83612c4e565b92508261387a576138796136f5565b5b828204905092915050565b6000819050919050565b60006138aa6138a56138a084613885565b6135ad565b612d77565b9050919050565b6138ba8161388f565b82525050565b60006040820190506138d560008301856138b1565b6138e26020830184612cfa565b939250505056fea26469706673582212207a8acb8aebf0ca70a2a2ca038f649d366444e8ce4565803973e3ab0a015303d364736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/src/modules/creator/deployment/router.tsx b/src/modules/creator/deployment/router.tsx deleted file mode 100644 index 554596bf..00000000 --- a/src/modules/creator/deployment/router.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from "react" -import { Redirect, Route, Switch, useRouteMatch } from "react-router-dom" -import { Deployment } from "." -import { ConfigContract } from "./steps/Config" -import { ContractDistribution } from "./steps/Distribution" -import { ContractSummary } from "./steps/Summary" -import { Ownership } from "./steps/Ownership" -import { Success } from "./steps/Success" - -export const TokenDeploymentRouter = (): JSX.Element => { - const match = useRouteMatch() - - return ( - - - - - - - - - - - - - - - - - - - - - - ) -} diff --git a/src/modules/creator/deployment/state/utils.ts b/src/modules/creator/deployment/state/utils.ts deleted file mode 100644 index d75414f6..00000000 --- a/src/modules/creator/deployment/state/utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -import BigNumber from "bignumber.js" - -export const numberWithCommas = (x: number | BigNumber) => { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") -} diff --git a/src/modules/creator/router.tsx b/src/modules/creator/router.tsx index bf427bf5..9555c579 100644 --- a/src/modules/creator/router.tsx +++ b/src/modules/creator/router.tsx @@ -3,9 +3,7 @@ import { Redirect, Route, Switch, useRouteMatch } from "react-router-dom" import { DAOList } from "modules/explorer/pages/DAOList" import { DAORouter } from "modules/explorer/pages/DAO/router" import { DAOCreate } from "." -import { Deployment } from "./deployment" -import { TokenDeploymentRouter } from "./deployment/router" -import { DeploymentProvider } from "./deployment/state/context" +import { TokenDeploymentRouter } from "./token/router" export const DAOCreatorRouter = (): JSX.Element => { const match = useRouteMatch() @@ -16,9 +14,7 @@ export const DAOCreatorRouter = (): JSX.Element => { - - - + diff --git a/src/modules/creator/token/etherlink/index.tsx b/src/modules/creator/token/etherlink/index.tsx new file mode 100644 index 00000000..ecba71d0 --- /dev/null +++ b/src/modules/creator/token/etherlink/index.tsx @@ -0,0 +1,87 @@ +import React, { useContext, useMemo } from "react" +import { Box, Grid, Step, StepLabel, useMediaQuery, useTheme } from "@material-ui/core" +import { Navbar } from "modules/common/Toolbar" +import ProgressBar from "react-customizable-progressbar" +import { DeploymentStepRouter, STEPS, useDeploymentStepNumber } from "./steps" +import { StepInfo } from "./state" +import { useHistory } from "react-router-dom" +import { NavigationBar } from "../../components/NavigationBar" +import { DeploymentContext } from "./state/context" +import { + PageContainer, + PageContent, + ProgressContainer, + IndicatorValue, + FAQClickText, + FAQClickToAction, + StyledStepper, + StepContentContainer +} from "../ui" + +export const EtherlinkTokenDeployment: React.FC = () => { + const creator = useContext(DeploymentContext) + const { back, next } = creator.state + + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down("sm")) + + const history = useHistory() + const step = useDeploymentStepNumber() + const progress = useMemo(() => step * 45, [step]) + + const goToFAQ = (): void => { + history.push("/faq") + } + + return ( + + + + {!isMobile && ( + + + + + {progress === 0.5 ? 0 : step * 45}% + + + + + New to DAOs? + Read our FAQ + + + + {STEPS.map(({ title, path }: StepInfo, index: number) => ( + + (index < step ? history.push(path) : null)} icon={index + 1}> + {title} + + + ))} + + + + )} + + + + + + + + + + {step < 3 && } + + + + ) +} diff --git a/src/modules/creator/token/etherlink/state/context.tsx b/src/modules/creator/token/etherlink/state/context.tsx new file mode 100644 index 00000000..75f1cff1 --- /dev/null +++ b/src/modules/creator/token/etherlink/state/context.tsx @@ -0,0 +1,114 @@ +import React, { createContext, useReducer, Dispatch, useMemo } from "react" +import useLocalStorage from "modules/common/hooks/useLocalStorage" +import { DeploymentAction, DeploymentState, TokenContractParams, ActionTypes } from "./types" +import BigNumber from "bignumber.js" + +const deploymentStatus = { + deploying: false, + successful: false +} + +const LOCAL_STORAGE_KEY = "deploymentParams" + +export const INITIAL_TOKEN_STATE: TokenContractParams = { + tokenSettings: { + name: "", + description: "", + totalSupply: null, + decimals: null, + symbol: "", + icon: "" + }, + tokenDistribution: { + holders: [ + { + walletAddress: "", + amount: null + } + ], + totalAmount: new BigNumber(0) + } +} + +export const INITIAL_STATE: DeploymentState = { + data: INITIAL_TOKEN_STATE, + deploymentStatus +} + +const DeploymentContext = createContext<{ + state: DeploymentState + dispatch: Dispatch + updateCache: (value: TokenContractParams) => void +}>({ + state: INITIAL_STATE, + dispatch: () => null, + updateCache: () => null +}) + +export const reducer = (state: DeploymentState, action: DeploymentAction): DeploymentState => { + switch (action.type) { + case ActionTypes.UPDATE_DEPLOYMENT_STATUS: + const { contract, deploying } = action.status + state = { + ...state, + deploymentStatus: { + contract, + deploying, + successful: false + } + } + return state + case ActionTypes.UPDATE_NAVIGATION_BAR: + state = { + ...state, + next: action.next, + back: action.back + } + return state + case ActionTypes.UPDATE_TOKEN_SETTINGS: + state = { + ...state, + data: { + ...state.data, + tokenSettings: action.contractInfo + } + } + return state + case ActionTypes.UPDATE_TOKEN_DISTRIBUTION: + state = { + ...state, + data: { + ...state.data, + tokenDistribution: action.distribution + } + } + return state + case ActionTypes.CLEAR_CACHE: + window.localStorage.removeItem(LOCAL_STORAGE_KEY) + state = { + ...INITIAL_STATE, + deploymentStatus: { + ...INITIAL_STATE.deploymentStatus, + successful: true + } + } + return state + } +} + +const DeploymentProvider: React.FC = ({ children }) => { + const [data, updateCache] = useLocalStorage(LOCAL_STORAGE_KEY, INITIAL_STATE.data) + + const stateWithCache = { + ...INITIAL_STATE, + data + } + + const [state, dispatch] = useReducer(reducer, stateWithCache) + const contextValue = useMemo(() => { + return { state, dispatch } + }, [state, dispatch]) + return {children} +} + +export { DeploymentProvider, DeploymentContext } diff --git a/src/modules/creator/token/etherlink/state/index.ts b/src/modules/creator/token/etherlink/state/index.ts new file mode 100644 index 00000000..8234ebd8 --- /dev/null +++ b/src/modules/creator/token/etherlink/state/index.ts @@ -0,0 +1,3 @@ +export * from "modules/creator/state/context" +export * from "modules/creator/state/types" +export * from "modules/creator/state/utils" diff --git a/src/modules/creator/token/etherlink/state/types.ts b/src/modules/creator/token/etherlink/state/types.ts new file mode 100644 index 00000000..74e690a5 --- /dev/null +++ b/src/modules/creator/token/etherlink/state/types.ts @@ -0,0 +1,100 @@ +import BigNumber from "bignumber.js" +import { NavigationBarProps } from "modules/creator/state/types" + +export type TokenContractSettings = { + name: string + description: string + totalSupply: number | null + decimals: number | null + symbol: string + icon: string +} + +export type TokenDistributionSettings = { + holders: Holder[] + totalAmount: BigNumber +} + +export type Holder = { + walletAddress: string + amount: number | null +} + +export interface TokenContractParams { + tokenSettings: TokenContractSettings + tokenDistribution: TokenDistributionSettings +} + +export type ErrorValues = Partial> + +type DeploymentStatus = { + deploying: boolean + successful: boolean + contract?: string +} + +export type DeploymentState = { + data: TokenContractParams + deploymentStatus: DeploymentStatus +} & NavigationBarProps + +export interface StepInfo { + title: string + index: number + path: string +} + +function updateTokenSettings(contractInfo: TokenContractSettings) { + return { + type: ActionTypes.UPDATE_TOKEN_SETTINGS, + contractInfo + } +} + +function updateTokenDistribution(distribution: TokenDistributionSettings) { + return { + type: ActionTypes.UPDATE_TOKEN_DISTRIBUTION, + distribution + } +} + +function updateDeploymentStatus({ deploying, contract }: DeploymentStatus) { + return { + type: ActionTypes.UPDATE_DEPLOYMENT_STATUS, + status: { deploying, contract } + } +} + +function updateNavigationBar(props: NavigationBarProps) { + return { + type: ActionTypes.UPDATE_NAVIGATION_BAR, + ...props + } +} + +function clearCache() { + return { + type: ActionTypes.CLEAR_CACHE + } +} + +export type DeploymentAction = ReturnType< + | typeof updateTokenSettings + | typeof updateDeploymentStatus + | typeof clearCache + | typeof updateTokenDistribution + | typeof updateNavigationBar +> + +export enum ActionTypes { + UPDATE_NAVIGATION_BAR = "UPDATE_NAVIGATION_BAR", + UPDATE_TOKEN_SETTINGS = "UPDATE_TOKEN_SETTINGS", + UPDATE_TOKEN_DISTRIBUTION = "UPDATE_TOKEN_DISTRIBUTION", + UPDATE_DEPLOYMENT_STATUS = "UPDATE_DEPLOYMENT_STATUS", + CLEAR_CACHE = "CLEAR_CACHE" +} +export interface TokenHolder { + address: string + balance: number + name?: string +} diff --git a/src/modules/creator/token/etherlink/steps/Config.tsx b/src/modules/creator/token/etherlink/steps/Config.tsx new file mode 100644 index 00000000..ac73d233 --- /dev/null +++ b/src/modules/creator/token/etherlink/steps/Config.tsx @@ -0,0 +1,221 @@ +import { Grid, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { Field, Form, Formik, FormikErrors, getIn } from "formik" +import React, { useContext, useEffect } from "react" +import { useHistory, useRouteMatch } from "react-router-dom" +import { DeploymentContext } from "../state/context" +import { ActionTypes, TokenContractSettings } from "../state/types" +import { FieldChange, handleChange, handleNegativeInput } from "modules/creator/utils" +import { + Title, + CustomTextarea, + CustomFormikTextField, + CustomInputContainer, + ErrorText, + TextareaContainer +} from "../../ui" + +const validateForm = (values: TokenContractSettings) => { + const errors: FormikErrors = {} + + if (!values.name) { + errors.name = "Required" + } + + // if (!values.description) { + // errors.description = "Required" + // } + + if (!values.totalSupply || values.totalSupply === null) { + errors.totalSupply = "Required" + } + + if (!values.decimals || values.decimals === null) { + errors.decimals = "Required" + } + + if (!values.symbol) { + errors.symbol = "Required" + } + + return errors +} + +const TokenSettingsForm = ({ submitForm, values, errors, touched, setFieldValue }: any) => { + const { dispatch } = useContext(DeploymentContext) + const match = useRouteMatch() + const history = useHistory() + const theme = useTheme() + const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) + + useEffect(() => { + if (values) { + dispatch({ + type: ActionTypes.UPDATE_NAVIGATION_BAR, + next: { + handler: () => { + submitForm(values) + }, + text: "Continue" + }, + back: { + text: "Back", + handler: () => history.push("/creator/ownership") + } + }) + } + }, [dispatch, errors, history, match.path, match.url, submitForm, values]) + + return ( + <> + + + + {" "} + Contract Name{" "} + + + + + {errors.name && touched.name ? {errors.name} : null} + + + + + {" "} + Description{" "} + + + {/* + + {() => ( + { + setFieldValue("description", newValue.target.value) + }} + /> + )} + + + {errors.description && touched.description ? {errors.description} : null} */} + + + + + {" "} + Supply{" "} + + + handleNegativeInput(e)} + /> + + {errors.totalSupply && touched.totalSupply ? {errors.totalSupply} : null} + + + + {" "} + Decimals{" "} + + + handleChange(e)} + /> + + {errors.decimals && touched.decimals ? {errors.decimals} : null} + + + + + {/* + + {" "} + Icon{" "} + + + + + */} + + + {" "} + Symbol{" "} + + + + + {errors.symbol && touched.symbol ? {errors.symbol} : null} + + + + + ) +} + +export const ConfigContract: React.FC = () => { + const { state, dispatch, updateCache } = useContext(DeploymentContext) + const { tokenSettings } = state.data + const history = useHistory() + + const saveStepInfo = (values: TokenContractSettings, { setSubmitting }: { setSubmitting: (b: boolean) => void }) => { + const newValues: TokenContractSettings = { ...values } + const newState = { + ...state.data, + tokenSettings: newValues + } + updateCache(newState) + setSubmitting(true) + dispatch({ type: ActionTypes.UPDATE_TOKEN_SETTINGS, contractInfo: newValues }) + history.push(`distribution`) + } + + return ( + <> + + + + Configure Etherlink Token Contract + + + + + {({ submitForm, isSubmitting, setFieldValue, values, errors, touched, setFieldTouched }) => { + return ( +
+ + + ) + }} +
+
+ + ) +} diff --git a/src/modules/creator/token/etherlink/steps/Distribution.tsx b/src/modules/creator/token/etherlink/steps/Distribution.tsx new file mode 100644 index 00000000..f6c0d2b8 --- /dev/null +++ b/src/modules/creator/token/etherlink/steps/Distribution.tsx @@ -0,0 +1,300 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Grid, IconButton, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { Field, FieldArray, Form, Formik, FormikErrors } from "formik" +import React, { useContext, useEffect } from "react" +import { useHistory, useRouteMatch } from "react-router-dom" +import { DeploymentContext } from "../state/context" +import { ActionTypes, Holder, TokenDistributionSettings } from "../state/types" +import BigNumber from "bignumber.js" +import { numberWithCommas } from "utils" +import { useTezos } from "services/beacon/hooks/useTezos" +import { FieldChange, handleNegativeInput } from "modules/creator/utils" +import AddCircleIcon from "@mui/icons-material/AddCircle" +import { validateContractAddress, validateAddress } from "@taquito/utils" +import { isAddress as isEtherAddress } from "ethers" +import { + CustomFormikTextField, + AddButtonContainer, + CustomAmountContainer, + CustomInputContainer, + RemoveButton, + AmountText, + ErrorText +} from "../../ui" + +const hasDuplicates = (options: Holder[]) => { + const trimOptions = options.map(option => option.walletAddress.trim()) + return new Set(trimOptions).size !== trimOptions.length +} + +const validateForm = (values: TokenDistributionSettings) => { + const errors: FormikErrors = {} + + values.holders.forEach((holder: Holder, index: number) => { + if (values.holders[index].walletAddress && !values.holders[index].amount) { + errors.holders = "Required" + } + if (!values.holders[index].walletAddress && values.holders[index].amount) { + errors.holders = "Required" + } + if (values.holders.length > 0 && hasDuplicates(values.holders)) { + errors.holders = "Duplicate wallets are not allowed" + } + if (values.totalAmount && values.totalAmount.minus(new BigNumber(getTotal(values.holders))) < new BigNumber(0)) { + errors.totalAmount = "Available balance has to be greater that the total supply" + } + if (values.totalAmount && values.totalAmount.gt(new BigNumber(getTotal(values.holders)))) { + errors.totalAmount = "Total Supply not fully allocated" + } + if (!isEtherAddress(values.holders[index].walletAddress)) { + errors.holders = "Invalid address" + } + }) + + return errors +} + +const TokenSettingsForm = ({ submitForm, values, errors, touched }: any) => { + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down("sm")) + + const newValue: Holder = { walletAddress: "", amount: null } + + const { dispatch } = useContext(DeploymentContext) + const match = useRouteMatch() + const history = useHistory() + + useEffect(() => { + if (values) { + dispatch({ + type: ActionTypes.UPDATE_NAVIGATION_BAR, + next: { + text: "Continue", + handler: () => { + submitForm(values) + } + }, + back: { + text: "Back", + handler: () => history.push(`config`) + } + }) + } + }, [dispatch, errors, history, match.path, match.url, submitForm, values]) + + return ( + <> + + ( +
+ {values.holders && values.holders.length > 0 + ? values.holders.map((holder: any, index: number) => ( +
+ {isMobile ? Wallet address : null} + + + + + + {isMobile ? ( + + Amount + + ) : null} + + + handleNegativeInput(e)} + InputProps={{ + endAdornment: + index !== 0 ? ( + { + if (index !== 0) { + arrayHelpers.remove(index) + } + }} + /> + ) : ( + + ) + }} + /> + + + {index === values.holders.length - 1 ? ( + + arrayHelpers.insert(values.holders.length, newValue)} + > + + + arrayHelpers.insert(values.holders.length, newValue)} + color={"secondary"} + > + Add + + + ) : null} + +
+ )) + : null} + {errors.holders && touched.holders ? {errors.holders} : null} +
+ )} + /> +
+ + ) +} + +const getTotal = (holders: Holder[]) => { + let total = 0 + holders.forEach(holder => (total += Number(holder.amount))) + return total +} + +export const ContractDistribution: React.FC = () => { + const { state, dispatch, updateCache } = useContext(DeploymentContext) + const { tokenDistribution, tokenSettings } = state.data + const history = useHistory() + const { account } = useTezos() + + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down("sm")) + + tokenDistribution.totalAmount = new BigNumber(Number(tokenSettings.totalSupply)) + + const saveStepInfo = ( + values: TokenDistributionSettings, + { setSubmitting }: { setSubmitting: (b: boolean) => void } + ) => { + const newValues: TokenDistributionSettings = { ...values } + + if (newValues.holders.length === 1 && newValues.holders[0].walletAddress === "") { + newValues.holders[0].walletAddress = account + newValues.holders[0].amount = newValues.totalAmount.toNumber() + } + + const newState = { + ...state.data, + tokenDistribution: newValues + } + updateCache(newState) + setSubmitting(true) + dispatch({ type: ActionTypes.UPDATE_TOKEN_DISTRIBUTION, distribution: newValues }) + history.push(`summary`) + } + + return ( + + + + Initial Token Distribution + + + + {({ submitForm, isSubmitting, setFieldValue, values, errors, touched, setFieldTouched }) => { + return ( +
+ + + + + Total supply:{" "} + + + {" "} + {numberWithCommas(values.totalAmount)}{" "} + + + + + Available: + + + {" "} + {numberWithCommas( + values.totalAmount && values.totalAmount.minus(new BigNumber(getTotal(values.holders))) + )} + + + + {errors.totalAmount && touched.totalAmount ? ( + {errors.totalAmount} + ) : null} + + + + + Wallet Address + + + + + Amount + + + + + +
+ ) + }} +
+
+ ) +} diff --git a/src/modules/creator/deployment/steps/Ownership.tsx b/src/modules/creator/token/etherlink/steps/Ownership.tsx similarity index 62% rename from src/modules/creator/deployment/steps/Ownership.tsx rename to src/modules/creator/token/etherlink/steps/Ownership.tsx index 92999427..eb09f319 100644 --- a/src/modules/creator/deployment/steps/Ownership.tsx +++ b/src/modules/creator/token/etherlink/steps/Ownership.tsx @@ -1,83 +1,20 @@ import React from "react" -import { Grid, Link, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { Grid, useMediaQuery, useTheme } from "@material-ui/core" import { MainButton } from "modules/common/MainButton" import { Navbar } from "modules/common/Toolbar" import { useHistory } from "react-router-dom" import { useTezos } from "services/beacon/hooks/useTezos" - -const PageContainer = styled(Grid)(({ theme }) => ({ - background: theme.palette.primary.main -})) - -const PageContent = styled(Grid)(({ theme }) => ({ - width: "1000px", - height: "100%", - margin: "auto", - padding: "28px 0", - flexDirection: "row", - paddingTop: 0, - ["@media (max-width:1167px)"]: { - width: "86vw" - }, - [theme.breakpoints.down("sm")]: { - marginTop: 10 - } -})) - -const Title = styled(Typography)(({ theme }) => ({ - fontSize: 32, - fontWeight: 600, - textAlign: "center", - [theme.breakpoints.down("sm")]: { - fontSize: 26 - } -})) - -const CardContainer = styled(Grid)(({ theme }) => ({ - background: theme.palette.primary.dark, - gap: 32, - borderRadius: 8, - padding: "40px 48px", - [theme.breakpoints.down("sm")]: { - padding: "30px 38px" - } -})) - -const DescriptionContainer = styled(Grid)(({ theme }) => ({ - [theme.breakpoints.down("sm")]: { - paddingLeft: "4%", - paddingRight: "4%" - } -})) - -const OptionsContainer = styled(Grid)(({ theme }) => ({ - [theme.breakpoints.down("sm")]: { - paddingLeft: "4%", - paddingRight: "4%" - } -})) - -const ChoicesContainer = styled(Grid)(({ theme }) => ({ - [theme.breakpoints.down("sm")]: { - gap: 32 - } -})) - -const DescriptionText = styled(Typography)(({ theme }) => ({ - fontWeight: 300, - fontSize: 18, - color: theme.palette.text.secondary, - [theme.breakpoints.down("sm")]: { - fontSize: 14 - } -})) - -const OptionButton = styled(Link)(({ theme }) => ({ - [theme.breakpoints.down("sm")]: { - display: "flex", - textAlign: "center" - } -})) +import { + CenterTitle, + PageContainer, + PageContent, + DescriptionText, + CardContainer, + DescriptionContainer, + OptionsContainer, + ChoicesContainer, + OptionButton +} from "../../ui" export const Ownership: React.FC = () => { const theme = useTheme() @@ -92,7 +29,7 @@ export const Ownership: React.FC = () => { - Do you already have a governance token? + Do you already have a governance token? diff --git a/src/modules/creator/deployment/steps/Success.tsx b/src/modules/creator/token/etherlink/steps/Success.tsx similarity index 64% rename from src/modules/creator/deployment/steps/Success.tsx rename to src/modules/creator/token/etherlink/steps/Success.tsx index fe8080de..df73b36c 100644 --- a/src/modules/creator/deployment/steps/Success.tsx +++ b/src/modules/creator/token/etherlink/steps/Success.tsx @@ -1,82 +1,19 @@ import React, { useEffect, useState } from "react" -import { Grid, Link, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { Grid, Typography, useMediaQuery, useTheme } from "@material-ui/core" import { MainButton } from "modules/common/MainButton" import { Navbar } from "modules/common/Toolbar" import { useHistory, useLocation } from "react-router-dom" import { Blockie } from "modules/common/Blockie" import { CopyAddress } from "modules/common/CopyAddress" - -const PageContainer = styled(Grid)(({ theme }) => ({ - background: theme.palette.primary.main -})) - -const PageContent = styled(Grid)(({ theme }) => ({ - width: "1000px", - height: "100%", - margin: "auto", - padding: "28px 0", - flexDirection: "row", - paddingTop: 0, - ["@media (max-width:1167px)"]: { - width: "86vw" - }, - [theme.breakpoints.down("sm")]: { - marginTop: 10 - } -})) - -const Title = styled(Typography)({ - fontSize: 24, - textAlign: "center" -}) - -const CardContainer = styled(Grid)(({ theme }) => ({ - background: theme.palette.primary.dark, - borderRadius: 8, - padding: "36px 47px" -})) - -const DescriptionContainer = styled(Grid)(({ theme }) => ({ - display: "inline-flex", - [theme.breakpoints.down("sm")]: { - paddingLeft: "4%", - paddingRight: "4%" - } -})) - -const OptionsContainer = styled(Grid)(({ theme }) => ({ - marginTop: 40, - [theme.breakpoints.down("sm")]: { - marginTop: 40 - } -})) - -const ChoicesContainer = styled(Grid)(({ theme }) => ({ - marginTop: 32, - gap: 48, - [theme.breakpoints.down("sm")]: { - gap: 16 - } -})) - -const DescriptionText = styled(Typography)(({ theme }) => ({ - fontWeight: 200, - color: theme.palette.text.secondary, - [theme.breakpoints.down("sm")]: { - fontSize: 14 - } -})) - -const OptionButton = styled(Link)(({ theme }) => ({ - [theme.breakpoints.down("sm")]: { - width: "95%", - display: "flex", - textAlign: "center" - }, - [theme.breakpoints.down("sm")]: { - justifyContent: "center" - } -})) +import { PageContainer, PageContent, TitleMediumCenter } from "../../ui" +import { + CardContainer, + DescriptionContainer, + DescriptionText, + OptionsContainer, + ChoicesContainer, + OptionButton +} from "../../ui/success" export const Success: React.FC = () => { const location = useLocation<{ address: string }>() @@ -86,6 +23,7 @@ export const Success: React.FC = () => { const isMobile = useMediaQuery(theme.breakpoints.down("sm")) useEffect(() => { + console.log({ location }) if (location && location.state && location.state.address) { setAddress(location.state.address) } else { @@ -99,7 +37,7 @@ export const Success: React.FC = () => { - Governance token successfully deployed! + Governance token successfully deployed! diff --git a/src/modules/creator/token/etherlink/steps/Summary.tsx b/src/modules/creator/token/etherlink/steps/Summary.tsx new file mode 100644 index 00000000..1de8ef31 --- /dev/null +++ b/src/modules/creator/token/etherlink/steps/Summary.tsx @@ -0,0 +1,234 @@ +import React, { useContext, useEffect, useState } from "react" +import { Grid, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { useHistory, useRouteMatch } from "react-router-dom" +import { toShortAddress } from "services/contracts/utils" +import { DeploymentContext } from "../state/context" +import BigNumber from "bignumber.js" +import { Blockie } from "modules/common/Blockie" +import { ActionTypes } from "../state/types" +import { useTokenOriginate } from "services/contracts/token/hooks/useToken" +import { CopyButton } from "modules/explorer/components/CopyButton" +import { numberWithCommas } from "utils" +import { + TitleSpacing, + ContainerEdit, + AdminAddress, + AdminAddressIcon, + KeyText, + AddressText, + ThirdContainer, + ThirdContainerFirstRow, + ThirdContainerRow, + ThirdContainerLastRow +} from "../../ui" +export const ContractSummary: React.FC = () => { + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down("sm")) + const history = useHistory() + const match = useRouteMatch() + + const { state, dispatch } = useContext(DeploymentContext) + const { tokenDistribution, tokenSettings } = state.data + + const [isLoading, setIsLoading] = useState(false) + + const goToSettings = () => { + history.push(`config`) + } + + const goToDistribution = () => { + history.push(`distribution`) + } + + const { + mutation: { mutate, data } + } = useTokenOriginate(state.data) + + useEffect(() => { + if (data && data.address) { + dispatch({ + type: ActionTypes.CLEAR_CACHE + }) + history.push("/creator/success", { address: data.address }) + } else if (data && !data.address) { + setIsLoading(false) + } + }, [data, dispatch, history]) + + useEffect(() => { + dispatch({ + type: ActionTypes.UPDATE_NAVIGATION_BAR, + back: { + handler: () => history.push(`distribution`), + text: "Back" + }, + next: { + handler: () => { + mutate({ + ...state.data + }) + setIsLoading(true) + }, + text: isLoading ? "Deploying..." : "Launch" + } + }) + }, [dispatch, history, match.path, match.url, mutate, state.data, isLoading]) + + return ( + <> + + + + Review Information + + + {" "} + Make sure you’ve set up your token right.{" "} + + + + + + + + Token Contract Settings + + Edit + + + + + + + + Name + + + + + {tokenSettings.name} + + + + + + + + + + Description + + + + + {tokenSettings.description} + + + + + + + + + + Symbol + + + + + {tokenSettings.symbol} + + + + + + + + + + Supply + + + + + {numberWithCommas(new BigNumber(Number(tokenSettings.totalSupply)))} + + + + + + {/* + + + + Icon + + + + + icon + {tokenSettings.icon} + + + + */} + + + + + + + Initial Distribution + + Edit + + + + {tokenDistribution.holders && tokenDistribution.holders.length > 0 + ? tokenDistribution.holders.map((holder, index) => { + return ( + + + + + + {toShortAddress(holder.walletAddress)} + + + + + + {numberWithCommas(new BigNumber(Number(holder.amount)))} + + + + + ) + }) + : null} + + + + ) +} diff --git a/src/modules/creator/token/etherlink/steps/index.tsx b/src/modules/creator/token/etherlink/steps/index.tsx new file mode 100644 index 00000000..f63a7bcb --- /dev/null +++ b/src/modules/creator/token/etherlink/steps/index.tsx @@ -0,0 +1,61 @@ +import React, { useMemo } from "react" +import { Route, Switch, useLocation } from "react-router" +import { Redirect, useRouteMatch } from "react-router-dom" + +import { StepInfo } from "modules/creator/state" + +import { ProtectedRoute } from "modules/creator/components/ProtectedRoute" +import { ConfigContract } from "./Config" +import { ContractDistribution } from "./Distribution" +import { ContractSummary } from "./Summary" + +export const STEPS: StepInfo[] = [ + { title: "Configure Etherlink Token Contract", index: 0, path: "config" }, + { title: "Initial Etherlink Token Distribution", index: 1, path: "distribution" }, + { title: "Review Etherlink Token Information", index: 2, path: "summary" } +] + +const urlToStepMap: Record = { + config: 0, + distribution: 1, + summary: 2 +} + +export const DeploymentStepRouter: React.FC = () => { + const match = useRouteMatch() + + return ( + + + + + + + + + + + + + + + ) +} + +type CreatorRouteNames = keyof typeof urlToStepMap + +export const useDeploymentStepNumber = (): number => { + const { pathname } = useLocation() + + return useMemo(() => { + const extracted: CreatorRouteNames = pathname.endsWith("/") + ? pathname.split("/").slice(-1)[0] + : pathname.split("/").slice(-1)[0] + + return urlToStepMap[extracted] + }, [pathname]) +} + +export { ConfigContract } from "./Config" +export { ContractDistribution } from "./Distribution" +export { ContractSummary } from "./Summary" diff --git a/src/modules/creator/token/index.tsx b/src/modules/creator/token/index.tsx new file mode 100644 index 00000000..d336f463 --- /dev/null +++ b/src/modules/creator/token/index.tsx @@ -0,0 +1,5 @@ +import React from "react" + +export const TokenDeployment: React.FC = () => { + return
Token Deployment
+} diff --git a/src/modules/creator/token/router.tsx b/src/modules/creator/token/router.tsx new file mode 100644 index 00000000..dd0e299d --- /dev/null +++ b/src/modules/creator/token/router.tsx @@ -0,0 +1,60 @@ +import React from "react" +import { Redirect, Route, Switch, useRouteMatch } from "react-router-dom" +import { TezosTokenDeployment } from "./tezos" +import { ConfigContract as TezosConfigContract } from "./tezos/steps/Config" +import { ContractDistribution as TezosContractDistribution } from "./tezos/steps/Distribution" +import { ContractSummary as TezosContractSummary } from "./tezos/steps/Summary" +import { Ownership as TezosOwnership } from "./tezos/steps/Ownership" +import { Success as TezosSuccess } from "./tezos/steps/Success" +import { Success as EtherlinkSuccess } from "./etherlink/steps/Success" +import { EtherlinkTokenDeployment } from "./etherlink" +import { useTezos } from "services/beacon/hooks/useTezos" +import { DeploymentProvider as EtherlinkDeploymentProvider } from "./etherlink/state/context" +import { DeploymentProvider as TezosDeploymentProvider } from "./tezos/state/context" + +export const TokenDeploymentRouter = (): JSX.Element => { + const { network } = useTezos() + const match = useRouteMatch() + + console.log("Network from token router", network) + if (network.startsWith("etherlink")) { + return ( + + + + + + + + + + + ) + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/modules/creator/deployment/index.tsx b/src/modules/creator/token/tezos/index.tsx similarity index 57% rename from src/modules/creator/deployment/index.tsx rename to src/modules/creator/token/tezos/index.tsx index 48b59fc4..3afe8d41 100644 --- a/src/modules/creator/deployment/index.tsx +++ b/src/modules/creator/token/tezos/index.tsx @@ -1,114 +1,24 @@ import React, { useContext, useMemo } from "react" -import { - Box, - Grid, - Link, - Paper, - Step, - StepLabel, - Stepper, - styled, - Typography, - useMediaQuery, - useTheme -} from "@material-ui/core" +import { Box, Grid, Step, StepLabel, useMediaQuery, useTheme } from "@material-ui/core" import { Navbar } from "modules/common/Toolbar" import ProgressBar from "react-customizable-progressbar" import { DeploymentStepRouter, STEPS, useDeploymentStepNumber } from "./steps" import { StepInfo } from "./state" import { useHistory } from "react-router-dom" -import { NavigationBar } from "../components/NavigationBar" +import { NavigationBar } from "../../components/NavigationBar" import { DeploymentContext } from "./state/context" - -const PageContainer = styled(Grid)(({ theme }) => ({ - background: theme.palette.primary.main -})) - -const PageContent = styled(Grid)(({ theme }) => ({ - marginTop: 0, - width: "1000px", - height: "100%", - margin: "auto", - padding: "28px 0", - flexDirection: "row", - paddingTop: 0, - ["@media (max-width:1167px)"]: { - width: "86vw" - }, - [theme.breakpoints.down("sm")]: { - marginTop: 10 - } -})) - -const IndicatorValue = styled(Paper)(({ theme }) => ({ - display: "flex", - alignItems: "center", - justifyContent: "center", - textAlign: "center", - position: "absolute", - top: 0, - width: "100%", - height: "100%", - margin: "0 auto", - fontSize: 25, - fontWeight: 300, - color: theme.palette.text.secondary, - userSelect: "none", - boxShadow: "none", - background: "inherit", - fontFamily: "Roboto Flex" -})) - -const StepContentContainer = styled(Grid)({ - alignItems: "baseline", - height: "100%", - paddingTop: 0, - boxSizing: "border-box", - overflowY: "auto", - marginLeft: 47, - zIndex: 10, - width: "fit-content", - ["@media (max-width:1167px)"]: { - marginLeft: 0 - } -}) - -const ProgressContainer = styled(Grid)(({ theme }) => ({ - background: "#2F3438", - display: "grid", - borderRadius: 8, - maxHeight: 480, - paddingTop: 20, - position: "sticky", - top: 125 -})) - -const StyledStepper = styled(Stepper)({ - "background": "inherit", - "paddingTop": 48, - "& .MuiStepLabel-label": { - fontSize: 14, - lineHeight: 14 - }, - "cursor": "pointer" -}) - -const FAQClickToAction = styled(Typography)(({ theme }) => ({ - color: theme.palette.secondary.main, - fontSize: "14px", - cursor: "pointer", - textAlign: "center", - textDecoration: "underline" -})) - -const FAQClickText = styled(Typography)(({ theme }) => ({ - color: theme.palette.text.secondary, - fontSize: "14px", - cursor: "pointer", - textAlign: "center" -})) - -export const Deployment: React.FC = () => { +import { + PageContainer, + PageContent, + ProgressContainer, + IndicatorValue, + FAQClickText, + FAQClickToAction, + StyledStepper, + StepContentContainer +} from "../ui" + +export const TezosTokenDeployment: React.FC = () => { const creator = useContext(DeploymentContext) const { back, next } = creator.state diff --git a/src/modules/creator/token/tezos/state/context.tsx b/src/modules/creator/token/tezos/state/context.tsx new file mode 100644 index 00000000..75f1cff1 --- /dev/null +++ b/src/modules/creator/token/tezos/state/context.tsx @@ -0,0 +1,114 @@ +import React, { createContext, useReducer, Dispatch, useMemo } from "react" +import useLocalStorage from "modules/common/hooks/useLocalStorage" +import { DeploymentAction, DeploymentState, TokenContractParams, ActionTypes } from "./types" +import BigNumber from "bignumber.js" + +const deploymentStatus = { + deploying: false, + successful: false +} + +const LOCAL_STORAGE_KEY = "deploymentParams" + +export const INITIAL_TOKEN_STATE: TokenContractParams = { + tokenSettings: { + name: "", + description: "", + totalSupply: null, + decimals: null, + symbol: "", + icon: "" + }, + tokenDistribution: { + holders: [ + { + walletAddress: "", + amount: null + } + ], + totalAmount: new BigNumber(0) + } +} + +export const INITIAL_STATE: DeploymentState = { + data: INITIAL_TOKEN_STATE, + deploymentStatus +} + +const DeploymentContext = createContext<{ + state: DeploymentState + dispatch: Dispatch + updateCache: (value: TokenContractParams) => void +}>({ + state: INITIAL_STATE, + dispatch: () => null, + updateCache: () => null +}) + +export const reducer = (state: DeploymentState, action: DeploymentAction): DeploymentState => { + switch (action.type) { + case ActionTypes.UPDATE_DEPLOYMENT_STATUS: + const { contract, deploying } = action.status + state = { + ...state, + deploymentStatus: { + contract, + deploying, + successful: false + } + } + return state + case ActionTypes.UPDATE_NAVIGATION_BAR: + state = { + ...state, + next: action.next, + back: action.back + } + return state + case ActionTypes.UPDATE_TOKEN_SETTINGS: + state = { + ...state, + data: { + ...state.data, + tokenSettings: action.contractInfo + } + } + return state + case ActionTypes.UPDATE_TOKEN_DISTRIBUTION: + state = { + ...state, + data: { + ...state.data, + tokenDistribution: action.distribution + } + } + return state + case ActionTypes.CLEAR_CACHE: + window.localStorage.removeItem(LOCAL_STORAGE_KEY) + state = { + ...INITIAL_STATE, + deploymentStatus: { + ...INITIAL_STATE.deploymentStatus, + successful: true + } + } + return state + } +} + +const DeploymentProvider: React.FC = ({ children }) => { + const [data, updateCache] = useLocalStorage(LOCAL_STORAGE_KEY, INITIAL_STATE.data) + + const stateWithCache = { + ...INITIAL_STATE, + data + } + + const [state, dispatch] = useReducer(reducer, stateWithCache) + const contextValue = useMemo(() => { + return { state, dispatch } + }, [state, dispatch]) + return {children} +} + +export { DeploymentProvider, DeploymentContext } diff --git a/src/modules/creator/token/tezos/state/index.ts b/src/modules/creator/token/tezos/state/index.ts new file mode 100644 index 00000000..8234ebd8 --- /dev/null +++ b/src/modules/creator/token/tezos/state/index.ts @@ -0,0 +1,3 @@ +export * from "modules/creator/state/context" +export * from "modules/creator/state/types" +export * from "modules/creator/state/utils" diff --git a/src/modules/creator/token/tezos/state/types.ts b/src/modules/creator/token/tezos/state/types.ts new file mode 100644 index 00000000..74e690a5 --- /dev/null +++ b/src/modules/creator/token/tezos/state/types.ts @@ -0,0 +1,100 @@ +import BigNumber from "bignumber.js" +import { NavigationBarProps } from "modules/creator/state/types" + +export type TokenContractSettings = { + name: string + description: string + totalSupply: number | null + decimals: number | null + symbol: string + icon: string +} + +export type TokenDistributionSettings = { + holders: Holder[] + totalAmount: BigNumber +} + +export type Holder = { + walletAddress: string + amount: number | null +} + +export interface TokenContractParams { + tokenSettings: TokenContractSettings + tokenDistribution: TokenDistributionSettings +} + +export type ErrorValues = Partial> + +type DeploymentStatus = { + deploying: boolean + successful: boolean + contract?: string +} + +export type DeploymentState = { + data: TokenContractParams + deploymentStatus: DeploymentStatus +} & NavigationBarProps + +export interface StepInfo { + title: string + index: number + path: string +} + +function updateTokenSettings(contractInfo: TokenContractSettings) { + return { + type: ActionTypes.UPDATE_TOKEN_SETTINGS, + contractInfo + } +} + +function updateTokenDistribution(distribution: TokenDistributionSettings) { + return { + type: ActionTypes.UPDATE_TOKEN_DISTRIBUTION, + distribution + } +} + +function updateDeploymentStatus({ deploying, contract }: DeploymentStatus) { + return { + type: ActionTypes.UPDATE_DEPLOYMENT_STATUS, + status: { deploying, contract } + } +} + +function updateNavigationBar(props: NavigationBarProps) { + return { + type: ActionTypes.UPDATE_NAVIGATION_BAR, + ...props + } +} + +function clearCache() { + return { + type: ActionTypes.CLEAR_CACHE + } +} + +export type DeploymentAction = ReturnType< + | typeof updateTokenSettings + | typeof updateDeploymentStatus + | typeof clearCache + | typeof updateTokenDistribution + | typeof updateNavigationBar +> + +export enum ActionTypes { + UPDATE_NAVIGATION_BAR = "UPDATE_NAVIGATION_BAR", + UPDATE_TOKEN_SETTINGS = "UPDATE_TOKEN_SETTINGS", + UPDATE_TOKEN_DISTRIBUTION = "UPDATE_TOKEN_DISTRIBUTION", + UPDATE_DEPLOYMENT_STATUS = "UPDATE_DEPLOYMENT_STATUS", + CLEAR_CACHE = "CLEAR_CACHE" +} +export interface TokenHolder { + address: string + balance: number + name?: string +} diff --git a/src/modules/creator/deployment/steps/Config.tsx b/src/modules/creator/token/tezos/steps/Config.tsx similarity index 79% rename from src/modules/creator/deployment/steps/Config.tsx rename to src/modules/creator/token/tezos/steps/Config.tsx index e2fe6613..8db27e91 100644 --- a/src/modules/creator/deployment/steps/Config.tsx +++ b/src/modules/creator/token/tezos/steps/Config.tsx @@ -1,96 +1,18 @@ -import { - Grid, - styled, - TextareaAutosize, - Typography, - useMediaQuery, - useTheme, - withStyles, - withTheme -} from "@material-ui/core" +import { Grid, Typography, useMediaQuery, useTheme } from "@material-ui/core" import { Field, Form, Formik, FormikErrors, getIn } from "formik" import React, { useContext, useEffect } from "react" import { useHistory, useRouteMatch } from "react-router-dom" import { DeploymentContext } from "../state/context" import { ActionTypes, TokenContractSettings } from "../state/types" -import { TextField as FormikTextField } from "formik-material-ui" import { FieldChange, handleChange, handleNegativeInput } from "modules/creator/utils" - -const Title = styled(Typography)(({ theme }) => ({ - fontSize: 32, - fontWeight: 600, - [theme.breakpoints.down("sm")]: { - fontSize: 26 - } -})) - -const CustomTextarea = styled(withTheme(TextareaAutosize))(props => ({ - "minHeight": 152, - "boxSizing": "border-box", - "width": "100%", - "marginTop": 14, - "fontWeight": 300, - "padding": "21px 20px", - "fontFamily": "Roboto Flex", - "border": "none", - "fontSize": 16, - "color": props.theme.palette.text.secondary, - "background": "#2F3438", - "borderRadius": 8, - "paddingRight": 40, - "wordBreak": "break-word", - "&:focus-visible": { - outline: "none" - }, - "resize": "none" -})) - -const CustomFormikTextField = withStyles({ - root: { - "& .MuiInput-root": { - fontWeight: 300, - textAlign: "initial" - }, - "& .MuiInputBase-input": { - textAlign: "initial" - }, - "& .MuiInput-underline:before": { - borderBottom: "none !important" - }, - "& .MuiInput-underline:hover:before": { - borderBottom: "none !important" - }, - "& .MuiInput-underline:after": { - borderBottom: "none !important" - } - } -})(FormikTextField) - -const CustomInputContainer = styled(Grid)(({ theme }) => ({ - "height": 54, - "boxSizing": "border-box", - "marginTop": 14, - "background": "#2F3438", - "borderRadius": 8, - "alignItems": "center", - "display": "flex", - "padding": "13px 23px", - "fontWeight": 300, - "& input::placeholder": { - fontWeight: 300 - } -})) - -const ErrorText = styled(Typography)({ - fontSize: 14, - color: "red", - marginTop: 4 -}) - -const TextareaContainer = styled(Grid)({ - display: "flex", - position: "relative" -}) +import { + Title, + CustomTextarea, + CustomFormikTextField, + CustomInputContainer, + ErrorText, + TextareaContainer +} from "../../ui" const validateForm = (values: TokenContractSettings) => { const errors: FormikErrors = {} @@ -265,7 +187,7 @@ export const ConfigContract: React.FC = () => { - Configure Token Contract + Configure Token ContractX diff --git a/src/modules/creator/deployment/steps/Distribution.tsx b/src/modules/creator/token/tezos/steps/Distribution.tsx similarity index 83% rename from src/modules/creator/deployment/steps/Distribution.tsx rename to src/modules/creator/token/tezos/steps/Distribution.tsx index 181f12e2..3909cb56 100644 --- a/src/modules/creator/deployment/steps/Distribution.tsx +++ b/src/modules/creator/token/tezos/steps/Distribution.tsx @@ -1,107 +1,26 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { Grid, IconButton, styled, Typography, useMediaQuery, useTheme, withStyles } from "@material-ui/core" +import { Grid, IconButton, Typography, useMediaQuery, useTheme } from "@material-ui/core" import { Field, FieldArray, Form, Formik, FormikErrors } from "formik" import React, { useContext, useEffect } from "react" import { useHistory, useRouteMatch } from "react-router-dom" import { DeploymentContext } from "../state/context" -import { ActionTypes, Holder, TokenContractSettings, TokenDistributionSettings } from "../state/types" -import { TextField as FormikTextField } from "formik-material-ui" -import { RemoveCircleOutline } from "@material-ui/icons" +import { ActionTypes, Holder, TokenDistributionSettings } from "../state/types" import BigNumber from "bignumber.js" -import { numberWithCommas } from "../state/utils" + import { useTezos } from "services/beacon/hooks/useTezos" import { FieldChange, handleNegativeInput } from "modules/creator/utils" import AddCircleIcon from "@mui/icons-material/AddCircle" import { validateContractAddress, validateAddress } from "@taquito/utils" - -const RemoveButton = styled(RemoveCircleOutline)({ - marginTop: 0, - fontSize: 18 -}) - -const AmountText = styled(Typography)({ - fontWeight: 400 -}) - -const CustomFormikTextField = withStyles({ - root: { - "& .MuiInput-root": { - fontWeight: 300, - textAlign: "initial" - }, - "& .MuiInputBase-input": { - textAlign: "initial" - }, - "& .MuiInput-underline:before": { - borderBottom: "none !important" - }, - "& .MuiInput-underline:hover:before": { - borderBottom: "none !important" - }, - "& .MuiInput-underline:after": { - borderBottom: "none !important" - } - } -})(FormikTextField) - -const CustomInputContainer = styled(Grid)(({ theme }) => ({ - "height": 54, - "boxSizing": "border-box", - "marginTop": 14, - "background": "#2F3438", - "borderRadius": 8, - "alignItems": "center", - "display": "flex", - "padding": "13px 23px", - "width": "85%", - "fontWeight": 300, - "& input::placeholder": { - fontWeight: 300 - }, - [theme.breakpoints.down("sm")]: { - width: "100%" - } -})) - -const CustomAmountContainer = styled(Grid)(({ theme }) => ({ - "height": 54, - "boxSizing": "border-box", - "marginTop": 14, - "background": "#2F3438", - "borderRadius": 8, - "alignItems": "center", - "display": "flex", - "padding": "13px 23px", - "width": "45%", - "& input::placeholder": { - fontWeight: 300 - }, - [theme.breakpoints.down("sm")]: { - width: "100%" - } -})) - -const AddButtonContainer = styled(Grid)(({ theme }) => ({ - "height": 54, - "boxSizing": "border-box", - "marginTop": 14, - "alignItems": "center", - "display": "flex", - "padding": "0px 0px", - "width": "15%", - "& input::placeholder": { - fontWeight: 300 - }, - [theme.breakpoints.down("sm")]: { - width: "100%" - } -})) - -const ErrorText = styled(Typography)({ - fontSize: 14, - color: "red", - marginTop: 4 -}) +import { numberWithCommas } from "utils" +import { + CustomFormikTextField, + AddButtonContainer, + CustomAmountContainer, + CustomInputContainer, + RemoveButton, + AmountText, + ErrorText +} from "../../ui" const isInvalidKtOrTzAddress = (address: string) => validateContractAddress(address) !== 3 && validateAddress(address) !== 3 diff --git a/src/modules/creator/token/tezos/steps/Ownership.tsx b/src/modules/creator/token/tezos/steps/Ownership.tsx new file mode 100644 index 00000000..e7b691ce --- /dev/null +++ b/src/modules/creator/token/tezos/steps/Ownership.tsx @@ -0,0 +1,84 @@ +import React from "react" +import { Grid, useMediaQuery, useTheme } from "@material-ui/core" +import { MainButton } from "modules/common/MainButton" +import { Navbar } from "modules/common/Toolbar" +import { useHistory } from "react-router-dom" +import { useTezos } from "services/beacon/hooks/useTezos" +import { + CenterTitle, + PageContainer, + PageContent, + DescriptionText, + CardContainer, + DescriptionContainer, + OptionsContainer, + ChoicesContainer, + OptionButton +} from "../../ui" + +export const Ownership: React.FC = () => { + const theme = useTheme() + const { account, etherlink } = useTezos() + const history = useHistory() + const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) + + return ( + <> + + + + + + Do you already have a governance token? + + + + + + This would be an FA2-compatible token contract that will serve to assign voting weight based on + ownership. + + + + + + + If you already have this asset deployed, click YES. If not, click NO and we will configure and deploy + one now. + + + + + + + + + Yes, I have one + + + + + { + const href = `/creator/deployment` + history.push(href) + }} + > + + No, I need one + + + + + + + + + ) +} diff --git a/src/modules/creator/token/tezos/steps/Success.tsx b/src/modules/creator/token/tezos/steps/Success.tsx new file mode 100644 index 00000000..5b0b9c04 --- /dev/null +++ b/src/modules/creator/token/tezos/steps/Success.tsx @@ -0,0 +1,92 @@ +import React, { useEffect, useState } from "react" +import { Grid, Typography, useMediaQuery, useTheme } from "@material-ui/core" +import { MainButton } from "modules/common/MainButton" +import { Navbar } from "modules/common/Toolbar" +import { useHistory, useLocation } from "react-router-dom" +import { Blockie } from "modules/common/Blockie" +import { CopyAddress } from "modules/common/CopyAddress" +import { PageContainer, PageContent, TitleMediumCenter } from "../../ui" +import { + CardContainer, + DescriptionContainer, + DescriptionText, + OptionsContainer, + ChoicesContainer, + OptionButton +} from "../../ui/success" + +export const Success: React.FC = () => { + const location = useLocation<{ address: string }>() + const [address, setAddress] = useState("") + const history = useHistory() + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down("sm")) + + useEffect(() => { + if (location && location.state && location.state.address) { + setAddress(location.state.address) + } else { + history.push("/explorer") + } + }, [location, history]) + return ( + <> + + + + + + Governance token successfully deployed! + + + + + Your Token Address: + + + + + {address && ( + + )} + + + + + Would you like to continue and create a DAO? + + + + + + + + Create DAO + + + + + + + {"I'm done"} + + + + + + + + + ) +} diff --git a/src/modules/creator/deployment/steps/Summary.tsx b/src/modules/creator/token/tezos/steps/Summary.tsx similarity index 82% rename from src/modules/creator/deployment/steps/Summary.tsx rename to src/modules/creator/token/tezos/steps/Summary.tsx index aa23b4bf..94513a08 100644 --- a/src/modules/creator/deployment/steps/Summary.tsx +++ b/src/modules/creator/token/tezos/steps/Summary.tsx @@ -3,90 +3,24 @@ import { Grid, styled, Typography, useMediaQuery, useTheme } from "@material-ui/ import { useHistory, useRouteMatch } from "react-router-dom" import { toShortAddress } from "services/contracts/utils" import { DeploymentContext } from "../state/context" -import { numberWithCommas } from "../state/utils" +import { numberWithCommas } from "utils" import BigNumber from "bignumber.js" import { Blockie } from "modules/common/Blockie" import { ActionTypes } from "../state/types" import { useTokenOriginate } from "services/contracts/token/hooks/useToken" import { CopyButton } from "modules/explorer/components/CopyButton" - -const ThirdContainer = styled(Grid)({ - background: "#2F3438", - borderRadius: 8, - boxSizing: "border-box" -}) - -const ThirdContainerFirstRow = styled(Grid)(({ theme }) => ({ - padding: "19px 48px", - borderBottom: "0.3px solid #575757", - backgroundColor: theme.palette.primary.dark, - borderRadius: "8px 8px 0px 0px", - alignItems: "center", - display: "flex", - minHeight: 70, - ["@media (max-width:1167px)"]: { - padding: "12px 15px", - maxHeight: "inherit" - } -})) - -const ThirdContainerLastRow = styled(Grid)({ - padding: "19px 48px", - alignItems: "center", - display: "flex", - backgroundColor: "#24282D", - borderRadius: "0px 0px 8px 8px", - minHeight: 70, - ["@media (max-width:1167px)"]: { - padding: "12px 15px", - maxHeight: "inherit" - } -}) - -const ThirdContainerRow = styled(Grid)({ - "borderBottom": "0.3px solid #575757", - "backgroundColor": "#24282D", - "padding": "24px 48px", - "minHeight": 70, - ["@media (max-width:1167px)"]: { - padding: "12px 15px", - maxHeight: "inherit" - }, - "&:last-child": { - borderBottom: "none" - } -}) - -const TitleSpacing = styled(Typography)({ - marginTop: 8, - fontWeight: 400, - fontSize: 18 -}) - -const ContainerEdit = styled(Typography)(({ theme }) => ({ - cursor: "pointer", - color: theme.palette.secondary.light -})) - -const AdminAddress = styled(Typography)({ - wordBreak: "break-all" -}) - -const AdminAddressIcon = styled(Typography)({ - wordBreak: "break-all", - display: "flex", - alignItems: "center" -}) - -const KeyText = styled(Typography)({ - fontWeight: 400 -}) - -const AddressText = styled(Typography)({ - marginLeft: 12, - fontWeight: 300, - marginRight: 8 -}) +import { + TitleSpacing, + ContainerEdit, + AdminAddress, + AdminAddressIcon, + KeyText, + AddressText, + ThirdContainer, + ThirdContainerFirstRow, + ThirdContainerRow, + ThirdContainerLastRow +} from "../../ui" export const ContractSummary: React.FC = () => { const theme = useTheme() diff --git a/src/modules/creator/deployment/steps/index.tsx b/src/modules/creator/token/tezos/steps/index.tsx similarity index 87% rename from src/modules/creator/deployment/steps/index.tsx rename to src/modules/creator/token/tezos/steps/index.tsx index 972af10f..72e47b87 100644 --- a/src/modules/creator/deployment/steps/index.tsx +++ b/src/modules/creator/token/tezos/steps/index.tsx @@ -56,6 +56,6 @@ export const useDeploymentStepNumber = (): number => { }, [pathname]) } -export { ConfigContract } from "modules/creator/deployment/steps/Config" -export { ContractDistribution } from "modules/creator/deployment/steps/Distribution" -export { ContractSummary } from "modules/creator/deployment/steps/Summary" +export { ConfigContract } from "./Config" +export { ContractDistribution } from "./Distribution" +export { ContractSummary } from "./Summary" diff --git a/src/modules/creator/token/ui/index.tsx b/src/modules/creator/token/ui/index.tsx new file mode 100644 index 00000000..aa4840f1 --- /dev/null +++ b/src/modules/creator/token/ui/index.tsx @@ -0,0 +1,358 @@ +import { Grid, Link, styled, Typography, withTheme, withStyles } from "@material-ui/core" +import { TextareaAutosize, Paper, Stepper } from "@material-ui/core" +import { TextField as FormikTextField } from "formik-material-ui" +import { RemoveCircleOutline } from "@material-ui/icons" + +export const Title = styled(Typography)(({ theme }) => ({ + fontSize: 32, + fontWeight: 600, + [theme.breakpoints.down("sm")]: { + fontSize: 26 + } +})) + +export const CenterTitle = styled(Typography)(({ theme }) => ({ + fontSize: 32, + fontWeight: 600, + textAlign: "center", + [theme.breakpoints.down("sm")]: { + fontSize: 26 + } +})) + +export const TitleMediumCenter = styled(Typography)({ + fontSize: 24, + textAlign: "center" +}) + +export const CustomTextarea = styled(withTheme(TextareaAutosize))(props => ({ + "minHeight": 152, + "boxSizing": "border-box", + "width": "100%", + "marginTop": 14, + "fontWeight": 300, + "padding": "21px 20px", + "fontFamily": "Roboto Flex", + "border": "none", + "fontSize": 16, + "color": props.theme.palette.text.secondary, + "background": "#2F3438", + "borderRadius": 8, + "paddingRight": 40, + "wordBreak": "break-word", + "&:focus-visible": { + outline: "none" + }, + "resize": "none" +})) + +export const CustomFormikTextField = withStyles({ + root: { + "& .MuiInput-root": { + fontWeight: 300, + textAlign: "initial" + }, + "& .MuiInputBase-input": { + textAlign: "initial" + }, + "& .MuiInput-underline:before": { + borderBottom: "none !important" + }, + "& .MuiInput-underline:hover:before": { + borderBottom: "none !important" + }, + "& .MuiInput-underline:after": { + borderBottom: "none !important" + } + } +})(FormikTextField) + +export const CustomInputContainer = styled(Grid)(({ theme }) => ({ + "height": 54, + "boxSizing": "border-box", + "marginTop": 14, + "background": "#2F3438", + "borderRadius": 8, + "alignItems": "center", + "display": "flex", + "padding": "13px 23px", + "fontWeight": 300, + "& input::placeholder": { + fontWeight: 300 + }, + [theme.breakpoints.down("sm")]: { + width: "100%" + } +})) + +export const ErrorText = styled(Typography)({ + fontSize: 14, + color: "red", + marginTop: 4 +}) + +export const TextareaContainer = styled(Grid)({ + display: "flex", + position: "relative" +}) + +// Starting for Distribution.tsx + +export const CustomAmountContainer = styled(Grid)(({ theme }) => ({ + "height": 54, + "boxSizing": "border-box", + "marginTop": 14, + "background": "#2F3438", + "borderRadius": 8, + "alignItems": "center", + "display": "flex", + "padding": "13px 23px", + "width": "45%", + "& input::placeholder": { + fontWeight: 300 + }, + [theme.breakpoints.down("sm")]: { + width: "100%" + } +})) + +export const AddButtonContainer = styled(Grid)(({ theme }) => ({ + "height": 54, + "boxSizing": "border-box", + "marginTop": 14, + "alignItems": "center", + "display": "flex", + "padding": "0px 0px", + "width": "15%", + "& input::placeholder": { + fontWeight: 300 + }, + [theme.breakpoints.down("sm")]: { + width: "100%" + } +})) + +export const RemoveButton = styled(RemoveCircleOutline)({ + marginTop: 0, + fontSize: 18 +}) + +export const AmountText = styled(Typography)({ + fontWeight: 400 +}) + +// Starting for Ownership.tsx + +export const PageContainer = styled(Grid)(({ theme }) => ({ + background: theme.palette.primary.main +})) + +export const PageContent = styled(Grid)(({ theme }) => ({ + width: "1000px", + height: "100%", + margin: "auto", + padding: "28px 0", + flexDirection: "row", + paddingTop: 0, + ["@media (max-width:1167px)"]: { + width: "86vw" + }, + [theme.breakpoints.down("sm")]: { + marginTop: 10 + } +})) + +export const CardContainer = styled(Grid)(({ theme }) => ({ + background: theme.palette.primary.dark, + gap: 32, + borderRadius: 8, + padding: "40px 48px", + [theme.breakpoints.down("sm")]: { + padding: "30px 38px" + } +})) + +export const DescriptionContainer = styled(Grid)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + paddingLeft: "4%", + paddingRight: "4%" + } +})) + +export const OptionsContainer = styled(Grid)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + paddingLeft: "4%", + paddingRight: "4%" + } +})) + +export const ChoicesContainer = styled(Grid)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + gap: 32 + } +})) + +export const DescriptionText = styled(Typography)(({ theme }) => ({ + fontWeight: 300, + fontSize: 18, + color: theme.palette.text.secondary, + [theme.breakpoints.down("sm")]: { + fontSize: 14 + } +})) + +export const OptionButton = styled(Link)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + display: "flex", + textAlign: "center" + } +})) + +// Starting for /index.tsx +export const IndicatorValue = styled(Paper)(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + position: "absolute", + top: 0, + width: "100%", + height: "100%", + margin: "0 auto", + fontSize: 25, + fontWeight: 300, + color: theme.palette.text.secondary, + userSelect: "none", + boxShadow: "none", + background: "inherit", + fontFamily: "Roboto Flex" +})) + +export const StepContentContainer = styled(Grid)({ + alignItems: "baseline", + height: "100%", + paddingTop: 0, + boxSizing: "border-box", + overflowY: "auto", + marginLeft: 47, + zIndex: 10, + width: "fit-content", + ["@media (max-width:1167px)"]: { + marginLeft: 0 + } +}) + +export const ProgressContainer = styled(Grid)(({ theme }) => ({ + background: "#2F3438", + display: "grid", + borderRadius: 8, + maxHeight: 480, + paddingTop: 20, + position: "sticky", + top: 125 +})) + +export const StyledStepper = styled(Stepper)({ + "background": "inherit", + "paddingTop": 48, + "& .MuiStepLabel-label": { + fontSize: 14, + lineHeight: 14 + }, + "cursor": "pointer" +}) + +export const FAQClickToAction = styled(Typography)(({ theme }) => ({ + color: theme.palette.secondary.main, + fontSize: "14px", + cursor: "pointer", + textAlign: "center", + textDecoration: "underline" +})) + +export const FAQClickText = styled(Typography)(({ theme }) => ({ + color: theme.palette.text.secondary, + fontSize: "14px", + cursor: "pointer", + textAlign: "center" +})) + +// Starting for Summary.tsx + +export const TitleSpacing = styled(Typography)({ + marginTop: 8, + fontWeight: 400, + fontSize: 18 +}) + +export const ContainerEdit = styled(Typography)(({ theme }) => ({ + cursor: "pointer", + color: theme.palette.secondary.light +})) + +export const AdminAddress = styled(Typography)({ + wordBreak: "break-all" +}) + +export const AdminAddressIcon = styled(Typography)({ + wordBreak: "break-all", + display: "flex", + alignItems: "center" +}) + +export const KeyText = styled(Typography)({ + fontWeight: 400 +}) + +export const AddressText = styled(Typography)({ + marginLeft: 12, + fontWeight: 300, + marginRight: 8 +}) + +export const ThirdContainer = styled(Grid)({ + background: "#2F3438", + borderRadius: 8, + boxSizing: "border-box" +}) + +export const ThirdContainerFirstRow = styled(Grid)(({ theme }) => ({ + padding: "19px 48px", + borderBottom: "0.3px solid #575757", + backgroundColor: theme.palette.primary.dark, + borderRadius: "8px 8px 0px 0px", + alignItems: "center", + display: "flex", + minHeight: 70, + ["@media (max-width:1167px)"]: { + padding: "12px 15px", + maxHeight: "inherit" + } +})) + +export const ThirdContainerLastRow = styled(Grid)({ + padding: "19px 48px", + alignItems: "center", + display: "flex", + backgroundColor: "#24282D", + borderRadius: "0px 0px 8px 8px", + minHeight: 70, + ["@media (max-width:1167px)"]: { + padding: "12px 15px", + maxHeight: "inherit" + } +}) + +export const ThirdContainerRow = styled(Grid)({ + "borderBottom": "0.3px solid #575757", + "backgroundColor": "#24282D", + "padding": "24px 48px", + "minHeight": 70, + ["@media (max-width:1167px)"]: { + padding: "12px 15px", + maxHeight: "inherit" + }, + "&:last-child": { + borderBottom: "none" + } +}) diff --git a/src/modules/creator/token/ui/success.tsx b/src/modules/creator/token/ui/success.tsx new file mode 100644 index 00000000..34704a61 --- /dev/null +++ b/src/modules/creator/token/ui/success.tsx @@ -0,0 +1,49 @@ +import { Grid, Link, styled, Typography, withTheme, withStyles } from "@material-ui/core" + +export const CardContainer = styled(Grid)(({ theme }) => ({ + background: theme.palette.primary.dark, + borderRadius: 8, + padding: "36px 47px" +})) + +export const DescriptionContainer = styled(Grid)(({ theme }) => ({ + display: "inline-flex", + [theme.breakpoints.down("sm")]: { + paddingLeft: "4%", + paddingRight: "4%" + } +})) + +export const OptionsContainer = styled(Grid)(({ theme }) => ({ + marginTop: 40, + [theme.breakpoints.down("sm")]: { + marginTop: 40 + } +})) + +export const ChoicesContainer = styled(Grid)(({ theme }) => ({ + marginTop: 32, + gap: 48, + [theme.breakpoints.down("sm")]: { + gap: 16 + } +})) + +export const DescriptionText = styled(Typography)(({ theme }) => ({ + fontWeight: 200, + color: theme.palette.text.secondary, + [theme.breakpoints.down("sm")]: { + fontSize: 14 + } +})) + +export const OptionButton = styled(Link)(({ theme }) => ({ + [theme.breakpoints.down("sm")]: { + width: "95%", + display: "flex", + textAlign: "center" + }, + [theme.breakpoints.down("sm")]: { + justifyContent: "center" + } +})) diff --git a/src/services/beacon/hooks/useTezos.ts b/src/services/beacon/hooks/useTezos.ts index 762d08d0..dbe2c113 100644 --- a/src/services/beacon/hooks/useTezos.ts +++ b/src/services/beacon/hooks/useTezos.ts @@ -7,6 +7,7 @@ import mixpanel from "mixpanel-browser" import { BeaconWallet } from "@taquito/beacon-wallet" import { EtherlinkContext } from "services/wagmi/context" import { useNetwork } from "services/useNetwork" +import { useChainId } from "wagmi" type WalletConnectReturn = { tezos: TezosToolkit @@ -51,7 +52,7 @@ export const useTezos = (): WalletConnectReturn => { } }) }, - [ethAccount?.address, dispatch, tezos, etherlinkNetwork, connectWithWagmi] + [dispatch, tezos] ) const handleTezosNetworkChange = useCallback( @@ -128,7 +129,7 @@ export const useTezos = (): WalletConnectReturn => { return newTezos }, - [connectWithWagmi, network, dispatch] + [network, dispatch] ) useEffect(() => { @@ -155,11 +156,20 @@ export const useTezos = (): WalletConnectReturn => { type: TezosActionType.RESET_TEZOS }) } - }, [network, etherlinkNetwork, handleChangeNetwork, isEtherlinkConnected]) + }, [ + network, + etherlinkNetwork, + handleChangeNetwork, + isEtherlinkConnected, + wallet, + switchToNetwork, + dispatch, + disconnectEtherWallet + ]) useEffect(() => { setNetwork(network) - }, [network]) + }, [network, setNetwork]) return { tezos, @@ -190,7 +200,7 @@ export const useTezos = (): WalletConnectReturn => { dispatch({ type: TezosActionType.RESET_TEZOS }) - }, [dispatch, network, wallet, isEtherlinkConnected]), + }, [network, wallet, isEtherlinkConnected, dispatch, disconnectEtherWallet]), changeNetwork: handleChangeNetwork, account, diff --git a/src/services/contracts/token/hooks/useToken.ts b/src/services/contracts/token/hooks/useToken.ts index af6f6c43..9f13d031 100644 --- a/src/services/contracts/token/hooks/useToken.ts +++ b/src/services/contracts/token/hooks/useToken.ts @@ -1,73 +1,112 @@ -import { DAOTemplate } from "../../../../modules/creator/state/types" -import { useState } from "react" -import { ContractAbstraction, ContractProvider, Wallet } from "@taquito/taquito" +import { ethers } from "ethers" +import { ContractAbstraction, ContractProvider, TezosToolkit, Wallet } from "@taquito/taquito" import { useMutation, useQueryClient } from "react-query" -import { deployMetadataCarrier } from "services/contracts/metadataCarrier/deploy" import { useTezos } from "services/beacon/hooks/useTezos" -import mixpanel from "mixpanel-browser" import { TokenContractParams } from "modules/creator/deployment/state/types" import { getCurrentBlock } from "services/utils/utils" import { deployTokenContract } from "services/contracts/token" import { useNotification } from "modules/common/hooks/useNotification" +import HbTokenAbi from "assets/abis/hb_evm.json" + +import AnalyticsService from "services/services/analytics" + +const ERC20_ABI = HbTokenAbi.abi +const ERC20_BYTECODE = HbTokenAbi.bytecode export const useTokenOriginate = (tokenData: TokenContractParams) => { const queryClient = useQueryClient() - const { tezos, connect, network, account } = useTezos() + const { tezos, connect, network, account, etherlink } = useTezos() + const provider = etherlink.provider + const signer = etherlink.signer + const openNotification = useNotification() const result = useMutation, Error, TokenContractParams>( async ({ tokenDistribution, tokenSettings }) => { - try { - let tezosToolkit = tezos + console.log({ tokenDistribution, tokenSettings, network }) + console.log({ provider }) + if (network.startsWith("etherlink")) { + try { + console.log("Deployer", signer?.getAddress()) + const factory = new ethers.ContractFactory(ERC20_ABI, ERC20_BYTECODE, signer) + const initialMembers = tokenDistribution.holders.map(holder => holder.walletAddress) + const initialAmounts = tokenDistribution.holders.map(holder => + ethers.parseUnits(holder.amount?.toString() ?? "0", tokenSettings.decimals ?? 18) + ) + const contract = await factory.deploy( + tokenSettings.name, + tokenSettings.symbol ?? "MTK", + initialMembers, + initialAmounts + ) + await contract.waitForDeployment() + const contractAddress = await contract.getAddress() + return { address: contractAddress } + } catch (error: any) { + // Use 'unknown' instead of 'any' for better type safety + const errorMessage = error instanceof Error ? error.message : String(error) + console.log("Error", errorMessage) + console.log({ error }) + openNotification({ + message: error?.shortMessage, + variant: "error", + autoHideDuration: 2000 + }) + return error + } + } else { + try { + let tezosToolkit = tezos - if (!account) { - const connectedToolkit = await connect() - if (typeof connectedToolkit === "string") { - throw new Error("Failed to connect to Tezos toolkit") + if (!account) { + const connectedToolkit = await connect() + if (typeof connectedToolkit === "string") { + throw new Error("Failed to connect to Tezos toolkit") + } + tezosToolkit = connectedToolkit as TezosToolkit } - tezosToolkit = connectedToolkit - } - mixpanel.track("Started Token origination", { - contract: "FA2Token", - tokenName: tokenSettings.name, - tokenSymbol: tokenSettings.symbol - }) + AnalyticsService.track("Started Token origination", { + contract: "FA2Token", + tokenName: tokenSettings.name, + tokenSymbol: tokenSettings.symbol + }) - const mutateTokenData: TokenContractParams = { - tokenDistribution, - tokenSettings - } + const mutateTokenData: TokenContractParams = { + tokenDistribution, + tokenSettings + } - const currentBlock = await getCurrentBlock(network) + const currentBlock = await getCurrentBlock(network) - const contract = await deployTokenContract({ - ...mutateTokenData, - tezos: tezosToolkit, - account, - currentBlock - }) + const contract = await deployTokenContract({ + ...mutateTokenData, + tezos: tezosToolkit, + account, + currentBlock + }) - if (!contract) { - throw new Error(`Error deploying ${tokenData.tokenSettings.name} Token`) - } + if (!contract) { + throw new Error(`Error deploying ${tokenData.tokenSettings.name} Token`) + } - mixpanel.track("Completed Token Deployment", { - contract: "FA2Token", - tokenName: tokenSettings.name, - tokenSymbol: tokenSettings.symbol - }) - - return contract - } catch (error) { - openNotification({ - message: (error as Error).message, - variant: "error", - autoHideDuration: 2000 - }) - return error + AnalyticsService.track("Completed Token Deployment", { + contract: "FA2Token", + tokenName: tokenSettings.name, + tokenSymbol: tokenSettings.symbol + }) + + return contract + } catch (error) { + openNotification({ + message: (error as Error).message, + variant: "error", + autoHideDuration: 2000 + }) + return error + } } }, { diff --git a/src/services/lite/utils.ts b/src/services/lite/utils.ts index 1b6a4640..1d62d268 100644 --- a/src/services/lite/utils.ts +++ b/src/services/lite/utils.ts @@ -161,10 +161,6 @@ export const getTreasuryPercentage = (proposalTotal: BigNumber, totalSupply: num return value } -export const numberWithCommas = (x: number) => { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") -} - const SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"] export const nFormatter = (num: any, digits: number) => { diff --git a/src/services/services/analytics.ts b/src/services/services/analytics.ts new file mode 100644 index 00000000..4d3d84ef --- /dev/null +++ b/src/services/services/analytics.ts @@ -0,0 +1,9 @@ +import mixpanel from "mixpanel-browser" + +const AnalyticsService = { + track: (event: string, properties: Record) => { + mixpanel.track(event, properties) + } +} + +export default AnalyticsService diff --git a/src/services/services/dao/hooks/useLiteDAO.ts b/src/services/services/dao/hooks/useLiteDAO.ts new file mode 100644 index 00000000..810de2dc --- /dev/null +++ b/src/services/services/dao/hooks/useLiteDAO.ts @@ -0,0 +1,10 @@ +// import { useQuery } from "@tanstack/react-query" +// import { useTezos } from "services/beacon/hooks/useTezos" + +// export const useLiteDAO = (address: string){ +// const { network } = useTezos() +// const { data, ...rest } = useQuery({ +// queryKey: ["lite-dao", address, network], +// queryFn: () => getLiteDAO(address, network) +// }) +// } diff --git a/src/services/wagmi/ethers.ts b/src/services/wagmi/ethers.ts new file mode 100644 index 00000000..6d5cf905 --- /dev/null +++ b/src/services/wagmi/ethers.ts @@ -0,0 +1,46 @@ +import * as React from "react" +import { usePublicClient, useWalletClient } from "wagmi" +import { FallbackProvider, JsonRpcProvider } from "ethers" +import { BrowserProvider, JsonRpcSigner } from "ethers" +import { type HttpTransport } from "viem" + +export function publicClientToProvider(publicClient: any) { + const { chain, transport } = publicClient + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address + } + if (transport.type === "fallback") { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network) + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Hook to convert a viem Public Client to an ethers.js Provider. */ +export function useEthersProvider({ chainId }: { chainId?: number } = {}) { + const publicClient = usePublicClient({ chainId }) + return React.useMemo(() => publicClientToProvider(publicClient), [publicClient]) +} + +export function walletClientToSigner(walletClient: any) { + const { account, chain, transport } = walletClient + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: walletClient } = useWalletClient({ chainId }) + return React.useMemo(() => (walletClient ? walletClientToSigner(walletClient) : undefined), [walletClient]) +} diff --git a/src/utils.ts b/src/utils.ts index efad8cd4..c4ef0f13 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,5 @@ import { LambdaCode } from "services/bakingBad/lambdas" +import BigNumber from "bignumber.js" export const roundNumber = ({ number, decimals }: { number: number; decimals: number }) => Math.round(number * 10 ** decimals) / 10 ** decimals @@ -19,3 +20,7 @@ export const parseLambdaCode = (lambdaCode: LambdaCode | undefined) => { return code } + +export const numberWithCommas = (x: number | BigNumber) => { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") +} diff --git a/yarn.lock b/yarn.lock index ff06d93c..2cf1987f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2553,7 +2553,7 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== -"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0": +"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0", "@lit-labs/ssr-dom-shim@^1.2.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz#2f3a8f1d688935c704dbc89132394a41029acbb8" integrity sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ== @@ -2565,6 +2565,13 @@ dependencies: "@lit-labs/ssr-dom-shim" "^1.0.0" +"@lit/reactive-element@^2.0.0", "@lit/reactive-element@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-2.0.4.tgz#8f2ed950a848016383894a26180ff06c56ae001b" + integrity sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + "@material-ui/core@^4.11.3": version "4.12.4" resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.12.4.tgz#4ac17488e8fcaf55eb6a7f5efb2a131e10138a73" @@ -4598,7 +4605,7 @@ mipd "0.0.7" zustand "4.4.1" -"@walletconnect/core@2.11.2", "@walletconnect/core@2.14.0", "@walletconnect/core@2.15.0": +"@walletconnect/core@2.11.2", "@walletconnect/core@2.14.0", "@walletconnect/core@2.15.0", "@walletconnect/core@2.16.1": version "2.14.0" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.14.0.tgz#e8afb01455968b02aaf26c74f3bfcc9b82678a39" integrity sha512-E/dgBM9q3judXnTfZQ5ILvDpeSdDpabBLsXtYXa3Nyc26cfNplfLJ2nXm9FgtTdhM1nZ7yx4+zDPiXawBRZl2g== @@ -4644,6 +4651,22 @@ "@walletconnect/utils" "2.15.0" events "3.3.0" +"@walletconnect/ethereum-provider@2.16.1": + version "2.16.1" + resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.16.1.tgz#4fb8a1df39104ad3fbd02579233e796f432f6d35" + integrity sha512-oD7DNCssUX3plS5gGUZ9JQ63muQB/vxO68X6RzD2wd8gBsYtSPw4BqYFc7KTO6dUizD6gfPirw32yW2pTvy92w== + dependencies: + "@walletconnect/jsonrpc-http-connection" "1.0.8" + "@walletconnect/jsonrpc-provider" "1.0.14" + "@walletconnect/jsonrpc-types" "1.0.4" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/modal" "2.6.2" + "@walletconnect/sign-client" "2.16.1" + "@walletconnect/types" "2.16.1" + "@walletconnect/universal-provider" "2.16.1" + "@walletconnect/utils" "2.16.1" + events "3.3.0" + "@walletconnect/events@1.0.1", "@walletconnect/events@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" @@ -4830,6 +4853,21 @@ "@walletconnect/utils" "2.15.0" events "3.3.0" +"@walletconnect/sign-client@2.16.1": + version "2.16.1" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.16.1.tgz#94a2f630ba741bd180f540c53576c5ceaace4857" + integrity sha512-s2Tx2n2duxt+sHtuWXrN9yZVaHaYqcEcjwlTD+55/vs5NUPlISf+fFmZLwSeX1kUlrSBrAuxPUcqQuRTKcjLOA== + dependencies: + "@walletconnect/core" "2.16.1" + "@walletconnect/events" "1.0.1" + "@walletconnect/heartbeat" "1.2.2" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "2.1.2" + "@walletconnect/time" "1.0.2" + "@walletconnect/types" "2.16.1" + "@walletconnect/utils" "2.16.1" + events "3.3.0" + "@walletconnect/time@1.0.2", "@walletconnect/time@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" @@ -4837,7 +4875,7 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.11.2", "@walletconnect/types@2.14.0", "@walletconnect/types@2.15.0": +"@walletconnect/types@2.11.2", "@walletconnect/types@2.14.0", "@walletconnect/types@2.15.0", "@walletconnect/types@2.16.1": version "2.14.0" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.14.0.tgz#af3d4799b8ac5d166251af12bc024276f82f9b91" integrity sha512-vevMi4jZLJ55vLuFOicQFmBBbLyb+S0sZS4IsaBdZkQflfGIq34HkN13c/KPl4Ye0aoR4/cUcUSitmGIzEQM5g== @@ -4864,7 +4902,22 @@ "@walletconnect/utils" "2.15.0" events "3.3.0" -"@walletconnect/utils@2.11.2", "@walletconnect/utils@2.14.0", "@walletconnect/utils@2.15.0": +"@walletconnect/universal-provider@2.16.1": + version "2.16.1" + resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.16.1.tgz#6d52c41c7388e01f89007956a1117748ab9a11e4" + integrity sha512-q/tyWUVNenizuClEiaekx9FZj/STU1F3wpDK4PUIh3xh+OmUI5fw2dY3MaNDjyb5AyrS0M8BuQDeuoSuOR/Q7w== + dependencies: + "@walletconnect/jsonrpc-http-connection" "1.0.8" + "@walletconnect/jsonrpc-provider" "1.0.14" + "@walletconnect/jsonrpc-types" "1.0.4" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "2.1.2" + "@walletconnect/sign-client" "2.16.1" + "@walletconnect/types" "2.16.1" + "@walletconnect/utils" "2.16.1" + events "3.3.0" + +"@walletconnect/utils@2.11.2", "@walletconnect/utils@2.14.0", "@walletconnect/utils@2.15.0", "@walletconnect/utils@2.16.1": version "2.14.0" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.14.0.tgz#48493ffe1e902815fda3cbd5cc5409288a066d35" integrity sha512-vRVomYQEtEAyCK2c5bzzEvtgxaGGITF8mWuIL+WYSAMyEJLY97mirP2urDucNwcUczwxUgI+no9RiNFbUHreQQ== @@ -4899,6 +4952,118 @@ "@walletconnect/window-getters" "^1.0.1" tslib "1.14.1" +"@web3modal/base@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/base/-/base-5.1.11.tgz#11beaca17fd0193d249174fb20da7bbb605abb2c" + integrity sha512-wJCsqQ1FG0Isiv0Exaz2Sv+FpijVmNPNay+sGdV5HP2SpBAR/1xxHca2/vLBdACX7rYAFAj723DYQE0fmUpIaw== + dependencies: + "@walletconnect/utils" "2.16.1" + "@web3modal/common" "5.1.11" + "@web3modal/core" "5.1.11" + "@web3modal/polyfills" "5.1.11" + "@web3modal/scaffold-ui" "5.1.11" + "@web3modal/scaffold-utils" "5.1.11" + "@web3modal/siwe" "5.1.11" + "@web3modal/ui" "5.1.11" + "@web3modal/wallet" "5.1.11" + optionalDependencies: + borsh "0.7.0" + bs58 "5.0.0" + +"@web3modal/common@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/common/-/common-5.1.11.tgz#29f6a0df6d6e1df7c3adb619efab08a6f20d4eab" + integrity sha512-YfSklKjjiM1RGxFTQm3ycYZ2Ktb6vswt9eg8lGXRknxN+SC7bCtuvgtyyCO0Z9/f9dPMOGIAmoJ/y6WHXWQqcg== + dependencies: + bignumber.js "9.1.2" + dayjs "1.11.10" + +"@web3modal/core@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/core/-/core-5.1.11.tgz#96406333c00ca949dbd1e8469e05b65d9c15551e" + integrity sha512-ugUVFVml1vVW+V7yxkn/AYYdrUJzn4ulFbDlxDMpmukKY6sDYLMMGAJ84O8ZC/OPyC7009NYd3mKZurxEyWkHw== + dependencies: + "@web3modal/common" "5.1.11" + "@web3modal/wallet" "5.1.11" + valtio "1.11.2" + +"@web3modal/polyfills@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/polyfills/-/polyfills-5.1.11.tgz#15f946e22c8d97dd43edc6fa8b7ff724c80e613d" + integrity sha512-BDIDYA2LGTCquahbZ+wyWQy4IBOPeKVSgt4ZpFir1fnVJUPkEluSwZStcKLtCzQvxJgER1sLicUrjJQHF36TOg== + dependencies: + buffer "6.0.3" + +"@web3modal/scaffold-ui@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/scaffold-ui/-/scaffold-ui-5.1.11.tgz#8e0e30c5da898b23b63dc4da5b9682d6ce99ca67" + integrity sha512-fBqzd7DStUaEjtdbEU86rzY4XIgt8c8JN8oxS/xnUEopmjFYvBLCCVEfbTkZyJrRvAAphz7+oS4TVzXw9k6t5A== + dependencies: + "@web3modal/common" "5.1.11" + "@web3modal/core" "5.1.11" + "@web3modal/scaffold-utils" "5.1.11" + "@web3modal/siwe" "5.1.11" + "@web3modal/ui" "5.1.11" + "@web3modal/wallet" "5.1.11" + lit "3.1.0" + +"@web3modal/scaffold-utils@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/scaffold-utils/-/scaffold-utils-5.1.11.tgz#85d880ca2ddea253ffb2f9fbccb9c9c3922ad107" + integrity sha512-4bcYpQ3oxak5mDZMW5/7ayrhpaJHy6dCfUio15AGPHnQlFjkqcfSuuG0Io8Oj8VUXcK2UBLch9YiEDz4Xgce9Q== + dependencies: + "@web3modal/common" "5.1.11" + "@web3modal/core" "5.1.11" + "@web3modal/polyfills" "5.1.11" + "@web3modal/wallet" "5.1.11" + valtio "1.11.2" + +"@web3modal/siwe@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/siwe/-/siwe-5.1.11.tgz#f68a43e7d5c5417ebfb85f82ce3478db4c5bc780" + integrity sha512-1aKEtMosACyY0SRjHjdcA/g3bRtMojTxlK7S/T6zBk57X/P3xcEZq9J8UM73plmGewjZdLaqGMgv6B/k/WleZQ== + dependencies: + "@walletconnect/utils" "2.16.1" + "@web3modal/common" "5.1.11" + "@web3modal/core" "5.1.11" + "@web3modal/scaffold-utils" "5.1.11" + "@web3modal/ui" "5.1.11" + "@web3modal/wallet" "5.1.11" + lit "3.1.0" + valtio "1.11.2" + +"@web3modal/ui@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/ui/-/ui-5.1.11.tgz#1bb5bdf3a54bbdf7d0068fdb65a46bc921da160c" + integrity sha512-L0L+2YOK+ONx+W7GPtkSdKZuAQ8cjcS5N8kp+WZzKOMUTeDLuXKtSnES4p/ShOVmkpV6qB8r0pPA9xgFh1D3ow== + dependencies: + lit "3.1.0" + qrcode "1.5.3" + +"@web3modal/wagmi@^5.0.6": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/wagmi/-/wagmi-5.1.11.tgz#19835c4905458d879b797da556acbf9a9ab721ee" + integrity sha512-etV1qfBVvh41EMuBHXUpcO/W818jZVNh5/l9Z5kqRPZxlQmBaJbt5mTzw6nw/Lujoe1yYKugGQFhgjfEQK+eyA== + dependencies: + "@walletconnect/ethereum-provider" "2.16.1" + "@walletconnect/utils" "2.16.1" + "@web3modal/base" "5.1.11" + "@web3modal/common" "5.1.11" + "@web3modal/polyfills" "5.1.11" + "@web3modal/scaffold-utils" "5.1.11" + "@web3modal/siwe" "5.1.11" + "@web3modal/wallet" "5.1.11" + +"@web3modal/wallet@5.1.11": + version "5.1.11" + resolved "https://registry.yarnpkg.com/@web3modal/wallet/-/wallet-5.1.11.tgz#3118bb1fa370436c252d7d97c731eac585cdb8a7" + integrity sha512-/ooQZXK1h7LGBUemebldYPAV2oJAgxkgSiCMoHWynhuS0LO3BzhOhGL+jV19w4iU81bS1GSNFTxYT9LL6Scesw== + dependencies: + "@walletconnect/logger" "2.1.2" + "@web3modal/common" "5.1.11" + "@web3modal/polyfills" "5.1.11" + zod "3.22.4" + "@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" @@ -5799,7 +5964,7 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -"bignumber.js@^8 || ^9", bignumber.js@^9.0.1, bignumber.js@^9.1.2: +bignumber.js@9.1.2, "bignumber.js@^8 || ^9", bignumber.js@^9.0.1, bignumber.js@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== @@ -5836,7 +6001,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.2.1: +bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -5877,6 +6042,15 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +borsh@0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + bowser@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -6024,6 +6198,13 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "2.x" +bs58@5.0.0, bs58@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" + integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== + dependencies: + base-x "^4.0.0" + bs58@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -6031,13 +6212,6 @@ bs58@^4.0.0: dependencies: base-x "^3.0.2" -bs58@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" - integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== - dependencies: - base-x "^4.0.0" - bs58check@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" @@ -6077,7 +6251,7 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@^6.0.3: +buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -7041,6 +7215,11 @@ date-fns@^2.29.3: dependencies: "@babel/runtime" "^7.21.0" +dayjs@1.11.10: + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== + dayjs@^1.11.11: version "1.11.11" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.11.tgz#dfe0e9d54c5f8b68ccf8ca5f72ac603e7e5ed59e" @@ -11412,6 +11591,15 @@ lit-element@^3.3.0: "@lit/reactive-element" "^1.3.0" lit-html "^2.8.0" +lit-element@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-4.1.1.tgz#07905992815076e388cf6f1faffc7d6866c82007" + integrity sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + "@lit/reactive-element" "^2.0.4" + lit-html "^3.2.0" + lit-html@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa" @@ -11419,6 +11607,13 @@ lit-html@^2.8.0: dependencies: "@types/trusted-types" "^2.0.2" +lit-html@^3.1.0, lit-html@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-3.2.1.tgz#8fc49e3531ee5947e4d93e8a5aa642ab1649833b" + integrity sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA== + dependencies: + "@types/trusted-types" "^2.0.2" + lit@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/lit/-/lit-2.8.0.tgz#4d838ae03059bf9cafa06e5c61d8acc0081e974e" @@ -11428,6 +11623,15 @@ lit@2.8.0: lit-element "^3.3.0" lit-html "^2.8.0" +lit@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-3.1.0.tgz#76429b85dc1f5169fed499a0f7e89e2e619010c9" + integrity sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w== + dependencies: + "@lit/reactive-element" "^2.0.0" + lit-element "^4.0.0" + lit-html "^3.1.0" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -15797,6 +16001,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -17312,6 +17521,11 @@ yup@^0.32.9: property-expr "^2.0.4" toposort "^2.0.2" +zod@3.22.4: + version "3.22.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== + zustand@4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.1.tgz#0cd3a3e4756f21811bd956418fdc686877e8b3b0"