diff --git a/asset-manifest.json b/asset-manifest.json index f55022c..4334450 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,13 +1,13 @@ { "files": { - "main.js": "./static/js/main.cbcc13fc.chunk.js", - "main.js.map": "./static/js/main.cbcc13fc.chunk.js.map", + "main.js": "./static/js/main.eb209abb.chunk.js", + "main.js.map": "./static/js/main.eb209abb.chunk.js.map", "runtime-main.js": "./static/js/runtime-main.cb4effe6.js", "runtime-main.js.map": "./static/js/runtime-main.cb4effe6.js.map", "static/js/2.c60be174.chunk.js": "./static/js/2.c60be174.chunk.js", "static/js/2.c60be174.chunk.js.map": "./static/js/2.c60be174.chunk.js.map", "index.html": "./index.html", - "precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js": "./precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js", + "precache-manifest.d4c599646a474981f970b693f824a083.js": "./precache-manifest.d4c599646a474981f970b693f824a083.js", "service-worker.js": "./service-worker.js", "static/js/2.c60be174.chunk.js.LICENSE.txt": "./static/js/2.c60be174.chunk.js.LICENSE.txt", "static/media/add-circle-icon.42a49a22.svg": "./static/media/add-circle-icon.42a49a22.svg", @@ -31,6 +31,6 @@ "entrypoints": [ "static/js/runtime-main.cb4effe6.js", "static/js/2.c60be174.chunk.js", - "static/js/main.cbcc13fc.chunk.js" + "static/js/main.eb209abb.chunk.js" ] } \ No newline at end of file diff --git a/index.html b/index.html index f8e8e71..91581d8 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Zodiac - Safe App
\ No newline at end of file +Zodiac - Safe App
\ No newline at end of file diff --git a/precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js b/precache-manifest.d4c599646a474981f970b693f824a083.js similarity index 94% rename from precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js rename to precache-manifest.d4c599646a474981f970b693f824a083.js index 4562f88..285d1ef 100644 --- a/precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js +++ b/precache-manifest.d4c599646a474981f970b693f824a083.js @@ -1,6 +1,6 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ { - "revision": "ae620502ca886557fc63c189731c38b9", + "revision": "ebec1dd979a28806e57f088b8c143170", "url": "./index.html" }, { @@ -12,8 +12,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "./static/js/2.c60be174.chunk.js.LICENSE.txt" }, { - "revision": "66ce0b1eb3ca5b1a8512", - "url": "./static/js/main.cbcc13fc.chunk.js" + "revision": "9d8f1f8174fff26a233e", + "url": "./static/js/main.eb209abb.chunk.js" }, { "revision": "fc6f85f5de474b47850b", diff --git a/service-worker.js b/service-worker.js index 7e64840..53d49d3 100644 --- a/service-worker.js +++ b/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "./precache-manifest.9e70dd88981ae60480f98be1cfa93cbe.js" + "./precache-manifest.d4c599646a474981f970b693f824a083.js" ); self.addEventListener('message', (event) => { diff --git a/static/js/main.cbcc13fc.chunk.js b/static/js/main.cbcc13fc.chunk.js deleted file mode 100644 index 6b859d9..0000000 --- a/static/js/main.cbcc13fc.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(this["webpackJsonpzodiac-app"]=this["webpackJsonpzodiac-app"]||[]).push([[0],{1118:function(e,t){},1212:function(e,t){},1214:function(e,t){},1412:function(e,t){},1417:function(e,t){},1435:function(e,t){},1437:function(e,t){},1458:function(e,t){},1495:function(e,t){},1593:function(e,t){},1636:function(e,t){},1656:function(e,t,a){"use strict";a.r(t);var n,r,o,c=a(0),i=a.n(c),l=a(60),s=a.n(l),u=a(472),d=a(1713),f=a(1722),m=a(64),p=a(71),b=a.n(p),g=a(501),h=a(14),E=Object(g.a)((function(e){return{root:{display:"grid",height:"calc(100% - 70px)",gridTemplateColumns:"390px 1fr",gridGap:e.spacing(.5),overflow:"hidden",padding:e.spacing(.5)},leftPanel:{overflowY:"auto"},content:{overflowY:"auto"}}})),v=function(e){var t=e.children,a=e.left,n=E();return i.a.createElement(h.c,{variant:"outlined",className:n.root},i.a.createElement(h.c,{variant:"outlined",className:n.content},a),i.a.createElement(h.c,{variant:"outlined",id:"app-content",className:n.content},t))},y=a(758),O=a(503),x=a(18),w=a(57),j=a(1),C=a.n(j),k=a(25),S=a(212),N=a(12),I=a(34),T=a(69),A=a(226),R=a(298),M=a(29),B=a(537),D="0x0000000000000000000000000000000000000001",L=function(e,t,a,n,r){return{to:t,data:e.encodeFunctionData(a,n),value:r||"0"}},P=a(9);!function(e){e[e.MAINNET=1]="MAINNET",e[e.GOERLI=5]="GOERLI",e[e.OPTIMISM=10]="OPTIMISM",e[e.BSC=56]="BSC",e[e.GNOSIS_CHAIN=100]="GNOSIS_CHAIN",e[e.POLYGON=137]="POLYGON",e[e.ARBITRUM=42161]="ARBITRUM",e[e.AVALANCHE=43114]="AVALANCHE"}(o||(o={}));var F,U={ETH:{symbol:"ETH",decimals:18},XDAI:{symbol:"xDai",decimals:18},MATIC:{symbol:"MATIC",decimals:18},BNB:{symbol:"BNB",decimals:18},AVAX:{symbol:"AVAX",decimals:18}},V=(n={},Object(P.a)(n,o.MAINNET,{chainId:o.MAINNET,name:"mainnet",shortName:"eth",nativeAsset:U.ETH}),Object(P.a)(n,o.GOERLI,{chainId:o.GOERLI,name:"goerli",shortName:"gor",nativeAsset:U.ETH}),Object(P.a)(n,o.OPTIMISM,{chainId:o.OPTIMISM,name:"optimism",shortName:"oeth",nativeAsset:U.ETH}),Object(P.a)(n,o.GNOSIS_CHAIN,{chainId:o.GNOSIS_CHAIN,name:"gnosis_chain",shortName:"gno",nativeAsset:U.XDAI}),Object(P.a)(n,o.BSC,{chainId:o.BSC,name:"binance_smart_chain",shortName:"bnb",nativeAsset:U.BNB}),Object(P.a)(n,o.POLYGON,{chainId:o.POLYGON,name:"polygon",shortName:"matic",nativeAsset:U.MATIC}),Object(P.a)(n,o.ARBITRUM,{chainId:o.ARBITRUM,name:"arbitrum",shortName:"arb1",nativeAsset:U.ETH}),Object(P.a)(n,o.AVALANCHE,{chainId:o.AVALANCHE,name:"avalanche",shortName:"avax",nativeAsset:U.AVAX}),n);r={},Object(P.a)(r,o.MAINNET,U.ETH),Object(P.a)(r,o.GOERLI,U.ETH),Object(P.a)(r,o.OPTIMISM,U.ETH),Object(P.a)(r,o.GNOSIS_CHAIN,U.XDAI),Object(P.a)(r,o.POLYGON,U.MATIC),Object(P.a)(r,o.BSC,U.BNB),Object(P.a)(r,o.ARBITRUM,U.ETH),Object(P.a)(r,o.AVALANCHE,U.AVAX);var H=(F={},Object(P.a)(F,o.MAINNET,{networkExplorerName:"Etherscan",networkExplorerUrl:"https://etherscan.io",networkExplorerApiUrl:"https://api.etherscan.io/api",safeTransactionApi:"https://safe-transaction-mainnet.safe.global/",safeUrl:"https://app.safe.global/eth:",verifyContractUrl:"https://etherscan.io/verifyContract",explorerApiKey:"6RJ8KT4B1S9V7E3CIYECNY7HFW8IPWQ3C4"}),Object(P.a)(F,o.GOERLI,{networkExplorerName:"Etherscan",networkExplorerUrl:"https://goerli.etherscan.io",networkExplorerApiUrl:"https://api-goerli.etherscan.io/api",safeTransactionApi:"https://safe-transaction-goerli.safe.global/",safeUrl:"https://app.safe.global/gor:",verifyContractUrl:"https://goerli.etherscan.io/verifyContract",explorerApiKey:"6RJ8KT4B1S9V7E3CIYECNY7HFW8IPWQ3C4"}),Object(P.a)(F,o.GNOSIS_CHAIN,{networkExplorerName:"GnosisScan",networkExplorerUrl:"https://gnosisscan.io",networkExplorerApiUrl:"https://api.gnosisscan.io/api",safeUrl:"https://app.safe.global/gno:",safeTransactionApi:"https://safe-transaction-gnosis-chain.safe.global/",verifyContractUrl:"https://gnosisscan.io/verifyContract",explorerApiKey:"8ENCUFT4D3XVJS7N9ZFS5Z9XQPNUGRKSN5"}),Object(P.a)(F,o.POLYGON,{networkExplorerName:"Polygonscan",networkExplorerUrl:"https://polygonscan.com",networkExplorerApiUrl:"https://api.polygonscan.com/api",safeUrl:"https://app.safe.global/matic:",safeTransactionApi:"https://safe-transaction-polygon.safe.global/",verifyContractUrl:"https://polygonscan.com/verifyContract",explorerApiKey:"T6WFHXT4HZZ1DISYBINENCSRY38JUW3IU7"}),Object(P.a)(F,o.BSC,{networkExplorerName:"Bscscan",networkExplorerUrl:"https://bscscan.com/",networkExplorerApiUrl:"https://api.bscscan.com/api",safeUrl:"https://app.safe.global/bsc:",safeTransactionApi:"https://safe-transaction-bsc.safe.global/",verifyContractUrl:"https://bscscan.com/verifyContract",explorerApiKey:"AW26UH2PS6I2U6V2537YUBDF5CJVCNDM5E"}),Object(P.a)(F,o.OPTIMISM,{networkExplorerName:"Optimism",networkExplorerUrl:"https://optimistic.etherscan.io/",networkExplorerApiUrl:"https://api-optimistic.etherscan.io/api",safeTransactionApi:"https://safe-transaction-optimism.safe.global/",safeUrl:"https://app.safe.global/oeth:",verifyContractUrl:"https://optimistic.etherscan.io/verifyContract",explorerApiKey:"JXEAJD2QC2Y5GY783GJ3HZ5KP7A4C3F2JH"}),Object(P.a)(F,o.ARBITRUM,{networkExplorerName:"Arbiscan",networkExplorerUrl:"https://arbiscan.io/",networkExplorerApiUrl:"https://api.arbiscan.io/api",safeTransactionApi:"https://safe-transaction-arbitrum.safe.global/",safeUrl:"https://app.safe.global/arb1:",verifyContractUrl:"https://arbiscan.io/verifyContract",explorerApiKey:"KQYPWCBF5Q2S7W8T95K3CVB74BEC6AKCWK"}),Object(P.a)(F,o.AVALANCHE,{networkExplorerName:"Snowtrace",networkExplorerUrl:"https://snowtrace.io/",networkExplorerApiUrl:"https://api.snowtrace.io/api",safeTransactionApi:"https://safe-transaction-avalanche.safe.global/",safeUrl:"https://app.safe.global/avax:",verifyContractUrl:"https://snowtrace.io/verifyContract",explorerApiKey:"4SV7ZU6UA9JJH922KR37J9Q1PPBGVZZF9C"}),F),_=function(e){var t=H[e];if(t)return{name:t.networkExplorerName,url:t.networkExplorerUrl,apiUrl:t.networkExplorerApiUrl,apiKey:t.explorerApiKey,safeTransactionApi:t.safeTransactionApi,safeUrl:t.safeUrl,verifyUrl:t.verifyContractUrl}},G=["function token() view returns (address)"],W=["function name() view returns (string)","function symbol() view returns (string)","function decimals() public view returns (uint8)"],z=["function supportsInterface(bytes4 interfaceID) external view returns (bool)"];function K(){return(K=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,r=new A.b(a,G,t),e.next=4,r.token();case 4:return o=e.sent,c=new A.b(o,W,t),e.next=8,c.symbol();case 8:return e.t0=e.sent,e.next=11,c.decimals();case 11:return e.t1=e.sent,i={symbol:e.t0,decimals:e.t1},e.abrupt("return",{isERC20:!0,coin:i});case 16:return e.prev=16,e.t2=e.catch(0),e.abrupt("return",{isERC20:!1,coin:V[n].nativeAsset});case 19:case"end":return e.stop()}}),e,null,[[0,16]])})))).apply(this,arguments)}var Y,Z=a(482),q=a(1714),X=a(481),Q=a(707),J=a(469),$=["svgRef","title"];function ee(){return(ee=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ae=function(e){var t=e.svgRef,a=e.title,n=te(e,$);return i.a.createElement("svg",ee({width:15,height:12,viewBox:"0 0 15 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Y||(Y=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z",fill:"#001428"})))},ne=i.a.forwardRef((function(e,t){return i.a.createElement(ae,ee({svgRef:t},e))})),re=(a.p,{USDC:"USDC",WETH:"WETH"});var oe,ce=[o.MAINNET,o.POLYGON,o.GOERLI,o.GNOSIS_CHAIN,o.OPTIMISM,o.ARBITRUM,o.AVALANCHE],ie=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:e.spacing(1)},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},select:{marginBottom:-1,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"100%"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1}}})),le=function(e){var t=e.onChange,a=e.defaultOption,n=void 0===a?re.USDC:a,r=e.label,o=e.chainId,l=ie(),s=Object(c.useState)(n),u=Object(x.a)(s,2),d=u[0],f=u[1],m=Object(c.useState)(!1),p=Object(x.a)(m,2),b=p[0],g=p[1],h=function(){return g(!1)},E=function(){return g(!0)},v=i.a.useRef(null),y=function(e){h();var a=Object.keys(re).find((function(t){return re["".concat(t)]===e}));f(e);var n=fe(o,"WETH"===a);t(n)};return Object(c.useEffect)((function(){v.current&&v.current.addEventListener("keyup",(function(e){"Tab"===e.code&&E()}))}),[v]),i.a.createElement("div",null,i.a.createElement(Z.a,{className:l.label},r),i.a.createElement(q.a,{container:!0,className:l.root},i.a.createElement(q.a,{item:!0,xs:12,className:l.dropdownContainer},i.a.createElement(X.a,{disableUnderline:!0,open:b,value:d,ref:v,onOpen:E,onClose:h,className:l.select,MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:l.dropdown,list:l.itemList}},renderValue:function(e){return e},onChange:function(e){return y(e.target.value)}},Object.keys(re).map((function(e){return ce.includes(o)||"WETH"!==e?i.a.createElement(Q.a,{key:e,value:re["".concat(e)],className:l.item},re["".concat(e)],i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"})):null}))))))};function se(e){switch(e){case o.MAINNET:case o.POLYGON:case o.GNOSIS_CHAIN:case o.GOERLI:case o.OPTIMISM:case o.ARBITRUM:return"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0"}return""}function ue(e){switch(e){case o.MAINNET:return"0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c";case o.BSC:return"0xa925646Cae3721731F9a8C886E5D1A7B123151B9";case o.GNOSIS_CHAIN:return"0xE78996A233895bE74a66F451f1019cA9734205cc";case o.POLYGON:return"0x60573B8DcE539aE5bF9aD7932310668997ef0428";case o.GOERLI:return"0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f";case o.OPTIMISM:return"0x0eF940F7f053a2eF5D6578841072488aF0c7d89A";case o.ARBITRUM:return"0x5D18bD4dC5f1AC8e9bD9B666Bd71cB35A327C4A9";case o.AVALANCHE:return"0xD88cd78631Ea0D068cedB0d1357a6eabe59D7502"}return""}function de(e){switch(e){case o.MAINNET:return"0x40f941E48A552bF496B154Af6bf55725f18D77c3";case o.POLYGON:return"0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64";case o.GOERLI:return"0xE60dBa66B85E10E7Fd18a67a6859E241A243950e";case o.GNOSIS_CHAIN:return"0xeF684C38F94F48775959ECf2012D7E864ffb9dd4";case o.OPTIMISM:return"0x278d6b1aA37d09769E519f05FcC5923161A8536D";case o.ARBITRUM:return"0xB0b9f73B424AD8dc58156C2AE0D7A1115D1EcCd1";case o.AVALANCHE:return"0xCFdC4d6FdeC25e339ef07e25C35a482A6bedcfE0"}return""}function fe(e,t){return t?function(e){switch(e){case o.MAINNET:return"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";case o.POLYGON:return"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619";case o.GOERLI:return"0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6";case o.GNOSIS_CHAIN:return"0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1";case o.OPTIMISM:return"0x4200000000000000000000000000000000000006";case o.ARBITRUM:return"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";case o.AVALANCHE:return"0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB"}return""}(e):function(e){switch(e){case o.MAINNET:return"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";case o.POLYGON:return"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";case o.GOERLI:return"0x07865c6E87B9F70255377e024ace6630C1Eaa37F";case o.GNOSIS_CHAIN:return"0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83";case o.OPTIMISM:return"0x7F5c764cBc14f9669B88837ca1490cCa17c31607";case o.ARBITRUM:return"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";case o.AVALANCHE:return"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}return""}(e)}function me(e){switch(e){case o.MAINNET:return"0xf72cfd1b34a91a64f9a98537fe63fbab7530adca";case o.GOERLI:return"0xba08deb3f07a9c55052777fed84a86be8e5ebc1c";case o.GNOSIS_CHAIN:return"0x29f39de98d750eb77b5fafb31b2837f079fce222";case o.POLYGON:return"0x5AFa42b30955f137e10f89dfb5EF1542a186F90e"}return""}function pe(e,t){switch(t){case oe.NO_ARBITRATOR:return ue(e);case oe.KLEROS:return me(e);case oe.OTHER:return""}return""}function be(e){switch(e){case o.MAINNET:return"0x8898B472C54c31894e3B9bb83cEA802a5d0e63C6";case o.POLYGON:return"0x11984dc4465481512eb5b777E44061C158CF2259";case o.GOERLI:return"0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649";case o.GNOSIS_CHAIN:return"0x5bB83e95f63217CDa6aE3D181BA580Ef377D2109";case o.OPTIMISM:return"0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA";case o.ARBITRUM:return"0xEE9deC2712cCE65174B561151701Bf54b99C24C8"}return""}function ge(e,t,a,n){var r=M.d.TELLOR,o=n.owner,c=n.oracle,i=n.cooldown,l=n.expiration,s=n.executor,u=c||se(a),d=Object(M.f)(r,{types:["address","address","address","address","uint32","uint32"],values:[o,t,s,u,i,l]},e,a,Date.now().toString()),f=d.transaction,m=d.expectedModuleAddress,p=[Object(N.a)(Object(N.a)({},f),{},{value:f.value.toString()})];if(s!==t){var b=Object(M.h)(M.d.DELAY,s,e),g=L(b.interface,b.address,"enableModule",[m]);p.push(g)}else{var h=je(t,m);p.push(h)}return p}function he(e,t,a,n){var r=n,o=r.cooldown,c=r.expiration,i=r.executor,l=Object(M.f)(M.d.DELAY,{types:["address","address","address","uint256","uint256"],values:[t,t,i,o,c]},e,a,Date.now().toString()),s=l.transaction,u=je(t,l.expectedModuleAddress);return[Object(N.a)(Object(N.a)({},s),{},{value:s.value.toString()}),u]}function Ee(e,t,a,n){var r=n.executor,o=n.controller,c=n.amb,i=n.chainId,l=Object(M.f)(M.d.BRIDGE,{types:["address","address","address","address","address","bytes32"],values:[t,t,r,c,o,I.ethers.utils.hexZeroPad(T.a.from(i).toHexString(),32)]},e,a,Date.now().toString()),s=l.transaction,u=je(t,l.expectedModuleAddress);return[Object(N.a)(Object(N.a)({},s),{},{value:s.value.toString()}),u]}function ve(e,t,a,n,r,o){var c=o?M.d.CIRCULATING_SUPPLY_ERC721:M.d.CIRCULATING_SUPPLY_ERC20,i=Object(M.g)(c,e,a),l=i.moduleFactory,s=i.moduleMastercopy,u=(new I.ethers.utils.AbiCoder).encode(["address","address","address[]"],[t,n,[t]]),d=s.interface.encodeFunctionData("setUp",[u]),f=Object(M.e)(l,s.address,d,r);return{transaction:{data:l.interface.encodeFunctionData("deployModule",[s.address,d,r]),to:l.address,value:"0"},expectedAddress:f}}function ye(e,t,a,n){return Oe.apply(this,arguments)}function Oe(){return(Oe=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f,m,p,b,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return o=[],c=r.executor,i=r.tokenContract,l=!1,e.prev=3,s=new A.b(i,z,t),e.next=7,s.supportsInterface("0x80ac58cd");case 7:l=e.sent,e.next=13;break;case 10:e.prev=10,e.t0=e.catch(3),console.warn("deployExitModule: error determining token type");case 13:return u=ve(t,a,n,i,Date.now().toString(),l),d=u.transaction,f=u.expectedAddress,o.push(d),m=l?M.d.EXIT_ERC721:M.d.EXIT_ERC20,p=Object(M.f)(m,{types:["address","address","address","address","address"],values:[a,a,c,i,f]},t,n,Date.now().toString()),b=p.transaction,g=p.expectedModuleAddress,o.push(Object(N.a)(Object(N.a)({},b),{},{value:b.value.toString()})),h=je(a,g),o.push(h),e.abrupt("return",o);case 21:case"end":return e.stop()}}),e,null,[[3,10]])})))).apply(this,arguments)}function xe(e,t,a){return we.apply(this,arguments)}function we(){return(we=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new A.b(a,B.a,t),e.next=3,r.getModulesPaginated(D,50);case 3:return o=e.sent,c=Object(x.a)(o,1),i=c[0],e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function je(e,t){return L(new R.b(B.a),e,"enableModule",[t])}function Ce(e,t,a,n){return ke.apply(this,arguments)}function ke(){return(ke=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,xe(t,a,n);case 2:if((o=e.sent).length){e.next=5;break}throw new Error("Safe does not have enabled modules");case 5:return c=D,o.length>1&&(i=o.findIndex((function(e){return e.toLowerCase()===r.toLowerCase()})))>0&&(c=o[i-1]),l=[c,r],e.abrupt("return",Object(N.a)({params:l},L(new R.b(B.a),a,"disableModule",l)));case 9:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(e){e[e.NO_ARBITRATOR=0]="NO_ARBITRATOR",e[e.KLEROS=1]="KLEROS",e[e.OTHER=2]="OTHER"}(oe||(oe={}));var Se=function(e,t,a,n,r){var o,c=arguments.length>5&&void 0!==arguments[5]?arguments[5]:[],i=new A.b(a,n,e);return(o=i.functions)[r].apply(o,Object(w.a)(c))};function Ne(e,t,a){return Ie.apply(this,arguments)}function Ie(){return(Ie=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=_(t)){e.next=3;break}return e.abrupt("return",[]);case 3:return o=new URL("api/v1/safes/".concat(a,"/transactions"),r.safeTransactionApi),Object.entries(n).forEach((function(e){var t=Object(x.a)(e,2),a=t[0],n=t[1];return o.searchParams.set(a,n)})),e.next=7,fetch(o.toString());case 7:return c=e.sent,e.next=10,c.json();case 10:return i=e.sent,e.abrupt("return",i.results);case 12:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Te(e,t){return Ae.apply(this,arguments)}function Ae(){return(Ae=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n=_(t)){e.next=3;break}throw new Error("invalid network");case 3:return r=new URL("api/v1/safes/".concat(a),n.safeTransactionApi),e.next=6,fetch(r.toString());case 6:return o=e.sent,e.next=9,o.json();case 9:return c=e.sent,e.abrupt("return",c);case 11:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Re(e,t,a,n){var r=n.target,o=n.multisend,c=Object(M.f)(M.d.ROLES_V1,{types:["address","address","address"],values:[t,t,r]},e,a,Date.now().toString()),i=c.transaction,l=c.expectedModuleAddress,s=je(t,l),u=Object(M.h)(M.d.ROLES_V1,l,e),d=L(u.interface,u.address,"setMultisend",[o]);return[Object(N.a)(Object(N.a)({},i),{},{value:i.value.toHexString()}),s,d]}function Me(e,t,a,n){var r=n.target,o=n.multisend,c=Object(M.f)(M.d.ROLES_V2,{types:["address","address","address"],values:[t,t,r]},e,a,Date.now().toString()),i=c.transaction,l=c.expectedModuleAddress,s=je(t,l),u=Object(M.h)(M.d.ROLES_V2,l,e),d={to:u.address,data:u.interface.encodeFunctionData("setTransactionUnwrapper",[o,"0x8d80ff0a","0x93B7fCbc63ED8a3a24B59e1C3e6649D50B7427c0"]),value:"0"};return[Object(N.a)(Object(N.a)({},i),{},{value:i.value.toHexString()}),s,d]}function Be(e,t,a,n,r){var o=M.d.OPTIMISTIC_GOVERNOR,c=n.executor,i=n.collateral,l=n.bond,s=n.rules,u=n.identifier,d=n.liveness,f=function(e,t){return t?Number(e)*Math.pow(10,18):Number(e)*Math.pow(10,6)}(l,r).toString(),m=Object(M.f)(o,{types:["address","address","uint256","string","bytes32","uint64"],values:[c,i,f,s,u,d]},e,a,Date.now().toString()),p=m.transaction,b=m.expectedModuleAddress,g=[Object(N.a)(Object(N.a)({},p),{},{value:p.value.toString()})];if(c!==t){var h=Object(M.h)(M.d.DELAY,c,e),E=L(h.interface,h.address,"enableModule",[b]);g.push(E)}else{var v=je(t,b);g.push(v)}return g}function De(e,t,a,n){var r=M.d.CONNEXT,o=n.domainId,c=n.sender,i=n.owner,l=n.avatar,s=n.target,u=be(a),d=Object(M.f)(r,{types:["address","address","address","address","uint32","address"],values:[i,l,s,c,o,u]},e,a,Date.now().toString()),f=d.transaction,m=d.expectedModuleAddress,p=[Object(N.a)(Object(N.a)({},f),{},{value:f.value.toString()})],b=je(t,m);return p.push(b),p}var Le,Pe,Fe,Ue=a(486),Ve=a(96),He=a(300),_e=a(487),Ge=a.n(_e);!function(e){e.TELLOR="tellor",e.OPTIMISTIC_GOVERNOR="optimisticGovernor",e.REALITY_ETH="realityETH",e.REALITY_ERC20="realityERC20",e.DELAY="delay",e.BRIDGE="bridge",e.EXIT="exit",e.ROLES_V1="roles_v1",e.ROLES_V2="roles_v2",e.OZ_GOVERNOR="ozGovernor",e.KLEROS_REALITY="klerosReality",e.CONNEXT="connext",e.UNKNOWN="unknown"}(Fe||(Fe={}));var We,ze=(Le={},Object(P.a)(Le,Fe.TELLOR,"Tellor Module"),Object(P.a)(Le,Fe.OPTIMISTIC_GOVERNOR,"UMA oSnap Module"),Object(P.a)(Le,Fe.REALITY_ERC20,"Reality Module"),Object(P.a)(Le,Fe.REALITY_ETH,"Reality Module"),Object(P.a)(Le,Fe.KLEROS_REALITY,"Kleros Reality Module"),Object(P.a)(Le,Fe.UNKNOWN,"Unknown Module"),Object(P.a)(Le,Fe.BRIDGE,"Bridge Module"),Object(P.a)(Le,Fe.DELAY,"Delay Modifier"),Object(P.a)(Le,Fe.ROLES_V1,"Roles Modifier (v1)"),Object(P.a)(Le,Fe.ROLES_V2,"Roles Modifier (v2)"),Object(P.a)(Le,Fe.EXIT,"Exit Module"),Object(P.a)(Le,Fe.OZ_GOVERNOR,"Governor Module"),Object(P.a)(Le,Fe.CONNEXT,"Connext Module"),Le),Ke=(Pe={},Object(P.a)(Pe,Fe.TELLOR,M.a[M.d.TELLOR]),Object(P.a)(Pe,Fe.OPTIMISTIC_GOVERNOR,M.a[M.d.OPTIMISTIC_GOVERNOR]),Object(P.a)(Pe,Fe.REALITY_ERC20,M.a[M.d.REALITY_ERC20]),Object(P.a)(Pe,Fe.REALITY_ETH,M.a[M.d.REALITY_ETH]),Object(P.a)(Pe,Fe.KLEROS_REALITY,M.a[M.d.REALITY_ETH]),Object(P.a)(Pe,Fe.UNKNOWN,[]),Object(P.a)(Pe,Fe.BRIDGE,M.a[M.d.BRIDGE]),Object(P.a)(Pe,Fe.DELAY,M.a[M.d.DELAY]),Object(P.a)(Pe,Fe.ROLES_V1,M.a[M.d.ROLES_V1]),Object(P.a)(Pe,Fe.ROLES_V2,M.a[M.d.ROLES_V2]),Object(P.a)(Pe,Fe.EXIT,M.a[M.d.EXIT_ERC20]),Object(P.a)(Pe,Fe.OZ_GOVERNOR,M.a[M.d.OZ_GOVERNOR]),Object(P.a)(Pe,Fe.CONNEXT,M.a[M.d.CONNEXT]),Pe);!function(e){e[e.CREATE=0]="CREATE",e[e.REMOVE=1]="REMOVE"}(We||(We={}));var Ye=["function masterCopy() external view returns (address)"];function Ze(e){if(e!==Fe.UNKNOWN)return{type:e,name:ze[e],abi:Ke[e]}}function qe(e){return"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea265627a7a72315820d8a00dc4fe6bf675a9d7416fc2d00bb3433362aa8186b750f76c4027269667ff64736f6c634300050e0032"===e.toLowerCase()}function Xe(e){return 92===e.length&&(e.startsWith("0x363d3d373d3d3d363d73")&&e.endsWith("5af43d82803e903d91602b57fd5bf3"))}function Qe(e){return"0x"+e.substr(22,40)}function Je(e,t,a){return $e.apply(this,arguments)}function $e(){return($e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new A.b(a,Ye,t),e.next=3,r.functions.masterCopy();case 3:return o=e.sent,c=Object(x.a)(o,1),i=c[0],e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var et=a(745),tt=a.n(et);function at(e){return!e.stateMutability||!["view","pure"].includes(e.stateMutability)}function nt(e){return!at(e)}var rt=Ge()((function(e,t){return tt()(function(){var a=Object(k.a)(C.a.mark((function a(n){var r,o,c,i,l,s,u,d,f,m;return C.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:if(r=_(e)){a.next=3;break}throw new Error("Network data not found");case 3:return o=r.apiUrl,c=r.apiKey,i={module:"contract",action:"getsourcecode",address:t},c&&(i.apiKey=c),l=new URLSearchParams(i),a.next=9,fetch("".concat(o,"?").concat(l));case 9:if((s=a.sent).ok){a.next=12;break}throw new Error("Could not fetch contract source code");case 12:return a.next=14,s.json();case 14:if(u=a.sent,d=u.status,f=u.result,"0"!==d){a.next=19;break}throw new Error("Could not fetch contract source code");case 19:return(m=f[0]).ContractName||n(new Error("Contract is not verified")),a.abrupt("return",m);case 22:case"end":return a.stop()}}),a)})));return function(e){return a.apply(this,arguments)}}(),{retries:4,minTimeout:1e3})}),(function(e,t){return"".concat(e,"_").concat(t)}));function ot(e){return!e.inputs.length}function ct(e){var t,a;return 1===(null===(t=e.outputs)||void 0===t?void 0:t.length)&&e.outputs&&"array"!==(null===(a=e.outputs[0])||void 0===a?void 0:a.baseType)}function it(e,t){var a=t;if("array"===e.baseType||"tuple"===e.baseType)try{a=JSON.parse(a)}catch(n){throw new Error("Input must be of type "+e.baseType)}if(!function(e,t){try{return He.b.encode([e],[t]),!0}catch(a){return!1}}(e,a))throw new Error("Input must be of type "+e.type);return a}function lt(e,t){if("array"===e.baseType||"tuple"===e.baseType)try{return JSON.stringify(t)}catch(a){console.warn("formatDisplayParamValue: value is not an object",t,a)}return t.toString()}var st,ut=Ge()(function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f,m;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,a.eth.getCode([r]);case 2:if(!Xe(o=e.sent)){e.next=9;break}return c=Qe(o),e.next=7,ut(t,a,n,c);case 7:return i=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},i),{},{address:r}));case 9:if(!qe(o)){e.next=17;break}return e.next=12,Je(t,r,n);case 12:return l=e.sent,e.next=15,ut(t,a,n,l);case 15:return s=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},s),{},{address:r}));case 17:if((u=wt(n,r))===Fe.UNKNOWN){e.next=20;break}return e.abrupt("return",Object(N.a)({type:u,address:r,implAddress:r,name:Tt(u)},Ze(u)));case 20:return e.prev=20,e.next=23,rt(n,r);case 23:return d=e.sent,f=d.ABI,m=d.ContractName,e.abrupt("return",{address:r,implAddress:r,name:m,abi:f,type:Fe.UNKNOWN});case 29:return e.prev=29,e.t0=e.catch(20),e.abrupt("return",{address:r,implAddress:r,type:Fe.UNKNOWN});case 32:case"end":return e.stop()}}),e,null,[[20,29]])})));return function(t,a,n,r){return e.apply(this,arguments)}}(),(function(e,t,a,n){return"".concat(t,"_").concat(a,"_").concat(n)}));function dt(e,t){return"array"!==e&&"tuple"!==e||(t=JSON.stringify(t)),t.toString()}var ft="0x0000000000000000000000000000000000000001";function mt(e){return e.type===Fe.DELAY}var pt=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u=arguments;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c=u.length>5&&void 0!==u[5]?u[5]:[a],e.next=3,ut(t,n,r,a);case 3:if((i=e.sent).type!==Fe.DELAY){e.next=8;break}return e.next=7,bt(t,a,n,r,o);case 7:return e.abrupt("return",e.sent);case 8:return e.next=10,ht(t,a,i.abi,n,r,c);case 10:return l=e.sent,e.next=13,vt(t,a,i.abi,r);case 13:return s=e.sent,e.abrupt("return",{owner:s,subModules:l,id:a,name:i.name,type:i.type,address:a,parentModule:o});case 15:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}();function bt(e,t,a,n,r){return gt.apply(this,arguments)}function gt(){return(gt=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d,f,m,p,b,g,h,E,v,y;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(M.h)(M.d.DELAY,a,t);case 2:return c=e.sent,i=c.interface.fragments.map((function(e){return e})),e.prev=4,l=new Ue.Contract(c.address,i),s=new Ue.Provider,e.next=9,s.init(t);case 9:return u=l.txCooldown(),d=l.txExpiration(),f=l.getModulesPaginated(ft,50),e.next=14,s.all([u,d,f]);case 14:if(m=e.sent,p=Object(x.a)(m,3),b=p[0],g=p[1],h=Object(x.a)(p[2],1),!(E=h[0])){e.next=26;break}return(v=E.map(function(){var e=Object(k.a)(C.a.mark((function e(c,i){var l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,pt(t,c,n,r,o);case 2:return l=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},l),{},{id:"".concat(a,"_").concat(c,"_").concat(i),parentModule:a}));case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}())).reverse(),e.next=25,Promise.all(v);case 25:E=e.sent;case 26:return e.next=28,vt(t,a,i,r);case 28:return y=e.sent,e.abrupt("return",{owner:y,address:a,parentModule:o,id:a,name:"Delay Module",type:Fe.DELAY,subModules:E||[],expiration:g.toString(),cooldown:b.toString()});case 32:return e.prev=32,e.t0=e.catch(4),console.warn("Error fetching delay module",e.t0),e.abrupt("return",{address:a,parentModule:o,id:a,name:"Delay Module",type:Fe.UNKNOWN,subModules:[]});case 36:case"end":return e.stop()}}),e,null,[[4,32]])})))).apply(this,arguments)}function ht(e,t,a,n,r){return Et.apply(this,arguments)}function Et(){return(Et=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d,f=arguments;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(c=f.length>5&&void 0!==f[5]?f[5]:[],e.prev=1,n){e.next=4;break}return e.abrupt("return",[]);case 4:return(i=new A.b(a,n,t)).interface.getFunction("getModulesPaginated(address,uint256)"),e.next=8,i.getModulesPaginated(ft,50);case 8:return l=e.sent,s=Object(x.a)(l,1),u=s[0],d=[].concat(Object(w.a)(c),Object(w.a)(u)),e.next=14,Promise.all(u.filter((function(e){return!c.includes(e)})).map(function(){var e=Object(k.a)(C.a.mark((function e(n,c){var i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,pt(t,n,r,o,a,d);case 2:return i=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},i),{},{id:"".concat(a,"_").concat(n,"_").concat(c),parentModule:a}));case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()));case 14:return e.abrupt("return",e.sent);case 17:return e.prev=17,e.t0=e.catch(1),e.abrupt("return",[]);case 20:case"end":return e.stop()}}),e,null,[[1,17]])})))).apply(this,arguments)}function vt(e,t,a,n){return yt.apply(this,arguments)}function yt(){return(yt=Object(k.a)(C.a.mark((function e(t,a,n,r){var o;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(e.prev=0,n){e.next=3;break}return e.abrupt("return",void 0);case 3:return(o=new A.b(a,n,t)).interface.getFunction("owner()"),e.next=7,o.owner();case 7:return e.abrupt("return",e.sent);case 10:return e.prev=10,e.t0=e.catch(0),e.abrupt("return",void 0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}function Ot(e){return e.dataDecoded&&"multiSend"===e.dataDecoded.method?e.dataDecoded.parameters[0].valueDecoded:[e]}var xt=(st={},Object(P.a)(st,M.d.TELLOR,Fe.TELLOR),Object(P.a)(st,M.d.OPTIMISTIC_GOVERNOR,Fe.OPTIMISTIC_GOVERNOR),Object(P.a)(st,M.d.REALITY_ETH,Fe.REALITY_ETH),Object(P.a)(st,M.d.REALITY_ERC20,Fe.REALITY_ERC20),Object(P.a)(st,M.d.DELAY,Fe.DELAY),Object(P.a)(st,M.d.BRIDGE,Fe.BRIDGE),Object(P.a)(st,M.d.EXIT_ERC20,Fe.EXIT),Object(P.a)(st,M.d.ROLES_V1,Fe.ROLES_V1),Object(P.a)(st,M.d.ROLES_V2,Fe.ROLES_V2),Object(P.a)(st,M.d.OZ_GOVERNOR,Fe.OZ_GOVERNOR),st);function wt(e,t){var a=M.c[e];if(!a)return Fe.UNKNOWN;var n=Object.entries(a).find((function(e){var a=Object(x.a)(e,2)[1];return Object.values(a).some((function(e){return e.toLowerCase()===t.toLowerCase()}))}));return n&&xt[n[0]]||Fe.UNKNOWN}function jt(e,t){var a,n=(null===(a=M.b[t])||void 0===a?void 0:a.factory)||"";return wt(t,Ot(e).map((function(e){if(e.to.toLowerCase()===n.toLowerCase()){if(!e.dataDecoded)try{return(r=e.data,new I.ethers.utils.Interface(Ct).decodeFunctionData("deployModule",r))[0]}catch(o){return void console.warn("failed to decode proxy factory transaction: ",e.data)}if("deployModule"===e.dataDecoded.method){var t,a=null===(t=e.dataDecoded.parameters)||void 0===t?void 0:t.find((function(e){return"masterCopy"===e.name}));if(a)return a.value}}var r})).find((function(e){return e}))||"")}var Ct=["function deployModule(address masterCopy, bytes initializer, uint256 saltNonce) returns (address proxy)"];function kt(e){return e.dataDecoded&&"enableModule"===e.dataDecoded.method}function St(e){return e.dataDecoded&&"disableModule"===e.dataDecoded.method}function Nt(e,t){return t.flatMap(Ot).filter(St).map((function(t){var a=t.dataDecoded.parameters.find((function(e){return"module"===e.name})),n=a&&a.value?a.value:"",r=e.find((function(e){return e.address===n}));return{address:n,executor:t.to,operation:We.REMOVE,module:r?r.type:Fe.UNKNOWN}}))}function It(e,t){var a=function(e,t){return e.map((function(e){var a,n=Ot(e).reverse().find(kt);if(n){var r=jt(e,t),o=null===(a=n.dataDecoded.parameters)||void 0===a?void 0:a.find((function(e){return"module"===e.name})),c=null===o||void 0===o?void 0:o.value;if(r&&c)return{address:c,type:r}}})).reduce((function(e,t){return t?Object(N.a)(Object(N.a)({},e),{},Object(P.a)({},t.address,t.type)):e}),{})}(e,t);return e.flatMap(Ot).filter((function(e){return kt(e)})).map((function(e){var t=e.dataDecoded.parameters[0].value||"",n=a[t]||Fe.UNKNOWN;return{address:t,executor:e.to,module:n,operation:We.CREATE}}))}function Tt(e){return ze[e||Fe.UNKNOWN]}function At(e){return e.modules.current}function Rt(e){return e.modules.list}function Mt(e){return e.modules.reloadCount}function Bt(e){return e.modules.loadingModules}function Dt(e){return Rt(e).filter(mt)}function Lt(e){return e.modules.operation}function Pt(e){return e.modules.pendingModules}function Ft(e){return Pt(e).filter((function(e){return e.operation===We.CREATE}))}function Ut(e){return Pt(e).filter((function(e){return e.operation===We.REMOVE}))}function Vt(e){return e.modules.safeThreshold}function Ht(e){return e.modules.currentPendingModule}var _t,Gt,Wt={operation:"read",reloadCount:0,safeThreshold:1,loadingModules:!0,list:[],current:void 0,pendingModules:[],moduleAdded:!1,realityModuleScreen:!1,OzGovernorModuleScreen:!1},zt=Object(S.b)("modules/fetchModulesList",function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.provider,r=t.safeSDK,o=t.safeAddress,c=t.chainId,e.next=3,n.ready;case 3:return e.next=5,xe(n,o,c);case 5:return i=e.sent,(l=i.map(function(){var e=Object(k.a)(C.a.mark((function e(t){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,pt(n,t,r,c,o);case 3:return e.abrupt("return",e.sent);case 6:throw e.prev=6,e.t0=e.catch(0),new Error("Error sanitizing module ".concat(t,": ").concat(e.t0));case 9:case"end":return e.stop()}}),e,null,[[0,6]])})));return function(t){return e.apply(this,arguments)}}())).reverse(),e.prev=8,e.next=11,Promise.all(l);case 11:return s=e.sent,e.abrupt("return",s.filter((function(e){return void 0!==e})));case 15:throw e.prev=15,e.t0=e.catch(8),console.error("Cant fetch modules",e.t0),e.t0;case 19:case"end":return e.stop()}}),e,null,[[8,15]])})));return function(t,a){return e.apply(this,arguments)}}()),Kt=Object(S.b)("modules/fetchPendingModules",function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c,i,l,s,u,d,f,m;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.safeAddress,r=t.chainId,o=t.retry,c=void 0===o||o,e.next=3,Te(r,n);case 3:return i=e.sent,e.next=6,Ne(r,n,{nonce__gte:i.nonce.toString()});case 6:return l=e.sent,s=a.getState(),u=Rt(s),d=It(l,r),f=Nt(u,l),m=[].concat(Object(w.a)(d),Object(w.a)(f)),c&&setTimeout((function(){a.dispatch(Kt({safeAddress:n,chainId:r,retry:!1}))}),4e3),e.abrupt("return",{safeInfo:i,pendingModules:m});case 14:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()),Yt=Object(S.c)({name:"modules",initialState:Wt,reducers:{increaseReloadCount:function(e){e.reloadCount+=1},setCurrentModule:function(e,t){e.current=t.payload,e.operation="read",e.currentPendingModule=void 0},unsetCurrentModule:function(e){e.current=void 0,e.currentPendingModule=void 0},setOperation:function(e,t){e.operation=t.payload},setCurrentPendingModule:function(e,t){e.currentPendingModule=t.payload,e.current=void 0},setModuleAdded:function(e,t){e.moduleAdded=t.payload},setRealityModuleScreen:function(e,t){e.realityModuleScreen=t.payload},setOzGovernorModuleScreen:function(e,t){e.OzGovernorModuleScreen=t.payload}},extraReducers:function(e){e.addCase(zt.rejected,(function(e){e.loadingModules=!1})),e.addCase(zt.fulfilled,(function(e,t){e.loadingModules=!1,e.list=t.payload;var a=e.current;a&&(t.payload.some((function(e){return e.address===a.address}))||(e.current=void 0))})),e.addCase(Kt.fulfilled,(function(e,t){var a=t.payload,n=a.safeInfo,r=a.pendingModules;e.safeThreshold=n.threshold,e.pendingModules=r}))}}),Zt=Yt.actions,qt=(Zt.increaseReloadCount,Zt.setCurrentModule),Xt=Zt.unsetCurrentModule,Qt=Zt.setOperation,Jt=Zt.setCurrentPendingModule,$t=Zt.setModuleAdded,ea=Zt.setRealityModuleScreen,ta=Zt.setOzGovernorModuleScreen,aa=a(195),na=Object(S.c)({name:"transactionBuilder",initialState:{open:!1,addTransaction:{},transactions:[]},reducers:{openTransactionBuilder:function(e){e.open=!0},closeTransactionBuilder:function(e){e.open=!1},setTransactions:function(e,t){e.transactions=t.payload},addTransaction:function(e,t){e.transactions.push(t.payload)},resetTransactions:function(e){e.transactions=[]},setNewTransaction:function(e,t){e.addTransaction=t.payload},resetNewTransaction:function(e){e.addTransaction={}}}}),ra=na.actions,oa=ra.openTransactionBuilder,ca=ra.closeTransactionBuilder,ia=ra.setNewTransaction,la=ra.resetNewTransaction,sa=ra.resetTransactions,ua=ra.addTransaction,da=ra.setTransactions,fa=function(e){return function(t){return function(a){if(a.type===zt.fulfilled.type){var n=Ht(e.getState()),r=t(a);if(n){var o=function e(t){var a=t.flatMap((function(t){return e(t.subModules)}));return[].concat(Object(w.a)(t),Object(w.a)(a))}(Rt(e.getState())).find((function(e){return e.address===n.address}));o&&e.dispatch(qt(o))}return r}if(a.type===Kt.fulfilled.type){var c=e.getState(),i=t(a);if(c.modules.moduleAdded){var l=Ft(c),s=Ft(e.getState());(!l.length&&s.length||l.length&&s.length&&s[0].address!==l[0].address)&&(e.dispatch(Jt(s[0])),e.dispatch($t(!1)))}return i}return t(a)}}},ma=function(e){return function(t){return function(a){return a.type===qt.type&&e.dispatch(ca()),t(a)}}},pa=Object(S.a)({reducer:{modules:Yt.reducer,transactionBuilder:na.reducer},middleware:function(e){return e().concat(fa,ma)}}),ba=function(){return Object(aa.c)()},ga=aa.d,ha=["svgRef","title"];function Ea(){return(Ea=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ya=function(e){var t=e.svgRef,a=e.title,n=va(e,ha);return i.a.createElement("svg",Ea({width:40,height:40,viewBox:"0 0 40 40",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,_t||(_t=i.a.createElement("path",{d:"M39 20H34M20 39V34M1 20H6M20 1V6",stroke:"#B2B5B2",strokeWidth:2,strokeLinecap:"round"})),Gt||(Gt=i.a.createElement("path",{d:"M33.435 33.435L29.8995 29.8995M6.56497 33.435L10.1005 29.8995M6.56497 6.56497L10.1005 10.1005M33.435 6.56497L29.8995 10.1005",stroke:"#B2B5B2",strokeWidth:2,strokeLinecap:"round"})))},Oa=i.a.forwardRef((function(e,t){return i.a.createElement(ya,Ea({svgRef:t},e))})),xa=(a.p,a(1716)),wa=a(43),ja=a.n(wa),Ca=a(67),ka=["className"],Sa=Object(g.a)((function(){return{root:{display:"flex",flexDirection:"column"}}})),Na=function(e){var t=e.className,a=Object(Ca.a)(e,ka),n=Sa();return i.a.createElement("div",Object.assign({className:ja()(n.root,t)},a))},Ia=Object(g.a)((function(e){return{root:{padding:8,transition:"0.2s ease all",cursor:"pointer","&:hover":{background:"rgba(217, 212, 173, 0.15)"}},active:{borderColor:e.palette.common.white,background:"none",cursor:"initial","&::before":{borderColor:e.palette.common.white},"&:hover":{background:"none"}},spacing:{"& + &, &.sub":{marginTop:12}},moduleItem:{display:"grid",gridTemplateColumns:"48px 1fr",gridGap:e.spacing(2),backgroundColor:"transparent","&.sub":{zIndex:2}},content:{width:"100%",justifyContent:"center"},image:{paddingTop:2}}})),Ta=function(e){var t=e.active,a=e.sub,n=e.image,r=void 0===n?null:n,o=e.children,c=e.onClick,l=Ia();return i.a.createElement(h.c,{borderStyle:"double",className:ja()(l.root,l.spacing,Object(P.a)({sub:a},l.active,t))},i.a.createElement("div",{onClick:t?void 0:c,className:ja()(l.moduleItem,{active:t,sub:a})},i.a.createElement("div",{className:l.image},r),i.a.createElement(Na,{className:l.content},o)))},Aa=Object(g.a)((function(e){return{hashInfo:{display:"inline-flex !important",width:50,height:50,padding:e.spacing(.5),borderStyle:"solid",borderWidth:1,borderRadius:"50%",borderColor:"rgba(255, 255, 255, 0.2)",background:"rgba(224, 197, 173, 0.1)","& p":{fontSize:12,color:e.palette.text.primary+" !important"},"& .jLVlPg":{margin:0},"& .jLVlPg > p":{fontWeight:"bold",fontSize:14}}}})),Ra=function(e){var t=Aa();return i.a.createElement(m.EthHashInfo,Object.assign({className:t.hashInfo},e))},Ma=a(1715),Ba=a(41),Da=["className"],La=Object(g.a)((function(){return{root:{display:"flex",flexDirection:"row"}}})),Pa=function(e){var t=e.className,a=Object(Ca.a)(e,Da),n=La();return i.a.createElement("div",Object.assign({className:ja()(n.root,t)},a))},Fa=["secondary","children","className"],Ua=Object(g.a)((function(e){return{badge:{display:"inline-block",padding:e.spacing(.25,.5),lineHeight:1,whiteSpace:"nowrap",borderWidth:1,borderStyle:"solid",borderColor:"rgba(255, 255, 255, 0.2)"},primary:{backgroundColor:"rgba(224, 197, 173, 0.1)"},secondary:{backgroundColor:Object(Ba.a)(e.palette.primary.light,.4)}}})),Va=function(e){var t=e.secondary,a=e.children,n=e.className,r=Object(Ca.a)(e,Fa),o=Ua();return t?i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement("div",Object.assign({className:ja()(o.badge,o.primary,n)},r),a),i.a.createElement("div",Object.assign({className:ja()(o.badge,o.secondary,n)},r),t)):i.a.createElement("div",Object.assign({className:ja()(o.badge,o.primary,n)},r),a)},Ha=function(e){var t=e.address,a=e.className,n=function(e,t){var a=_(e);if(a){var n=t.length>42?"tx":"address";return function(){return{url:"".concat(a.url,"/").concat(n,"/").concat(t),alt:a.name}}}}(Object(p.useSafeAppsSDK)().safe.chainId,t);return n?i.a.createElement(m.ExplorerButton,{explorerUrl:n,className:a}):null};function _a(e){return e.substr(0,6)+"..."+e.substr(-4)}function Ga(e){if(e<60)return 1===e?"1 second":"".concat(e," second");if(e<3600){var t=Math.floor(e/60);return 1===t?"1 minute":"".concat(t," minute")}if(e<172800){var a=Math.floor(e/3600);return 1===a?"1 hour":"".concat(a," hour")}var n=Math.floor(e/86400);return"".concat(n," day")}var Wa,za=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.5),justifyContent:"start",alignItems:"center",minWidth:0,"& > *":{gridRow:1}},gutterBottom:{marginBottom:e.spacing(1)},showOnHover:{"& .btn":{visibility:"hidden"},"&:hover .btn":{visibility:"initial"}}}})),Ka=function(e){var t,a=e.address,n=e.short,r=void 0!==n&&n,o=e.hideCopyBtn,c=void 0!==o&&o,l=e.hideExplorerBtn,s=void 0!==l&&l,u=e.showOnHover,d=void 0!==u&&u,f=e.gutterBottom,p=void 0!==f&&f,b=e.classes,g=(b=void 0===b?{}:b).icon,h=b.container,E=e.TypographyProps,v=za();return i.a.createElement("div",{className:ja()(v.root,h,(t={},Object(P.a)(t,v.showOnHover,d),Object(P.a)(t,v.gutterBottom,p),t))},i.a.createElement(y.a,Object.assign({noWrap:!0},E),r?_a(a):a),c?null:i.a.createElement(m.CopyToClipboardBtn,{textToCopy:a,className:ja()(g,"btn")}),s?null:i.a.createElement(Ha,{address:a,className:ja()(g,"btn")}))},Ya=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer"}}})),Za=function(e){var t=e.module,a=Ya(),n=ba();return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(Va,null,Ga(t.cooldown)," delay"),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(e){e.stopPropagation(),n(qt(t)),n(Qt("write")),n(ia({func:"setTxCooldown(uint256)",params:[t.cooldown]}))}},"Change Delay")))},qa=a(23),Xa=Object(qa.a)((function(e){return{root:{color:e.palette.text.primary,textDecoration:"underline",transition:"opacity 0.25s ease-in-out","&:hover":{opacity:.6}}}}))(Ma.a),Qa=["image","linkText","title"],Ja=Object(g.a)((function(e){return{title:{marginBottom:e.spacing(.5),textTransform:"uppercase"},image:{width:50,height:50,display:"inline-flex !important",padding:e.spacing(.5),alignItems:"center",justifyContent:"center",borderStyle:"solid",borderWidth:1,borderRadius:"50%",borderColor:"rgba(255, 255, 255, 0.2)",background:"rgba(224, 197, 173, 0.1)"}}})),$a=function(e){var t=e.image,a=void 0===t?null:t,n=e.linkText,r=e.title,o=Object(Ca.a)(e,Qa),c=Ja(),l=Object(p.useSafeAppsSDK)().safe,s=_(l.chainId),u=s?"".concat(s.safeUrl).concat(l.safeAddress,"/transactions"):"";return i.a.createElement(Ta,Object.assign({image:i.a.createElement("div",{className:c.image},a)},o),i.a.createElement(y.a,{variant:"body2",className:c.title},r),i.a.createElement("div",null,i.a.createElement(Xa,{target:"_parent",href:u},n)))},en=["svgRef","title"];function tn(){return(tn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var nn,rn,on,cn=function(e){var t=e.svgRef,a=e.title,n=an(e,en);return i.a.createElement("svg",tn({width:34,height:34,viewBox:"0 0 34 34",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Wa||(Wa=i.a.createElement("path",{d:"M2 17C2 16.4477 1.55228 16 1 16C0.447715 16 0 16.4477 0 17H2ZM10.6248 1.2361C10.1129 1.44332 9.86584 2.02632 10.0731 2.53825C10.2803 3.05018 10.8633 3.2972 11.3752 3.08997L10.6248 1.2361ZM32 17C32 25.2843 25.2843 32 17 32V34C26.3888 34 34 26.3888 34 17H32ZM17 32C8.71573 32 2 25.2843 2 17H0C0 26.3888 7.61116 34 17 34V32ZM17 2C25.2843 2 32 8.71573 32 17H34C34 7.61116 26.3888 0 17 0V2ZM11.3752 3.08997C13.1109 2.38739 15.009 2 17 2V0C14.7474 0 12.5948 0.438641 10.6248 1.2361L11.3752 3.08997Z",fill:"#FFFFFF"})))},ln=i.a.forwardRef((function(e,t){return i.a.createElement(cn,tn({svgRef:t},e))})),sn=(a.p,Object(g.a)((function(e){return{root:{position:"relative",width:34,height:34},floating:{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center"},icon:{},rotate:{animationName:"$rotate",animationDuration:"2000ms",animationTimingFunction:"linear",animationIterationCount:"infinite"},"@keyframes rotate":{"0%":{transform:"rotate(0deg)"},"100%":{transform:"rotate(360deg)"}}}}))),un=function(e){var t=e.icon,a=sn();return i.a.createElement("div",{className:a.root},i.a.createElement("div",{className:a.floating},i.a.createElement(ln,{className:a.rotate})),i.a.createElement("div",{className:a.floating},t))},dn=["svgRef","title"];function fn(){return(fn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var pn,bn,gn,hn,En,vn,yn,On,xn,wn=function(e){var t=e.svgRef,a=e.title,n=mn(e,dn);return i.a.createElement("svg",fn({width:16,height:16,viewBox:"0 0 16 16",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,nn||(nn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M6.66667 12.0064C7.03533 12.0064 7.33333 11.7084 7.33333 11.3398V7.33976C7.33333 6.9711 7.03533 6.6731 6.66667 6.6731C6.298 6.6731 6 6.9711 6 7.33976V11.3398C6 11.7084 6.298 12.0064 6.66667 12.0064Z",fill:"#B2B5B2"})),rn||(rn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M9.33415 12.0064C9.70281 12.0064 10.0008 11.7084 10.0008 11.3398V7.33976C10.0008 6.9711 9.70281 6.6731 9.33415 6.6731C8.96548 6.6731 8.66748 6.9711 8.66748 7.33976V11.3398C8.66748 11.7084 8.96548 12.0064 9.33415 12.0064Z",fill:"#B2B5B2"})),on||(on=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.0085 13.034C10.9998 13.2033 10.8365 13.336 10.6771 13.3346H5.31245C5.15912 13.3173 5.00512 13.204 4.99645 13.0293L4.56445 5.33329H11.4225L11.0085 13.034ZM6.66439 3.07729C6.66439 2.85463 6.85306 2.66663 7.07572 2.66663H8.92105C9.14772 2.66663 9.33239 2.85129 9.33239 3.07729V3.99996H6.66439V3.07729ZM13.3328 3.99992H12.1742C12.1702 3.99992 12.1662 3.99659 12.1615 3.99659C12.1535 3.99592 12.1468 3.99992 12.1382 3.99992H10.6655V3.07725C10.6655 2.11592 9.88351 1.33325 8.92085 1.33325H7.07551C6.11351 1.33325 5.33085 2.11592 5.33085 3.07725V3.99992H2.66618C2.29818 3.99992 1.99951 4.29792 1.99951 4.66659C1.99951 5.03525 2.29818 5.33325 2.66618 5.33325H3.22951L3.66484 13.0979C3.70685 13.9713 4.43885 14.6686 5.29151 14.6686C5.30351 14.6686 5.31551 14.6679 5.32751 14.6679H10.6608H10.6988C11.5655 14.6679 12.2982 13.9719 12.3402 13.1026L12.7575 5.33325H13.3328C13.7015 5.33325 13.9995 5.03525 13.9995 4.66659C13.9995 4.29792 13.7015 3.99992 13.3328 3.99992Z",fill:"#B2B5B2"})))},jn=i.a.forwardRef((function(e,t){return i.a.createElement(wn,fn({svgRef:t},e))})),Cn=(a.p,["svgRef","title"]);function kn(){return(kn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Nn=function(e){var t=e.svgRef,a=e.title,n=Sn(e,Cn);return i.a.createElement("svg",kn({width:37,height:36,viewBox:"0 0 37 36",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,pn||(pn=i.a.createElement("circle",{cx:29,cy:4.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),bn||(bn=i.a.createElement("circle",{cx:4,cy:17.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),gn||(gn=i.a.createElement("circle",{cx:27,cy:31.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),hn||(hn=i.a.createElement("path",{d:"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833",stroke:"#FFFFFF",strokeWidth:2,strokeLinecap:"round"})),En||(En=i.a.createElement("path",{d:"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),vn||(vn=i.a.createElement("path",{d:"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),yn||(yn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M18.6667 22.0064C19.0353 22.0064 19.3333 21.7084 19.3333 21.3398V17.3398C19.3333 16.9711 19.0353 16.6731 18.6667 16.6731C18.298 16.6731 18 16.9711 18 17.3398V21.3398C18 21.7084 18.298 22.0064 18.6667 22.0064Z",fill:"#B2B5B2"})),On||(On=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M21.3341 22.0064C21.7028 22.0064 22.0008 21.7084 22.0008 21.3398V17.3398C22.0008 16.9711 21.7028 16.6731 21.3341 16.6731C20.9655 16.6731 20.6675 16.9711 20.6675 17.3398V21.3398C20.6675 21.7084 20.9655 22.0064 21.3341 22.0064Z",fill:"#B2B5B2"})),xn||(xn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M23.0085 23.0338C22.9998 23.2032 22.8365 23.3358 22.6771 23.3345H17.3125C17.1591 23.3172 17.0051 23.2038 16.9965 23.0292L16.5645 15.3332H23.4225L23.0085 23.0338ZM18.6644 13.0772C18.6644 12.8545 18.8531 12.6665 19.0757 12.6665H20.9211C21.1477 12.6665 21.3324 12.8512 21.3324 13.0772V13.9998H18.6644V13.0772ZM25.3328 13.9998H24.1742C24.1702 13.9998 24.1662 13.9965 24.1615 13.9965C24.1535 13.9958 24.1468 13.9998 24.1382 13.9998H22.6655V13.0771C22.6655 12.1158 21.8835 11.3331 20.9208 11.3331H19.0755C18.1135 11.3331 17.3308 12.1158 17.3308 13.0771V13.9998H14.6662C14.2982 13.9998 13.9995 14.2978 13.9995 14.6665C13.9995 15.0351 14.2982 15.3331 14.6662 15.3331H15.2295L15.6648 23.0978C15.7068 23.9711 16.4388 24.6685 17.2915 24.6685C17.3035 24.6685 17.3155 24.6678 17.3275 24.6678H22.6608H22.6988C23.5655 24.6678 24.2982 23.9718 24.3402 23.1025L24.7575 15.3331H25.3328C25.7015 15.3331 25.9995 15.0351 25.9995 14.6665C25.9995 14.2978 25.7015 13.9998 25.3328 13.9998Z",fill:"#B2B5B2"})))},In=i.a.forwardRef((function(e,t){return i.a.createElement(Nn,kn({svgRef:t},e))})),Tn=(a.p,["instant","module"]),An=function(e){var t=e.instant,a=e.module,n=Object(Ca.a)(e,Tn);return t?i.a.createElement($a,Object.assign({title:a.name||"",linkText:"Transaction confirming...",image:i.a.createElement(un,{icon:i.a.createElement(jn,null)})},n)):i.a.createElement($a,Object.assign({title:a.name||"",linkText:"Awaiting removal approval",image:i.a.createElement(In,null)},n))};function Rn(e,t){var a=Mn(e),n="/app/".concat(a,":").concat(e.safeAddress,"/apps"),r=new URLSearchParams({appUrl:t});return new URL("".concat("https://gnosis-safe.io").concat(n,"?").concat(r)).href}function Mn(e){return V[e.chainId].shortName}var Bn,Dn,Ln=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer",textUnderlineOffset:"2px","&:hover":{opacity:.5}}}})),Pn=function(e){var t=e.module,a=Ln(),n=Object(p.useSafeAppsSDK)().safe;return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Pa,{style:{justifyContent:"space-between"}},i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(){window.location.href=function(e,t){var a=Mn(e);return new URL("".concat("https://roles-v1.gnosisguild.org","/#/").concat(a,":").concat(t)).href}(n,t.address)},underline:"always"},"Edit Roles")))},Fn=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer",textUnderlineOffset:"2px","&:hover":{opacity:.5}}}})),Un=function(e){var t=e.module,a=Fn(),n=Object(p.useSafeAppsSDK)().safe;return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Pa,{style:{justifyContent:"space-between"}},i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(){window.location.href=function(e,t){var a=Mn(e);return new URL("".concat("https://roles.gnosisguild.org","/").concat(a,":").concat(t)).href}(n,t.address)},underline:"always"},"View Roles")))},Vn=["module","classes"],Hn=["module","remove","instant","onClick"],_n=Object(g.a)((function(e){return{text:{lineHeight:1,letterSpacing:"1px"},name:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},badge:{marginTop:e.spacing(1)},content:{display:"flex",flexDirection:"column",justifyContent:"center",height:56}}})),Gn=function(e){var t=e.module,a=e.classes,n=Object(Ca.a)(e,Vn),r=Object(p.useSafeAppsSDK)().safe;if(mt(t))return i.a.createElement(Za,Object.assign({module:t},n));if(t.type===Fe.ROLES_V1)return i.a.createElement(Pn,Object.assign({module:t,chainId:r.chainId},n));if(t.type===Fe.ROLES_V2)return i.a.createElement(Un,Object.assign({module:t,chainId:r.chainId},n));var o=t.owner&&t.owner!==r.safeAddress?i.a.createElement(Va,{secondary:_a(t.owner),className:a.badge},"External Owner"):null;return i.a.createElement(i.a.Fragment,null,t.name?i.a.createElement(y.a,{variant:"body2",className:a.name},t.name):null,i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),o)},Wn=function(e){var t=e.module,a=e.remove,n=void 0!==a&&a,r=e.instant,o=void 0!==r&&r,c=e.onClick,l=Object(Ca.a)(e,Hn),s=_n();return n?i.a.createElement(An,Object.assign({module:t,instant:o,onClick:c},l)):i.a.createElement(Ta,Object.assign({image:i.a.createElement(Ra,{showAvatar:!0,avatarSize:"lg",showHash:!1,hash:t.address})},l),i.a.createElement("div",{onClick:c,className:s.content},i.a.createElement(Gn,Object.assign({classes:s},e))),t.subModules.length?i.a.createElement(yr,{sub:!0,modules:t.subModules}):null)},zn=["svgRef","title"];function Kn(){return(Kn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Zn,qn,Xn,Qn,Jn,$n,er,tr,ar=function(e){var t=e.svgRef,a=e.title,n=Yn(e,zn);return i.a.createElement("svg",Kn({width:16,height:17,viewBox:"0 0 16 17",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Bn||(Bn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M14.6668 8.49992C14.6668 12.1818 11.6821 15.1666 8.00016 15.1666C4.31826 15.1666 1.3335 12.1818 1.3335 8.49992C1.3335 4.81802 4.31826 1.83325 8.00016 1.83325C11.6821 1.83325 14.6668 4.81802 14.6668 8.49992ZM2.66667 8.49988C2.66667 11.4454 5.05448 13.8332 8 13.8332C10.9455 13.8332 13.3333 11.4454 13.3333 8.49988C13.3333 5.55436 10.9455 3.16654 8 3.16654C5.05448 3.16654 2.66667 5.55436 2.66667 8.49988Z",fill:"#B2B5B2"})),Dn||(Dn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.6665 7.83341H10.6665C11.0347 7.83341 11.3332 8.13189 11.3332 8.50008C11.3332 8.86827 11.0347 9.16675 10.6665 9.16675H8.6665V11.1667C8.6665 11.5349 8.36803 11.8334 7.99984 11.8334C7.63165 11.8334 7.33317 11.5349 7.33317 11.1667V9.16675H5.33317C4.96498 9.16675 4.6665 8.86827 4.6665 8.50008C4.6665 8.13189 4.96498 7.83341 5.33317 7.83341H7.33317V5.83341C7.33317 5.46522 7.63165 5.16675 7.99984 5.16675C8.36803 5.16675 8.6665 5.46522 8.6665 5.83341V7.83341Z",fill:"#B2B5B2"})))},nr=i.a.forwardRef((function(e,t){return i.a.createElement(ar,Kn({svgRef:t},e))})),rr=(a.p,["svgRef","title"]);function or(){return(or=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ir,lr=function(e){var t=e.svgRef,a=e.title,n=cr(e,rr);return i.a.createElement("svg",or({width:37,height:36,viewBox:"0 0 37 36",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Zn||(Zn=i.a.createElement("circle",{cx:29,cy:4.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),qn||(qn=i.a.createElement("circle",{cx:4,cy:17.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),Xn||(Xn=i.a.createElement("circle",{cx:27,cy:31.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),Qn||(Qn=i.a.createElement("path",{d:"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833",stroke:"#FFFFFF",strokeWidth:2,strokeLinecap:"round"})),Jn||(Jn=i.a.createElement("path",{d:"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),$n||($n=i.a.createElement("path",{d:"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),er||(er=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M26.6668 17.5C26.6668 21.1819 23.6821 24.1667 20.0002 24.1667C16.3183 24.1667 13.3335 21.1819 13.3335 17.5C13.3335 13.8181 16.3183 10.8334 20.0002 10.8334C23.6821 10.8334 26.6668 13.8181 26.6668 17.5ZM14.6667 17.5C14.6667 20.4455 17.0545 22.8333 20 22.8333C22.9455 22.8333 25.3333 20.4455 25.3333 17.5C25.3333 14.5545 22.9455 12.1667 20 12.1667C17.0545 12.1667 14.6667 14.5545 14.6667 17.5Z",fill:"#B2B5B2"})),tr||(tr=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M20.6665 16.8333H22.6665C23.0347 16.8333 23.3332 17.1318 23.3332 17.5C23.3332 17.8681 23.0347 18.1666 22.6665 18.1666H20.6665V20.1666C20.6665 20.5348 20.368 20.8333 19.9998 20.8333C19.6316 20.8333 19.3332 20.5348 19.3332 20.1666V18.1666H17.3332C16.965 18.1666 16.6665 17.8681 16.6665 17.5C16.6665 17.1318 16.965 16.8333 17.3332 16.8333H19.3332V14.8333C19.3332 14.4651 19.6316 14.1666 19.9998 14.1666C20.368 14.1666 20.6665 14.4651 20.6665 14.8333V16.8333Z",fill:"#B2B5B2"})))},sr=i.a.forwardRef((function(e,t){return i.a.createElement(lr,or({svgRef:t},e))})),ur=(a.p,a(746)),dr=function(){var e=Object(p.useSafeAppsSDK)(),t=e.sdk,a=e.safe,n=Object(c.useMemo)((function(){return new I.ethers.providers.Web3Provider(new ur.SafeAppProvider(a,t))}),[t,a]);return{sdk:t,safe:a,provider:n}},fr=function(){var e=dr(),t=e.sdk,a=e.safe,n=e.provider,r=ba(),o=ga(Ht),l=ga(Pt),s=ga(Ft),u=1===ga(Vt);Object(c.useEffect)((function(){r(Kt(a))}),[r,a]),Object(c.useEffect)((function(){if(u&&l.length){var e=setInterval((function(){return r(Kt(a))}),3e3);return function(){clearInterval(e),r(zt({provider:n,safeSDK:t,chainId:a.chainId,safeAddress:a.safeAddress}))}}}),[r,u,t,a,l.length,n]);var d=u?i.a.createElement(un,{icon:i.a.createElement(nr,null)}):i.a.createElement(sr,{style:{marginLeft:-4}}),f=u?"Transaction confirming...":"Awaiting approval";return i.a.createElement(i.a.Fragment,null,s.map((function(e,t){var a={key:t,instant:u,onClick:function(){return r(Jt(e))},active:(null===o||void 0===o?void 0:o.address)===e.address},n=Ze(e.module),c=Tt(null===n||void 0===n?void 0:n.type);return i.a.createElement($a,Object.assign({title:c,linkText:f,image:d},a))})))},mr=["svgRef","title"];function pr(){return(pr=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var gr,hr=function(e){var t=e.svgRef,a=e.title,n=br(e,mr);return i.a.createElement("svg",pr({width:30,height:7,viewBox:"0 0 30 7",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,ir||(ir=i.a.createElement("path",{d:"M1.28906 1.69727C5.32916 3.95696 10.0897 5.26087 15.1864 5.26087C20.283 5.26087 25.0436 3.95696 29.0837 1.69727",strokeWidth:2})))},Er=i.a.forwardRef((function(e,t){return i.a.createElement(hr,pr({svgRef:t},e))})),vr=(a.p,Object(g.a)((function(e){return{subModules:{position:"relative"},line:{position:"absolute",borderColor:"#6d6b5a",borderStyle:"solid",borderBottomWidth:2,borderLeftWidth:2,borderTopWidth:0,borderRightWidth:0,borderBottomLeftRadius:16,top:6,left:-40,width:32},moduleStackIcon:{position:"absolute",top:0,left:-54,zIndex:100,stroke:"#6d6b5a"},emptyModulesText:{maxWidth:200},emptyImage:{border:"1px solid rgba(255,255,255,0.2)",borderRadius:"50%",padding:e.spacing(.5)}}}))),yr=function(e){var t=e.modules,a=e.sub,n=void 0!==a&&a,r=vr(),o=dr(),l=o.safe,s=o.sdk,u=o.provider,d=ba(),f=ga(At),m=ga(Bt),p=ga(Pt),b=ga(Vt),g=ga(Ut),h=i.a.useState(null),E=Object(x.a)(h,2),v=E[0],O=E[1];if(Object(c.useEffect)((function(){if(null==v){var e=function(){d(zt({provider:u,safeSDK:s,chainId:l.chainId,safeAddress:l.safeAddress}))},t=setInterval(e,1e4);O(t),e()}return function(){null!=v&&clearInterval(v)}}),[s,d,l,v,u]),m)return i.a.createElement(Ta,{image:i.a.createElement(xa.a,{variant:"circle",width:50,height:50})},i.a.createElement(xa.a,{width:160,height:20}),i.a.createElement(xa.a,{width:100,height:20}));if(!t.length&&!p.length)return i.a.createElement(Ta,{image:i.a.createElement(Oa,{className:r.emptyImage,height:50,width:50})},i.a.createElement(y.a,{className:r.emptyModulesText},"Modules will appear here once added"));var w=t.map((function(e){var t=e.id===(null===f||void 0===f?void 0:f.id),a=g.some((function(t){return function(e,t){return t.address===e.address&&t.executor===e.parentModule}(e,t)}));return i.a.createElement(Wn,{key:e.address,remove:a,instant:1===b,module:e,active:t,sub:n,onClick:function(){return function(e){d(qt(e)),d(la())}(e)}})}));if(n){var j=t.map((function(e,a){var n=a&&t[a-1],o=1+74*(n&&n.subModules.length)+74*(a+1)+12*a-37+6;return i.a.createElement("div",{key:a,className:r.line,style:{height:o}})})),C=t.length?i.a.createElement(Er,{className:r.moduleStackIcon}):null;return i.a.createElement("div",{className:r.subModules},w,C,j)}return i.a.createElement(Na,null,i.a.createElement(fr,null),w)},Or=function(){return i.a.createElement("div",{style:{flexGrow:1}})},xr=["svgRef","title"];function wr(){return(wr=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Cr=function(e){var t=e.svgRef,a=e.title,n=jr(e,xr);return i.a.createElement("svg",wr({width:13,height:12,viewBox:"0 0 13 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,gr||(gr=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M7.22344 4.8H10.8234C11.4862 4.8 12.0234 5.33726 12.0234 6C12.0234 6.66274 11.4862 7.2 10.8234 7.2H7.22344V10.8C7.22344 11.4627 6.68618 12 6.02344 12C5.3607 12 4.82344 11.4627 4.82344 10.8V7.2H1.22344C0.560696 7.2 0.0234375 6.66274 0.0234375 6C0.0234375 5.33726 0.560696 4.8 1.22344 4.8H4.82344V1.2C4.82344 0.537258 5.3607 0 6.02344 0C6.68618 0 7.22344 0.537258 7.22344 1.2V4.8Z",fill:"white"})))},kr=i.a.forwardRef((function(e,t){return i.a.createElement(Cr,wr({svgRef:t},e))})),Sr=(a.p,Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},hashInfo:{"& p":{color:e.palette.text.primary+" !important"}},header:{padding:e.spacing(0,1,2,1),boxSizing:"content-box",minHeight:40,alignItems:"center"},moduleList:{marginTop:e.spacing(3)}}}))),Nr=function(){var e=Sr(),t=ba(),a=ga(Rt),n=ga(At),r=ga(Ht);return i.a.createElement("div",{className:e.root},i.a.createElement(Pa,{className:e.header},i.a.createElement(y.a,{variant:"h5"},"Modules and Modifiers"),i.a.createElement(Or,null),n||r?i.a.createElement(O.a,{size:"small",disableRipple:!0,color:"secondary",variant:"contained",onClick:function(){t(Xt())},startIcon:i.a.createElement(kr,null)},"Add"):null),i.a.createElement(yr,{modules:a}))},Ir=["classes","className"],Tr=Object(g.a)((function(e){return{icon:{color:e.palette.secondary.main},queryButton:{textTransform:"none",fontSize:16,"&.MuiButton-contained.Mui-disabled":{backgroundColor:e.palette.secondary.main,color:e.palette.common.white},"&.MuiButton-outlinedSecondary.Mui-disabled":{color:e.palette.common.white,borderColor:e.palette.common.white}},buttonDisabled:{opacity:.5},outlined:{color:e.palette.common.white,padding:e.spacing(.75,2),borderColor:"rgba(217, 212, 173, 0.3)",transition:"0.2s ease all","&::before":{borderColor:"rgba(217, 212, 173, 0.3)"},"&:hover":{background:"rgba(217, 212, 173, 0.15)",borderColor:"rgba(217, 212, 173, 0.3)"}}}})),Ar=function(e){var t=e.classes,a=e.className,n=Object(Ca.a)(e,Ir),r=Tr();return i.a.createElement(O.a,Object.assign({color:"secondary",variant:"contained",classes:Object(N.a)({disabled:r.buttonDisabled,outlined:r.outlined},t),disableRipple:!0,className:ja()(r.queryButton,a)},n))};function Rr(e){return Object(N.a)(Object(N.a)({},e),{},{func:e.func.format("full")})}function Mr(e){var t=new R.b([e.func]);return Object(N.a)(Object(N.a)({},e),{},{func:Ve.f.from(t.fragments[0])})}function Br(e){return"remove_".concat(e.address,"_").concat(e.parentModule)}function Dr(e){return e.transactionBuilder.addTransaction}function Lr(e){return e.transactionBuilder.transactions.map(Mr)}function Pr(e){return e.transactionBuilder.open}var Fr,Ur=Object(g.a)((function(e){return{header:{minHeight:88,display:"flex",flexDirection:"row",alignItems:"center",padding:e.spacing(3)},text:{marginLeft:"16px !important",color:e.palette.text.primary+" !important"},addressType:{fontSize:".75rem",fontFamily:"Roboto Mono"},spacing:{marginLeft:e.spacing(2)},removeButton:{}}})),Vr=function(e){var t=e.module,a=Ur(),n=ba(),r=dr(),o=r.safe,c=r.provider,l=ga(Ut),s=ga(Lr).some((function(e){return e.id===Br(t)})),u=l.map((function(e){return e.address})).includes(t.address),d=s||u,f=function(){var e=Object(k.a)(C.a.mark((function e(){var a,r,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,Ce(c,t.parentModule,o.chainId,t.address);case 3:a=e.sent,r=a.params,i=new R.b(B.a),l=i.getFunction("disableModule"),s={module:t,params:r,id:Br(t),func:l,to:t.parentModule},n(ua(Rr(s))),n(oa()),e.next=15;break;case 12:e.prev=12,e.t0=e.catch(0),console.warn("could not remove module",e.t0);case 15:case"end":return e.stop()}}),e,null,[[0,12]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement("div",{className:a.header},i.a.createElement(Ra,{showAvatar:!0,showHash:!1,avatarSize:"lg",hash:t.address}),i.a.createElement(Ka,{short:!0,address:t.address,classes:{container:a.spacing,icon:a.spacing},TypographyProps:{classes:{root:a.addressType}}}),i.a.createElement(Or,null),i.a.createElement(Ar,{disableElevation:!0,className:a.removeButton,variant:"outlined",onClick:f,disabled:d,startIcon:i.a.createElement(jn,null)},"Remove"))},Hr=["open","content","children","className","containerClassName"],_r=Object(g.a)((function(e){return{root:{padding:e.spacing(2),transition:"0.2s ease all","& + &":{marginTop:e.spacing(2)},"&:hover":{background:"rgba(217, 212, 173, 0.15)"}},content:{marginTop:e.spacing(2)},hide:{display:"none"}}})),Gr=function(e){var t=e.open,a=void 0!==t&&t,n=e.content,r=e.children,o=e.className,c=e.containerClassName,l=Object(Ca.a)(e,Hr),s=_r();return i.a.createElement(h.c,Object.assign({},l,{borderStyle:"double",className:ja()(s.root,o)}),r,n?i.a.createElement("div",{className:ja()(s.content,c,Object(P.a)({},s.hide,!a))},n):null)},Wr=function(e){var t=e.defaultParams,a=e.func,n=e.children,r=Object(c.useRef)(a.inputs.map((function(e,a){return{value:t&&void 0!==t[a]?t[a]:"",valid:!0}}))),o=function(){return function(e,t){try{return He.b.encode(e.inputs,t),!0}catch(a){return!1}}(a,r.current.map((function(e){return e.value})))},i=Object(c.useState)(o()),l=Object(x.a)(i,2),s=l[0],u=l[1];return n({paramInputProps:a.inputs.map((function(e,t){return{param:e,value:r.current[t].value,onChange:function(e,a){!function(e,t,a){r.current[e]={value:t,valid:a};var n=r.current.every((function(e){return e.valid}));u(n&&o())}(t,e,a)}}})),getParams:function(){return r.current.map((function(e){return e.value}))},areParamsValid:s})},zr=Object(g.a)((function(e){return{root:{color:e.palette.common.white,fontFamily:"Roboto Mono",fontSize:12,padding:e.spacing(2)},item:{"& + &":{marginTop:e.spacing(1)}},label:{color:"rgba(217, 212, 173, 0.9)"},value:{overflowWrap:"break-word"}}})),Kr=function(e){var t,a=e.func,n=e.loading,r=void 0!==n&&n,o=e.result,c=zr();return r?i.a.createElement(xa.a,{variant:"rect",height:50}):o?i.a.createElement(h.c,{className:c.root},null===(t=a.outputs)||void 0===t?void 0:t.map((function(e,t){return i.a.createElement("div",{key:t,className:c.item},i.a.createElement("span",{className:c.label},e.name?"".concat(e.name," (").concat(e.type,")"):e.type,":"," "),i.a.createElement("span",{className:c.value},dt(e.baseType,o[t])))}))):null},Yr=a(756),Zr=Object(g.a)((function(e){return{spaceLeft:{marginLeft:e.spacing(1)},type:{fontFamily:"Roboto Mono",fontSize:".75rem"},queryType:{fontSize:".75rem"}}})),qr=function(e){var t=e.date,a=e.func,n=e.result,r=e.showResult,o=e.loading,c=void 0!==o&&o,l=Zr();if(c)return i.a.createElement(xa.a,{variant:"text",width:300});if(r&&n&&n.length&&a.outputs){var s=a.outputs[0],u=s.baseType,d=s.type,f=dt(u,n[0]);return"address"===u?i.a.createElement(Ka,{address:f,TypographyProps:{classes:{root:l.type}}}):i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"subtitle1",className:l.type},"(",d,")"),i.a.createElement(y.a,{noWrap:!0,className:ja()(l.spaceLeft,l.type)},f),i.a.createElement(m.CopyToClipboardBtn,{textToCopy:f,className:l.spaceLeft}))}return t?i.a.createElement(y.a,{className:l.queryType},"Queried ",i.a.createElement(Yr.a,{datetime:t})):i.a.createElement(y.a,{className:l.queryType},"Query")},Xr=Object(g.a)((function(e){return{root:{fontSize:12,padding:e.spacing(2),marginBottom:e.spacing(2),color:e.palette.error.main,borderRadius:e.shape.borderRadius,borderColor:e.palette.error.main,borderStyle:"solid",borderWidth:2,wordWrap:"break-word"}}})),Qr=function(e){var t=e.error,a=Xr();return t?i.a.createElement("div",{className:a.root},t):null},Jr=["svgRef","title"];function $r(){return($r=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var to=function(e){var t=e.svgRef,a=e.title,n=eo(e,Jr);return i.a.createElement("svg",$r({width:21,height:20,viewBox:"0 0 21 20",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Fr||(Fr=i.a.createElement("path",{d:"M15.2111 9.10557L8.44721 5.72361C7.78231 5.39116 7 5.87465 7 6.61803L7 13.382C7 14.1253 7.78231 14.6088 8.44722 14.2764L15.2111 10.8944C15.9482 10.5259 15.9482 9.4741 15.2111 9.10557Z",fill:"#FFFFFF"})))},ao=i.a.forwardRef((function(e,t){return i.a.createElement(to,$r({svgRef:t},e))})),no=(a.p,["param","value","onChange"]);function ro(e){return e.name?"".concat(e.name," (").concat(e.type,")"):"(".concat(e.type,")")}var oo,co=function(e){var t=e.param,a=e.value,n=e.onChange,r=Object(Ca.a)(e,no);if(null!=r.defaultValue)throw new Error("This is a controlled component, `defaultValue` should not be used. Use `value` instead.");var o=Object(c.useState)(function(e,t){return void 0!==t?"object"===typeof t?JSON.stringify(t):t.toString():"boolean"===e.baseType?"false":""}(t,a)),l=Object(x.a)(o,2),s=l[0],u=l[1],d=Object(c.useState)(),f=Object(x.a)(d,2),m=f[0],p=f[1],b=function(e){var a=e.target.value;if(u(a),"boolean"!==t.baseType){if(!a.length)return n(a,!1),void p(void 0);try{var r=it(t,a);n(r,!0),p(void 0)}catch(m){n(a,!1),p(null===m||void 0===m?void 0:m.message)}}else n("true"===a,!0)};return"boolean"===t.baseType?i.a.createElement(h.e,Object.assign({select:!0,color:"secondary",label:ro(t),value:s,onChange:b},r),i.a.createElement(Q.a,{value:"true"},"True"),i.a.createElement(Q.a,{value:"false"},"False")):i.a.createElement(h.e,Object.assign({color:"secondary",label:ro(t),value:s,onChange:b,error:!!m,helperText:m},r))},io=["svgRef","title"];function lo(){return(lo=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var uo=function(e){var t=e.svgRef,a=e.title,n=so(e,io);return i.a.createElement("svg",lo({width:18,height:10,viewBox:"0 0 18 10",ref:t},n),a?i.a.createElement("title",null,a):null,oo||(oo=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0651 9.58417C9.77258 9.86274 9.38708 10.0013 9.00008 9.99992C8.61458 10.0013 8.22908 9.86274 7.93658 9.58417C7.93058 9.57846 7.87208 9.51846 7.86608 9.51274L0.439578 2.43703C-0.143922 1.88132 -0.143922 0.972744 0.439578 0.41703C1.02308 -0.138684 1.97708 -0.138684 2.56058 0.41703L9.00008 6.55132L15.4411 0.41703C16.0246 -0.138684 16.9786 -0.138684 17.5621 0.41703C18.1456 0.972744 18.1456 1.88132 17.5621 2.43703L10.1461 9.49846C10.1401 9.50417 10.0711 9.57846 10.0651 9.58417Z"})))},fo=i.a.forwardRef((function(e,t){return i.a.createElement(uo,lo({svgRef:t},e))})),mo=(a.p,["up","className"]),po=Object(g.a)((function(e){return{arrowIcon:{cursor:"pointer",color:e.palette.primary.main,fill:"#B2B5B2",width:18,height:10,"&.rotate":{transform:"rotate(180deg)"}}}})),bo=function(e){var t=e.up,a=void 0!==t&&t,n=e.className,r=Object(Ca.a)(e,mo),o=po();return i.a.createElement(fo,Object.assign({className:ja()(o.arrowIcon,{rotate:a},n)},r))},go=Object(g.a)((function(e){return{clickable:{cursor:"pointer"},expandIcon:{marginLeft:e.spacing(2)},icon:{color:e.palette.common.white},queryButton:{marginTop:e.spacing(2)},title:{marginRight:e.spacing(1)}}})),ho=function(e){var t=e.address,a=e.func,n=go(),r=ga(Mt),o=dr(),l=o.safe,s=o.provider,u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)(),b=Object(x.a)(p,2),g=b[0],h=b[1],E=function(){var e=Object(c.useState)(!1),t=Object(x.a)(e,2),a=t[0],n=t[1],r=Object(c.useState)(),o=Object(x.a)(r,2),i=o[0],l=o[1],s=Object(c.useState)(),u=Object(x.a)(s,2),d=u[0],f=u[1];return{loading:a,error:d,result:i,fetch:Object(c.useCallback)((function(){n(!0),l(void 0),Se.apply(void 0,arguments).then((function(e){l(e),f(void 0)})).catch((function(e){f(e.message),l(void 0)})).finally((function(){return n(!1)}))}),[])}}(),v=E.loading,O=E.result,w=E.fetch,j=E.error,C=ot(a),k=ct(a),S=k&&a.outputs?a.outputs[0].baseType:"",N=void 0!==O&&k?dt(S,O[0]).length:0,I=Object(c.useCallback)((function(e){h(void 0),w(s,l.chainId,t,[a],a.name,e)}),[t,w,a,l.chainId,s]);Object(c.useEffect)((function(){!v&&O&&h(new Date)}),[v,O]),Object(c.useEffect)((function(){C&&I()}),[I,C,r]);var T=k&&N<60&&!j,A=!T||!C,R=i.a.createElement(i.a.Fragment,null,i.a.createElement(Qr,{error:j}),T?null:i.a.createElement(Kr,{loading:v,func:a,result:O}),i.a.createElement(Wr,{func:a},(function(e){var t=e.paramInputProps,a=e.areParamsValid,r=e.getParams;return i.a.createElement(i.a.Fragment,null,t.map((function(e,t){return i.a.createElement(J.a,{marginTop:2,key:t},i.a.createElement(co,e))})),t.length?i.a.createElement(Ar,{fullWidth:!0,disabled:!a,className:n.queryButton,onClick:function(){return I(r())},startIcon:i.a.createElement(ao,{className:n.icon})},"Run Query"):null)})));return i.a.createElement(Gr,{open:f&&A,content:R},i.a.createElement(Pa,{style:{alignItems:"center"},className:ja()(Object(P.a)({},n.clickable,A)),onClick:function(){return m(!f)}},i.a.createElement(y.a,{className:n.title},a.name),i.a.createElement(Or,null),i.a.createElement(qr,{func:a,result:O,loading:v,date:g,showResult:T}),A?i.a.createElement(bo,{up:f,className:n.expandIcon}):null))},Eo=Object(g.a)((function(e){return{root:{opacity:.5},expandIcon:{marginLeft:e.spacing(2)},icon:{color:e.palette.secondary.main},title:{marginRight:e.spacing(1)}}}));function vo(e){if(!ct(e)||!e.outputs)return"";var t=e.outputs[0].baseType;return t.includes("int")?"0":"bool"===t?"true":"0x0000000000000000000000000000000000000000"}var yo=function(e){var t=e.func,a=Eo(),n=ot(t),r=ct(t),o=n&&r;return i.a.createElement(Gr,{className:a.root},i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(y.a,{className:a.title},t.name),i.a.createElement(Or,null),i.a.createElement(qr,{func:t,showResult:o,result:o?[vo(t)]:void 0}),o?null:i.a.createElement(bo,{className:a.expandIcon})))},Oo=function(e){var t=e.abi,a=e.address,n=e.preview,r=Object(c.useMemo)((function(){return function(e){return(e instanceof R.b?e:new R.b(e)).fragments.filter(Ve.f.isFunctionFragment).map(Ve.f.from).filter(nt)}(t)}),[t]);return i.a.createElement(i.a.Fragment,null,r.map((function(e){return n?i.a.createElement(yo,{key:e.name,func:e}):i.a.createElement(ho,{key:e.name,address:a,func:e})})))},xo=a(505),wo=a(504),jo=a(384),Co=a(378),ko=a.n(Co),So=["InputProps","InputLabelProps","label","append","variantAppend","AppendProps","tooltipMsg"],No=Object(qa.a)((function(e){return{root:{"& label.Mui-focused":{position:"relative",transform:"none",color:e.palette.text.primary,marginBottom:e.spacing(1)},"& .MuiInputBase-root":{marginTop:0,minHeight:"37px"},"& .MuiSelect-select:focus":{backgroundColor:"transparent"}}}}))(xo.a),Io=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:"4px"},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},icon:{fontSize:"1rem"},append:{display:"flex",alignItems:"center",padding:e.spacing(1),borderWidth:1,borderStyle:"solid",borderLeftWidth:0},primary:{borderColor:e.palette.primary.light},secondary:{borderColor:h.f.tan[300]},error:{background:"rgba(244, 67, 54, 0.1)",border:"1px solid rgba(244, 67, 54, 0.3)"}}})),To=function(e){var t=e.InputProps,a=e.InputLabelProps,n=e.label,r=e.append,o=e.variantAppend,c=e.AppendProps,l=e.tooltipMsg,s=Object(Ca.a)(e,So),u=Io();return s.select||!r?i.a.createElement(No,Object.assign({focused:!s.disabled,label:n,placeholder:n,InputProps:Object(N.a)({disableUnderline:!0},t),InputLabelProps:Object(N.a)({shrink:!0},a)},s)):i.a.createElement("div",null,i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Z.a,Object.assign({},a,{className:u.label}),n)),l&&i.a.createElement(q.a,{item:!0},i.a.createElement(wo.a,{title:l},i.a.createElement(ko.a,{className:u.icon})))),i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,className:u.inputContainer},i.a.createElement(jo.a,Object.assign({disabled:s.disabled,placeholder:s.placeholder,onClick:s.onClick,inputMode:s.inputMode,value:s.value,onChange:s.onChange},t,{className:ja()(u.input,null===t||void 0===t?void 0:t.className)}))),i.a.createElement(q.a,Object.assign({item:!0,xs:8},c,{className:ja()("".concat(u.append," ").concat(function(){switch(o){case"primary":return u.primary;case"secondary":return u.secondary;case"error":return u.error}}()),null===c||void 0===c?void 0:c.className)}),r)))},Ao=function(e){var t=Object(c.useState)(!1),a=Object(x.a)(t,2),n=a[0],r=a[1];function o(t){t.key===e&&r(!0)}var i=function(t){t.key===e&&r(!1)};return Object(c.useEffect)((function(){return window.addEventListener("keydown",o),window.addEventListener("keyup",i),function(){window.removeEventListener("keydown",o),window.removeEventListener("keyup",i)}}),[]),n},Ro=a(129),Mo=a.n(Ro),Bo=a(379),Do=a.n(Bo),Lo={seconds:1,minutes:60,hours:3600,days:86400,months:2592e3},Po=Object(g.a)((function(e){return{select:{padding:0,border:0,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"120px"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1},primary:{borderColor:e.palette.primary.light},secondary:{borderColor:h.f.tan[300]},error:{background:"rgba(244, 67, 54, 0.1)",borderColor:"rgba(244, 67, 54, 0.3)"},errorIcon:{fill:"rgba(244, 67, 54, 1)"}}}));function Fo(e,t){return T.a.from(e).mul(Lo[t])}var Uo,Vo=function(e){var t=e.onChange,a=e.defaultUnit,n=void 0===a?"hours":a,r=e.defaultValue,o=void 0===r?"0":r,l=e.value,s=e.valueUnit,u=e.label,d=e.variant,f=void 0===d?"primary":d,m=e.tooltipMsg,p=e.alertType,b=Po(),g=Ao("Tab"),h=Object(c.useState)(n),E=Object(x.a)(h,2),v=E[0],y=E[1],O=Object(c.useState)(T.a.from(o).div(Lo[v]).toString()),w=Object(x.a)(O,2),j=w[0],C=w[1],k=Object(c.useState)(!1),S=Object(x.a)(k,2),N=S[0],I=S[1],A=function(){return I(!1)},R=function(){return I(!0)},M=i.a.useRef(null),B=function(e){try{var a=Fo(e||"0",v);C(e),t(a.toString(),v)}catch(n){console.warn("invalid time")}},D=function(e){A(),y(e),j&&t(Fo(j,e).toString(),e)};return Object(c.useEffect)((function(){g&&N&&A()}),[g,N]),Object(c.useEffect)((function(){M.current&&M.current.addEventListener("keyup",(function(e){"Tab"===e.code&&R()}))}),[M]),Object(c.useEffect)((function(){if(l&&s){var e=T.a.from(l).div(Lo[s]).toString();e!==j&&C(e),["hours","days"].includes(v)&&s!==v&&y(s)}}),[l,s,j,v]),i.a.createElement(To,{label:u,variantAppend:f,tooltipMsg:m,InputProps:{value:j,placeholder:"24",classes:{root:function(){switch(f){case"primary":return b.primary;case"secondary":return b.secondary;case"error":return b.error}}()},onChange:function(e){return B(e.target.value)},startAdornment:function(){if(p)switch(p){case"error":return i.a.createElement(Mo.a,{className:b.errorIcon});case"warning":return i.a.createElement(Do.a,{className:b.errorIcon})}return null}()},AppendProps:{className:b.dropdownContainer},append:i.a.createElement(X.a,{disableUnderline:!0,open:N,value:v,ref:M,onOpen:R,onClose:A,className:"".concat(b.select," ").concat("primary"===f?b.primary:b.secondary),MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:b.dropdown,list:b.itemList}},renderValue:function(e){return e},onChange:function(e){return D(e.target.value)}},Object.keys(Lo).map((function(e){return i.a.createElement(Q.a,{key:e,value:e,className:b.item},e,i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"}))})))})},Ho=["label","value","onChange"],_o=function(e){var t=e.param,a=e.func;if(1===a.inputs.length){var n=Object(x.a)(a.inputs,1)[0];if(["setTxCooldown","setTxExpiration"].includes(a.name)&&n.type.includes("int"))return i.a.createElement(Go,t)}return i.a.createElement(co,t)},Go=function(e){var t=e.label,a=e.value,n=e.onChange,r=Object(Ca.a)(e,Ho),o=a||"0";return i.a.createElement(Vo,Object.assign({},r,{label:t||"Time",defaultValue:o,defaultUnit:"seconds",onChange:function(e){return n(e,!0)}}))},Wo=Object(g.a)((function(e){return{greyText:{"& select":{color:e.palette.primary.main}},icon:{color:e.palette.common.white},addButton:{marginTop:e.spacing(2)},header:{padding:e.spacing(1),marginBottom:e.spacing(1.5)},text:{maxWidth:366},content:{padding:e.spacing(1.5)},field:{marginTop:e.spacing(2.5)}}})),zo=function(e){var t=e.func,a=e.onAdd,n=e.defaultParams,r=Wo(),o=ga(At);if(!t)return i.a.createElement(Ar,{fullWidth:!0,disabled:!0,className:r.addButton,startIcon:i.a.createElement(kr,{className:r.icon})},"Add this transaction");return i.a.createElement(Wr,{func:t,defaultParams:n},(function(e){var n=e.paramInputProps,c=e.areParamsValid,l=e.getParams;return i.a.createElement(i.a.Fragment,null,n.map((function(e,a){return i.a.createElement("div",{className:r.field,key:a},i.a.createElement(_o,{func:t,param:e}))})),i.a.createElement(Ar,{fullWidth:!0,onClick:function(){return e=l(),void(o&&a({func:t,params:e,module:o,to:o.address,id:"".concat(t.name,"_").concat((new Date).getTime())}));var e},disabled:!c,className:r.addButton,startIcon:i.a.createElement(kr,{className:r.icon})},"Add this transaction"))}))},Ko=function(e,t){if(t){var a=e.findIndex((function(e){return e.format()===t}));if(a>=0)return a}return-1},Yo=function(e){var t=e.abi,a=e.onAdd,n=Wo(),r=ba(),o=Object(c.useMemo)((function(){return function(e){return(e instanceof R.b?e:new R.b(e)).fragments.filter(Ve.f.isFunctionFragment).map(Ve.f.from).filter(at)}(t)}),[t]),l=ga(Dr),s=l.func,u=l.params,d=Object(c.useState)((function(){return Ko(o,s)})),f=Object(x.a)(d,2),m=f[0],p=f[1];Object(c.useEffect)((function(){s&&p(Ko(o,s))}),[s,o]);return i.a.createElement(i.a.Fragment,null,i.a.createElement(h.c,{className:n.header,elevation:0},i.a.createElement(y.a,{variant:"h5",gutterBottom:!0},"Add Transaction"),i.a.createElement(y.a,{variant:"body2",className:n.text},"Add multiple transactions here, and we will bundle them together into a single transaction, to save you gas.")),i.a.createElement(h.c,{className:n.content,elevation:0},i.a.createElement(h.e,{select:!0,value:m,onChange:function(e){p(parseInt(e.target.value)),r(la())},className:ja()(Object(P.a)({},n.greyText,void 0===m)),color:"secondary",label:"Function"},i.a.createElement(Q.a,{value:-1},"Select function"),o.map((function(e,t){return i.a.createElement(Q.a,{key:e.format("full"),value:t},e.name)}))),i.a.createElement(zo,{key:"".concat(m,"_").concat(s),defaultParams:u,func:void 0!==m?o[m]:void 0,onAdd:function(e){p(-1),a(e)}})))},Zo=a(1717),qo=a(1725),Xo=["disabled"],Qo=Object(qa.a)((function(e){return{root:{width:"50%",padding:e.spacing(1,2.5),"& span":{fontSize:16,textTransform:"none",color:e.palette.text.primary+" !important"}},selected:{backgroundColor:e.palette.secondary.main+" !important"}}}))(Zo.a),Jo=function(e){var t=e.disabled,a=void 0!==t&&t,n=Object(Ca.a)(e,Xo);return i.a.createElement(qo.a,Object.assign({exclusive:!0,size:"small"},n),i.a.createElement(Qo,{disabled:a,value:"read",disableRipple:!0},"Read Contract"),i.a.createElement(Qo,{disabled:a,value:"write",disableRipple:!0},"Write Contract"))},$o=Object(g.a)((function(e){return{content:{padding:e.spacing(2),marginTop:e.spacing(3),background:h.f.tan[100]},hide:{display:"none"}}})),ec=function(e){var t=e.address,a=e.abi,n=$o(),r=ba(),o=ga(Lt);return i.a.createElement(i.a.Fragment,null,i.a.createElement(Jo,{value:o,onChange:function(e,t){return function(e){e&&r(Qt(e))}(t)}}),i.a.createElement(h.c,{className:n.content},i.a.createElement("div",{className:ja()(Object(P.a)({},n.hide,"read"!==o))},i.a.createElement(Oo,{address:t,abi:a})),i.a.createElement("div",{className:ja()(Object(P.a)({},n.hide,"write"!==o))},i.a.createElement(Yo,{abi:a,onAdd:function(e){r(ua(Rr(e)))}}))))},tc=Object(g.a)((function(e){return{root:{padding:e.spacing(2.5)},title:{marginBottom:e.spacing(2)},link:{fontSize:16}}})),ac=function(){var e=tc(),t=Object(p.useSafeAppsSDK)().safe,a=(_(t.chainId)||{}).verifyUrl;return i.a.createElement(h.c,{borderStyle:"double",className:e.root},i.a.createElement(y.a,{variant:"h5",className:e.title},"No Read or Write functions available"),i.a.createElement(y.a,null,"We couldn't find an ABI and didn't recognize it as one of the known Zodiac contracts."),i.a.createElement(Xa,{target:"_blank",href:a,className:e.link},"Verify this contract on Etherscan to fix this."))},nc=function(e){var t=e.module,a=dr(),n=a.safe,r=a.sdk,o=a.provider,l=Object(c.useState)(!0),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(),m=Object(x.a)(f,2),p=m[0],b=m[1];return Object(c.useEffect)((function(){d(!0),b(void 0),ut(o,r,n.chainId,t.address).then((function(e){var t=e.abi;return b(t)})).catch((function(e){return console.warn("getModuleABI",e)})).finally((function(){return d(!1)}))}),[t,n,r,o]),u?i.a.createElement(xa.a,{variant:"rect",width:300,height:48}):p?i.a.createElement(ec,{address:t.address,abi:p}):i.a.createElement(ac,null)},rc=Object(g.a)((function(e){return{content:{padding:e.spacing(0,2,2,2)}}})),oc=function(e){var t=e.module,a=rc();return i.a.createElement(i.a.Fragment,null,i.a.createElement(Vr,{module:t}),i.a.createElement("div",{className:a.content},i.a.createElement(nc,{key:t.address,module:t})))},cc=["children","className"],ic=Object(g.a)((function(e){return{tag:{display:"inline-block",borderRadius:8,lineHeight:1,padding:e.spacing(.75,.5),margin:e.spacing(0,1,1,0),backgroundColor:"rgba(0,20,40,0.5)",color:e.palette.common.white}}})),lc=function(e){var t=e.children,a=e.className,n=Object(Ca.a)(e,cc),r=ic();return i.a.createElement("div",Object.assign({className:ja()(r.tag,a)},n),t)},sc=Object(g.a)((function(e){return{root:{display:"flex",flexDirection:"column",alignItems:"center",userSelect:"none",padding:e.spacing(2),cursor:"pointer",transition:"0.2s ease all","&:hover":{background:"rgba(217, 212, 173, 0.15)"}},badgeIcon:{background:h.f.sepia[100],marginBottom:e.spacing(1)},title:{marginBottom:e.spacing(.5)}}})),uc=function(e){var t=e.title,a=e.description,n=e.icon,r=e.available,o=e.deprecated,c=e.className,l=e.onClick,s=sc();return r?i.a.createElement(h.c,{borderStyle:"double",className:ja()(s.root,c),onClick:l},i.a.createElement(h.a,{icon:n,size:60,className:s.badgeIcon}),i.a.createElement(y.a,{variant:"h6",className:s.title},t),o&&i.a.createElement(lc,null,"Deprecated"),i.a.createElement(y.a,{variant:"body2",align:"center"},a)):null},dc=a(708),fc=a(1718),mc=function(e){var t=e.tags,a=e.className,n=e.style;return i.a.createElement("div",null,t.map((function(e){return i.a.createElement(lc,{key:e,className:a,style:n},e)})))},pc=["svgRef","title"];function bc(){return(bc=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var hc,Ec,vc,yc=function(e){var t=e.svgRef,a=e.title,n=gc(e,pc);return i.a.createElement("svg",bc({width:11,height:13,viewBox:"0 0 11 13",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Uo||(Uo=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.79066 6.19787L6.50066 3.90787V11.4949C6.50066 12.0449 6.05066 12.4949 5.50066 12.4949C4.94966 12.4949 4.50066 12.0449 4.50066 11.4949V3.90787L2.20966 6.19787C1.82066 6.58687 1.18466 6.58687 0.795656 6.19787C0.406656 5.80887 0.406656 5.17287 0.795656 4.78387L4.79366 0.786873C4.85166 0.726872 4.92566 0.694874 4.99366 0.653873C5.03566 0.628874 5.06966 0.592874 5.11566 0.572873C5.15666 0.554873 5.20266 0.554873 5.24566 0.544873C5.45766 0.487873 5.68166 0.488873 5.88566 0.572873C5.92966 0.591873 5.96266 0.626873 6.00366 0.651873C6.07366 0.692873 6.14666 0.725873 6.20766 0.786873L10.2047 4.78387C10.5937 5.17287 10.5937 5.80887 10.2047 6.19787C9.81566 6.58787 9.17966 6.58787 8.79066 6.19787Z",fill:"white"})))},Oc=i.a.forwardRef((function(e,t){return i.a.createElement(yc,bc({svgRef:t},e))})),xc=(a.p,Object(g.a)((function(e){return{root:{width:"100%",outline:"none",maxWidth:380,margin:e.spacing(14,1,1,1),padding:e.spacing(2),backgroundColor:"rgba(78, 72, 87, 0.8)"},modal:{position:"absolute !important",paddingBottom:e.spacing(2),overflow:"auto",alignItems:"flex-start"},backdrop:{backdropFilter:"blur(4px)"},description:{marginTop:e.spacing(1)},gutterBottom:{marginBottom:e.spacing(3)},row:{display:"flex",flexDirection:"row"},center:{justifyContent:"center"},imageContainer:{marginRight:e.spacing(2),minWidth:68},infoContainer:{flexGrow:1},readMore:{display:"block",marginTop:e.spacing(1.5),fontSize:16},loader:{display:"block",margin:"0 auto"},warningIcon:{marginRight:e.spacing(1),"& .icon-color":{fill:"#E0B325 !important"}},warningText:{color:"#E0B325"}}}))),wc=function(e){var t=e.open,a=e.title,n=e.description,r=e.onAdd,o=e.tags,c=void 0===o?[]:o,l=e.icon,s=e.readMoreLink,u=e.onClose,d=e.children,f=e.ButtonProps,p=e.warning,b=e.hideButton,g=void 0!==b&&b,E=xc();return i.a.createElement(dc.a,{keepMounted:!0,open:t,onClose:u,className:ja()(E.modal,E.row,E.center),BackdropProps:{className:E.backdrop}},i.a.createElement(fc.a,{in:t},i.a.createElement(h.c,{borderStyle:"double",className:E.root,elevation:3},i.a.createElement("div",{className:ja()(E.row,E.gutterBottom)},i.a.createElement(h.a,{icon:l,size:68,className:E.imageContainer}),i.a.createElement("div",{className:E.infoContainer},i.a.createElement(y.a,{variant:"h5",gutterBottom:!0},a),i.a.createElement(mc,{tags:c}),n?i.a.createElement(y.a,{gutterBottom:!0,className:E.description},n):null,p?i.a.createElement(Pa,null,i.a.createElement(m.Icon,{type:"error",size:"md",className:E.warningIcon}),i.a.createElement(y.a,{variant:"body1",className:E.warningText},p)):null,s?i.a.createElement(Xa,{href:s,target:"_blank",className:E.readMore},"Read more here"):null)),d?i.a.createElement("div",{className:ja()(Object(P.a)({},E.gutterBottom,!g))},d):null,g?null:i.a.createElement(Ar,Object.assign({fullWidth:!0,startIcon:i.a.createElement(Oc,null),onClick:r},f),"Add Module"))))},jc=a(705),Cc=Object(g.a)((function(e){return{root:{color:e.palette.text.secondary,"&:hover":{background:"none"}}}})),kc=function(e){var t=Object.assign({},e),a=Cc();return i.a.createElement(jc.a,Object.assign({disableFocusRipple:!0,disableRipple:!0,disableTouchRipple:!0,color:"default"},t,{classes:{root:a.root}}))},Sc=a(704),Nc=["svgRef","title"];function Ic(){return(Ic=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Ac,Rc,Mc=function(e){var t=e.svgRef,a=e.title,n=Tc(e,Nc);return i.a.createElement("svg",Ic({width:32,height:32,viewBox:"0 0 32 32",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,hc||(hc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,fill:"#E0C5AD",fillOpacity:.1})),Ec||(Ec=i.a.createElement("path",{d:"M10 17L14 21L23 11",stroke:"white",strokeWidth:2,strokeLinejoin:"round"})),vc||(vc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,stroke:"white"})))},Bc=i.a.forwardRef((function(e,t){return i.a.createElement(Mc,Ic({svgRef:t},e))})),Dc=(a.p,["svgRef","title"]);function Lc(){return(Lc=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Fc=function(e){var t=e.svgRef,a=e.title,n=Pc(e,Dc);return i.a.createElement("svg",Lc({width:32,height:32,viewBox:"0 0 32 32",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Ac||(Ac=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,fill:"#E0C5AD",fillOpacity:.1})),Rc||(Rc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,stroke:"white"})))},Uc=i.a.forwardRef((function(e,t){return i.a.createElement(Fc,Lc({svgRef:t},e))})),Vc=(a.p,Object(g.a)((function(){return{root:{padding:0,backgroundColor:"transparent !important",borderRadius:0}}}))),Hc=function(e){var t=Object.assign({},e),a=Vc();return i.a.createElement(Sc.a,Object.assign({disableFocusRipple:!0,disableRipple:!0,disableTouchRipple:!0,icon:i.a.createElement(Uc,null),checkedIcon:i.a.createElement(Bc,null),classes:{root:a.root}},t))},_c=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."),Gc=Object(g.a)((function(e){return{container:{marginLeft:e.spacing(1.5)},item:{marginTop:e.spacing(2)},text:{fontSize:12},delayText:{marginBottom:e.spacing(.5)}}})),Wc=function(e){var t=e.modules,a=e.value,n=e.description,r=void 0===n?_c:n,o=e.type,l=e.onChange,s=Gc(),u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1];return i.a.createElement(Pa,{style:{alignItems:"flex-start"}},i.a.createElement(Hc,{checked:f,onChange:function(){f&&l(void 0),m(!f)}}),i.a.createElement("div",{className:s.container},i.a.createElement(y.a,{gutterBottom:!0},"Attach to ",o.replace(/^\w/,(function(e){return e.toUpperCase()}))," Module"),r,f?t.map((function(e){return i.a.createElement(Pa,{key:e.address,className:s.item},i.a.createElement(kc,{checked:a===e.address,onClick:function(){return l(e.address)}}),i.a.createElement(Na,{style:{justifyContent:"center"}},mt(e)?i.a.createElement(Va,{className:ja()(s.text,s.delayText)},Ga(e.expiration)," delay"):null,i.a.createElement(Ka,{short:!0,hideCopyBtn:!0,hideExplorerBtn:!0,address:e.address,TypographyProps:{className:s.text}})))})):null))},zc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),Kc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=zc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(1===d.length?d[0].address:""),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)({owner:s.safeAddress,oracle:se(s.chainId),cooldown:"86400",expiration:"604800"}),h=Object(x.a)(g,2),E=h[0],v=h[1],O=Object(c.useState)({oracle:!!E.oracle}),w=Object(x.a)(O,2),j=w[0],S=w[1],I=Object.values(j).every((function(e){return e})),T=function(e,t,a){v(Object(N.a)(Object(N.a)({},E),{},Object(P.a)({},e,t))),void 0!==a&&S(Object(N.a)(Object(N.a)({},j),{},Object(P.a)({},e,a)))},A=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Object(N.a)(Object(N.a)({},E),{},{executor:p||s.safeAddress}),r=ge(u,s.safeAddress,s.chainId,t),e.next=5,l.txs.send({txs:r});case 5:n&&n(),a&&a(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}(),R=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return i.a.createElement(wc,{open:t,onClose:a,title:"Tellor Module",description:"Allows successful Snapshot proposals to execute transactions using the Tellor oracle.",icon:"tellor",tags:["From Tellor"],onAdd:A,readMoreLink:"https://github.com/tellor-io/snapshot-zodiac-module",ButtonProps:{disabled:!I}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",label:"Owner Address",onChange:function(e,t){return T("owner",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:E.oracle,label:"Oracle Address",onChange:function(e,t){return T("oracle",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:E.cooldown,defaultUnit:"hours",onChange:function(e){return T("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:E.expiration,defaultUnit:"days",onChange:function(e){return T("expiration",e)}}))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:R,modules:d,value:p,onChange:function(e){return b(e)},type:Fe.DELAY})):null)},Yc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},errorMessage:{color:"red"}}})),Zc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=Yc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(1===d.length?d[0].address:""),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(!0),h=Object(x.a)(g,2),E=h[0],v=h[1],O=Object(c.useState)({finder:de(s.chainId),owner:s.safeAddress,collateral:fe(s.chainId,E),bond:"2",rules:"",identifier:"0x4153534552545f54525554480000000000000000000000000000000000000000",liveness:"86400",snapshotURL:"https://snapshot.org/#/",votingQuorum:"5",votingPeriod:"24"}),w=Object(x.a)(O,2),j=w[0],S=w[1],I=Object(c.useState)({finder:!!j.finder,bond:!!j.bond,snapshotURL:!!j.snapshotURL,votingPeriod:!!j.votingPeriod,votingQuorum:!!j.votingQuorum}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object.values(A).every((function(e){return e})),B=function(e,t,a){S(Object(N.a)(Object(N.a)({},j),{},Object(P.a)({},e,t))),void 0!==a&&R(Object(N.a)(Object(N.a)({},A),{},Object(P.a)({},e,a)))},D=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Object(N.a)(Object(N.a)({},j),{},{owner:s.safeAddress,executor:p||s.safeAddress}),r=Be(u,s.safeAddress,s.chainId,t,E),e.next=5,l.txs.send({txs:r});case 5:n&&n(),a&&a(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}(),L=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return j.rules="I assert that this transaction proposal is valid according to the following rules: Proposals approved on Snapshot, as verified at ".concat(j.snapshotURL,", are valid as long as there is a minimum quorum of ").concat(j.votingQuorum," and a minimum voting period of ").concat(j.votingPeriod," hours and it does not appear that the Snapshot voting system is being exploited or is otherwise unavailable. The quorum and voting period are minimum requirements for a proposal to be valid. Quorum and voting period values set for a specific proposal in Snapshot should be used if they are more strict than the rules parameter. The explanation included with the on-chain proposal must be the unique IPFS identifier for the specific Snapshot proposal that was approved or a unique identifier for a proposal in an alternative voting system approved by DAO social consensus if Snapshot is being exploited or is otherwise unavailable."),i.a.createElement(wc,{open:t,onClose:a,title:"UMA oSnap Module",description:"Allows successful Snapshot proposals to execute transactions using UMA's optimistic oracle.",icon:"optimisticGov",tags:["From UMA"],onAdd:D,readMoreLink:"https://docs.uma.xyz/developers/osnap",ButtonProps:{disabled:!M}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(le,{label:"Collateral",defaultAddress:j.collateral,defaultOption:re.WETH,onChange:function(e){B("collateral",e),v(!E)},chainId:s.chainId})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("string"),color:"secondary",value:j.bond,label:"Bond",onChange:function(e,t){return B("bond",e,t)}}),i.a.createElement(y.a,{className:r.errorMessage},Number(j.bond)<1500&&!E?"Warning: A minimum bond of 1,500 is recommended for USDC":Number(j.bond)<2&&E?"Warning: A bond of 2 is recommended for WETH":null)),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Liveness",defaultValue:j.liveness,defaultUnit:"hours",onChange:function(e){return B("liveness",e)}}),i.a.createElement(y.a,{className:r.errorMessage},Number(j.liveness)<86400?"Warning: The minimum recommended liveness period is 24 hours.":null)),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("string"),color:"secondary",value:j.snapshotURL,label:"Snapshot Space URL",onChange:function(e,t){return B("snapshotURL",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("uint256"),color:"secondary",value:j.votingQuorum,label:"Voting Quorum",onChange:function(e,t){return B("votingQuorum",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("uint256"),color:"secondary",value:j.votingPeriod,label:"Voting Period (hours)",onChange:function(e,t){return B("votingPeriod",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(y.a,null,"Rules Parameter:"),i.a.createElement(y.a,null,j.rules))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:L,modules:d,value:p,onChange:function(e){return b(e)},type:Fe.DELAY})):null)},qc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),Xc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=qc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({expiration:"86400",cooldown:"86400"}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=function(e,t){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,t)))},g=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=he(u,s.safeAddress,s.chainId,{executor:s.safeAddress,cooldown:m.cooldown,expiration:m.expiration}),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Delay Modifier",description:"Adds a settable delay time to any transaction originating from this module.",icon:"delay",tags:["Stackable","From Gnosis Guild"],onAdd:g,readMoreLink:"https://zodiac.wiki/index.php/Category:Delay_Modifier"},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:m.cooldown,defaultUnit:"hours",onChange:function(e){return b("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:m.expiration,defaultUnit:"hours",onChange:function(e){return b("expiration",e)}}))))},Qc=Object(g.a)((function(e){return{addButton:{marginTop:e.spacing(2)},addTransactionButton:{marginTop:e.spacing(1)},addIcon:{stroke:e.palette.common.white,width:20,height:20}}})),Jc=function(e){var t=e.onSubmit,a=e.open,n=e.onClose,r=Object(p.useSafeAppsSDK)(),o=r.sdk,l=r.safe,s=ba(),u=Qc(),d=Object(c.useState)(""),f=Object(x.a)(d,2),m=f[0],b=f[1],g=Object(c.useState)(!1),h=Object(x.a)(g,2),E=h[0],v=h[1],y=function(){n&&n(),b(""),v(!1)},O=function(){var e=Object(k.a)(C.a.mark((function e(){var a;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=je(l.safeAddress,m),e.prev=1,e.next=4,o.txs.send({txs:[a]});case 4:y(),t&&t(),n&&n(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(1),console.warn("error adding custom module",e.t0);case 12:case"end":return e.stop()}}),e,null,[[1,9]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{hideButton:!0,open:a,onClose:n,title:"Custom Module",icon:"custom",readMoreLink:"https://zodiac.wiki/index.php/Category:Custom_Module",warning:"Modules do not require multisig approval for transactions. Only add modules that you trust!"},i.a.createElement(co,{placeholder:"0xCcBFc37093009fd31f85F1Bf90c34F1e03FB351E",label:"Module Address",param:Ve.g.fromString("address"),onChange:function(e,t){b(e),v(!!e.length&&t)}}),i.a.createElement(Ar,{fullWidth:!0,disableElevation:!0,className:u.addButton,variant:"contained",disabled:!E,startIcon:i.a.createElement(Oc,null),onClick:O},"Add Module"),i.a.createElement(Ar,{fullWidth:!0,className:u.addTransactionButton,disabled:!E,startIcon:i.a.createElement(kr,null),onClick:function(){var e={func:new R.b(B.a).getFunction("enableModule"),to:l.safeAddress,params:[m],id:"add_module_"+(new Date).getTime()};s(ua(Rr(e))),y(),n&&n()},variant:"outlined"},"Add to Transaction Bundle"))},$c=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),ei=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=$c(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({amb:!1,controller:!1,chainId:!1}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({amb:"",chainId:"",controller:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Ee(u,s.safeAddress,s.chainId,Object(N.a)(Object(N.a)({},h),{},{executor:s.safeAddress})),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Bridge Module",description:"This module allows for execution of transactions initiated by a designated address on the other side of a designated arbitrary message bridge (AMB).",icon:"bridge",tags:["From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Bridge_Module",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.amb,label:"AMB Contract Address",onChange:function(e,t){return O("amb",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.controller,label:"Controller Contract Address",onChange:function(e,t){return O("controller",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("uint256"),label:"Chain Id",value:h.chainId,onChange:function(e,t){return O("chainId",e,t)}}))))},ti=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},textLink:{cursor:"pointer"}}})),ai=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ti(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({tokenContract:!1}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({tokenContract:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,ye(u,s.safeAddress,s.chainId,Object(N.a)(Object(N.a)({},h),{},{executor:s.safeAddress}));case 3:return t=e.sent,e.next=6,l.txs.send({txs:t});case 6:n&&n(),a&&a(),e.next=13;break;case 10:e.prev=10,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Exit Module",description:"This module allows any holders of a designated ERC20, at any time, to redeem their designated ERC20 tokens in exchange for a proportional share of the Safe\u2019s ERC20 compatible assets.",icon:"exit",tags:["From Gnosis Guild"],onAdd:O,readMoreLink:"https://zodiac.wiki/index.php/Category:Exit_Pattern",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.tokenContract,label:"Token Contract Address",onChange:function(e,t){return function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))}("tokenContract",e,t)}}))))},ni=a(269),ri=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),oi=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ri(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({target:!0,multisend:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({target:s.safeAddress,multisend:ci(s)}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Re(u,s.safeAddress,s.chainId,h),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Roles Modifier v1",description:"Legacy version of the Roles Modifier",icon:"roles",tags:["Deprecated","Stackable","From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Roles_Modifier",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.target,label:"Target Address",onChange:function(e,t){return O("target",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.multisend,label:"Multisend Address",onChange:function(e,t){return O("multisend",e,t)}}))))};function ci(e){return ni.b[e.chainId]||ni.a}var ii=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),li=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ii(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({target:!0,multisend:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({target:s.safeAddress,multisend:si(s)}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Me(u,s.safeAddress,s.chainId,h),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Roles Modifier",description:"Allows avatars to enforce granular, role-based, permissions for attached modules",icon:"roles",tags:["Stackable","From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Roles_Modifier",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.target,label:"Target Address",onChange:function(e,t){return O("target",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.multisend,label:"Multisend Address",onChange:function(e,t){return O("multisend",e,t)}}))))};function si(e){return ni.b[e.chainId]||ni.a}var ui=a(172),di={NO_ARBITRATOR:"No arbitration (highest bond wins)",KLEROS:"Kleros",OTHER:"Other (custom address)"},fi=[o.MAINNET,o.GOERLI,o.GNOSIS_CHAIN,o.POLYGON],mi=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:e.spacing(1)},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},select:{marginBottom:-1,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"100%"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1}}})),pi=function(e){var t=e.onChange,a=e.defaultOption,n=void 0===a?di.NO_ARBITRATOR:a,r=e.defaultAddress,o=void 0===r?"":r,l=e.label,s=e.chainId,u=mi(),d=Object(c.useState)(n),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)(o),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object(c.useState)(!1),y=Object(x.a)(v,2),O=y[0],w=y[1],j=function(){return w(!1)},C=function(){return w(!0)},k=i.a.useRef(null),S=function(e,a){try{!0===a&&(E(e),t(e))}catch(n){console.warn("invalid arbitrator option")}},N=function(e){j();var a=Object.keys(di).find((function(t){return di["".concat(t)]===e}));if(p(e),"OTHER"===a)E(""),t("");else{var n=pe(s,oe[a]);E(n),t(n)}};return Object(c.useEffect)((function(){k.current&&k.current.addEventListener("keyup",(function(e){"Tab"===e.code&&C()}))}),[k]),i.a.createElement("div",null,i.a.createElement(Z.a,{className:u.label},l),i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,xs:12,className:u.dropdownContainer},i.a.createElement(X.a,{disableUnderline:!0,open:O,value:m,ref:k,onOpen:C,onClose:j,className:u.select,MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:u.dropdown,list:u.itemList}},renderValue:function(e){return e},onChange:function(e){return N(e.target.value)}},Object.keys(di).map((function(e){return fi.includes(s)||"KLEROS"!==e?i.a.createElement(Q.a,{key:e,value:di["".concat(e)],className:u.item},di["".concat(e)],i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"})):null}))))),m===di.OTHER&&i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h,label:"",placeholder:"address (0x...)",onChange:function(e,t){return S(e,t)}}))))};function bi(e,t,a,n,r){var o=r?M.d.REALITY_ERC20:M.d.REALITY_ETH,c=n.timeout,i=n.cooldown,l=n.expiration,s=n.bond,u=n.templateId,d=n.oracle,f=n.executor,m=n.arbitrator,p=d||ue(a),b=Object(M.f)(o,{types:["address","address","address","address","uint32","uint32","uint32","uint256","uint256","address"],values:[t,t,f,p,c,i,l,s,u,m]},e,a,Date.now().toString()),g=b.transaction,h=b.expectedModuleAddress,E=[Object(N.a)(Object(N.a)({},g),{},{value:g.value.toString()})];if(f!==t){var v=Object(M.h)(M.d.DELAY,f,e),y=L(v.interface,v.address,"enableModule",[h]);E.push(y)}else{var O=je(t,h);E.push(O)}return E}var gi=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),hi=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=gi(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(1===d.length?d[0].address:""),E=Object(x.a)(g,2),v=E[0],O=E[1],w=Object(c.useState)(V[s.chainId].nativeAsset),j=Object(x.a)(w,2),S=j[0],T=j[1],A=Object(c.useState)({oracle:ue(s.chainId),templateId:"",timeout:172800..toString(),cooldown:172800..toString(),expiration:604800..toString(),bond:"0.1",arbitrator:pe(s.chainId,oe.NO_ARBITRATOR)}),R=Object(x.a)(A,2),M=R[0],B=R[1],D=Object(c.useState)({oracle:!!M.oracle,templateId:!!M.templateId,bond:!!M.bond}),L=Object(x.a)(D,2),F=L[0],U=L[1],H=Object.values(F).every((function(e){return e}));Object(c.useEffect)((function(){M.oracle&&I.ethers.utils.isAddress(M.oracle)&&function(e,t,a){return K.apply(this,arguments)}(u,M.oracle,s.chainId).then((function(e){T(e.coin),b(e.isERC20)})).catch((function(){T(V[s.chainId].nativeAsset),b(!1)}))}),[M.oracle,s.chainId,u]);var _=function(e,t,a){B(Object(N.a)(Object(N.a)({},M),{},Object(P.a)({},e,t))),void 0!==a&&U(Object(N.a)(Object(N.a)({},F),{},Object(P.a)({},e,a)))},G=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r,o;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=I.ethers.utils.parseUnits(M.bond,S.decimals),r=Object(N.a)(Object(N.a)({},M),{},{executor:v||s.safeAddress,bond:t.toString()}),e.next=5,bi(u,s.safeAddress,s.chainId,r,p);case 5:return o=e.sent,e.next=8,l.txs.send({txs:o});case 8:n&&n(),a&&a(),e.next=15;break;case 12:e.prev=12,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 15:case"end":return e.stop()}}),e,null,[[0,12]])})));return function(){return e.apply(this,arguments)}}(),W=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return i.a.createElement(wc,{open:t,onClose:a,title:"Reality Module",description:"Allows Reality.eth questions to execute a transaction when resolved.",icon:"reality",tags:["Stackable","From Gnosis Guild"],onAdd:G,readMoreLink:"https://zodiac.wiki/index.php/Category:Reality_Module",ButtonProps:{disabled:!H}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:ui.ParamType.from("address"),color:"secondary",value:M.oracle,label:"Oracle Address",onChange:function(e,t){return _("oracle",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(y.a,null,"TemplateId"),i.a.createElement(Or,null),i.a.createElement(Ma.a,{color:"textSecondary",href:"https://reality.eth.link/app/template-generator/",target:"_blank"},"Get a template here")),i.a.createElement(co,{param:ui.ParamType.from("uint256"),color:"secondary",placeholder:"10929783",label:void 0,value:M.templateId,onChange:function(e,t){return _("templateId",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Timeout",defaultValue:M.timeout,defaultUnit:"days",onChange:function(e){return _("timeout",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:M.cooldown,defaultUnit:"days",onChange:function(e){return _("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:M.expiration,defaultUnit:"days",onChange:function(e){return _("expiration",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Bond",color:"secondary",value:M.bond,append:null===S||void 0===S?void 0:S.symbol,onChange:function(e){var t=e.target.value||"0",a=t.startsWith("0")&&t.length>1?t.substr(1):t;a=a.startsWith(".")?"0"+a:a;try{I.ethers.utils.parseUnits(a,S.decimals),_("bond",a)}catch(n){console.warn("invalid bond",t,n)}}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(pi,{label:"Arbitrator",defaultAddress:M.arbitrator,defaultOption:di.NO_ARBITRATOR,onChange:function(e){return _("arbitrator",e)},chainId:s.chainId}))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:W,modules:d,value:v,onChange:function(e){return O(e)},type:Fe.DELAY})):null)},Ei=a(510),vi=a(477),yi=a(488),Oi=a.n(yi),xi=a(747);function wi(e,t,a,n,r,o,c){return ji.apply(this,arguments)}function ji(){return(ji=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i){var l,s,u,d,f,m,p,b,g,h,E,v,y,O,x,w,j,k,S,T;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(l=i?M.d.REALITY_ERC20:M.d.REALITY_ETH,s=o.timeout,u=o.cooldown,d=o.expiration,f=o.bond,m=o.oracle,p=o.executor,b=o.arbitrator,null!=(g=null!=m&&I.ethers.utils.isAddress(m)?m:ue(r))){e.next=5;break}throw new Error("No oracle address provided and no default oracle available for this chain (chainID: ".concat(r,")"));case 5:return h=Date.now().toString(),E={types:["address","address","address","address","uint32","uint32","uint32","uint256","uint256","address"],values:[n,a,p,g,s,u,d,f,0,b]},v=Object(M.f)(l,E,t,r,h),y=v.transaction,O=v.expectedModuleAddress,x=[Object(N.a)(Object(N.a)({},y),{},{value:y.value.toString()})],p!==a?(w=Object(M.h)(M.d.DELAY,p,t),j=L(w.interface,w.address,"enableModule",[O]),x.push(j)):(k=je(a,O),x.push(k)),S=new I.ethers.Contract(n,xi.abi,t),e.next=13,S.populateTransaction.createTemplateAndChangeOwner(O,g,JSON.stringify({type:"bool",title:c.templateQuestion,category:"DAO proposal",lang:"en"}),a);case 13:if(null!=(T=e.sent).to){e.next=16;break}throw new Error("Missing to address");case 16:if(null!=T.data){e.next=18;break}throw new Error("Missing data");case 18:return x.push({to:T.to,data:T.data,value:"0"}),e.abrupt("return",{txs:x,meta:{expectedModuleAddress:O}});case 20:case"end":return e.stop()}}),e)})))).apply(this,arguments)}a(111);var Ci,ki=a(748),Si=(new TextDecoder,function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=Ci){e.next=4;break}return e.next=3,ki.create();case 3:Ci=e.sent;case 4:return e.abrupt("return",Ci);case 5:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()),Ni=function(){var e=Object(k.a)(C.a.mark((function e(t){var a,n,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Si();case 2:return a=e.sent,e.next=5,a.add(t);case 5:return n=e.sent,r=n.cid,e.abrupt("return",r);case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Ii=a(194),Ti="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",Ai=["function setText(bytes32 node, string calldata key, string calldata value) external","function text(bytes32 node, string calldata key) external view returns (string memory)"],Ri=["function owner(bytes32 node) external view returns (address)","function resolver(bytes32 node) external view returns (address)"],Mi=["function ownerOf(uint256 tokenId) public view returns (address owner)"],Bi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return o=new I.ethers.Contract(Ti,Ri,t),c=I.ethers.utils.namehash(a),e.next=4,o.resolver(c);case 4:return i=e.sent,l=new I.ethers.Contract(i,Ai,t),e.next=8,l.populateTransaction.setText(c,n,r);case 8:if(null!=(s=e.sent).to){e.next=11;break}throw new Error("Missing to address");case 11:if(null!=s.data){e.next=13;break}throw new Error("Missing data");case 13:return e.abrupt("return",{to:s.to,data:s.data,value:"0"});case 14:case"end":return e.stop()}}),e)})));return function(t,a,n,r){return e.apply(this,arguments)}}(),Di=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=I.ethers.BigNumber,o=a.split(".")[0],c=I.ethers.utils.keccak256(I.ethers.utils.toUtf8Bytes(o)),i=r.from(c).toString(),l=new I.ethers.Contract("0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",Mi,t),e.next=7,l.ownerOf(i);case 7:return s=e.sent,e.abrupt("return",I.ethers.utils.getAddress(s)===I.ethers.utils.getAddress(n));case 9:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Li=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i,l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=I.ethers.utils.namehash(t),o=new I.ethers.Contract(Ti,Ri,n),e.next=4,o.resolver(r);case 4:return c=e.sent,i=new I.ethers.Contract(c,Ai,n),l=i.functions.text(r,a),e.abrupt("return",l);case 8:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Pi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new I.ethers.Contract(Ti,Ri,t),o=I.ethers.utils.namehash(a),e.next=4,r.owner(o);case 4:return c=e.sent,e.abrupt("return",I.ethers.utils.getAddress(n)===I.ethers.utils.getAddress(c));case 6:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Fi=a(489),Ui=a.n(Fi),Vi=["flagged","verified","hibernated","turbo"],Hi=function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Gi(t,a);case 2:return e.next=4,fetch("".concat(Wi(a),"/api/spaces/").concat(t));case 4:if(!(n=e.sent).ok){e.next=17;break}return e.prev=6,e.next=9,n.json().then((function(e){e.flagged,e.verified,e.hibernated,e.turbo;return Object(Ca.a)(e,Vi)}));case 9:return e.abrupt("return",e.sent);case 12:return e.prev=12,e.t0=e.catch(6),e.abrupt("return",void 0);case 15:e.next=18;break;case 17:throw n;case 18:case"end":return e.stop()}}),e,null,[[6,12]])})));return function(t,a){return e.apply(this,arguments)}}(),_i=function(e){return Ui.a.utils.validateSchema(Ui.a.schemas.space,e)},Gi=function(e,t){return fetch("".concat(Wi(t),"/api/spaces/").concat(e,"/poke"))},Wi=function(e){return e===o.GOERLI?"https://testnet.hub.snapshot.org":"https://hub.snapshot.org"},zi="https://api.zodiac.gnosisguild.org/api";var Ki=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(console.log(),""!==(null!==(o=r.apiKey)&&void 0!==o?o:"")&&""!==(null!==(c=r.secretKey)&&void 0!==c?c:"")){e.next=3;break}throw new Error("API keys for monitoring service missing. Monitoring will NOT be set up.");case 3:if(""!==(null!==(i=r.discordKey)&&void 0!==i?i:"")||""!==(null!==(l=r.slackKey)&&void 0!==l?l:"")||0!==r.email.length||""!==(null!==(s=r.telegram.botToken)&&void 0!==s?s:"")||null===(u=r.telegram.chatId)||void 0===u||!u){e.next=5;break}throw new Error("No notification channel(s) specified. Monitoring will NOT be set up.");case 5:return d=[],r.email.length>0&&d.push({channel:"email",config:{emails:r.email}}),r.discordKey.length>0&&d.push({channel:"discord",config:{url:r.discordKey}}),r.slackKey.length>0&&d.push({channel:"slack",config:{url:r.slackKey}}),r.telegram.botToken.length>0&&d.push({channel:"telegram",config:r.telegram}),f={apiKey:r.apiKey,apiSecret:r.secretKey,network:Zi(t),oracleAddress:n,realityModuleAddress:a,notificationChannels:d},e.abrupt("return",fetch(zi+"/monitoring/notification",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(f)}));case 12:case"end":return e.stop()}}),e)})));return function(t,a,n,r){return e.apply(this,arguments)}}(),Yi=function(){var e=Object(k.a)(C.a.mark((function e(t){var a,n;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=t.apiKey,n=t.apiSecret,e.abrupt("return",fetch("".concat(zi,"/monitoring/validation?apiKey=").concat(a,"&apiSecret=").concat(n),{method:"GET",mode:"cors",headers:{"Content-Type":"application/json",Accept:"application/json"}}));case 2:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Zi=function(e){switch(e){case o.MAINNET:return"mainnet";case o.GOERLI:return"goerli";case o.OPTIMISM:return"optimism";case o.BSC:return"bsc";case o.GNOSIS_CHAIN:return"xdai";case o.POLYGON:return"matic";case o.ARBITRUM:return"arbitrum";case o.AVALANCHE:return"avalanche";default:throw new Error("Unsupported network")}};var qi,Xi=function(){var e=Object(k.a)(C.a.mark((function e(t){var a;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,fetch("https://api.zodiac.gnosisguild.org/api/ipfs-pinning/snapshot-settings",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});case 2:return a=e.sent,e.abrupt("return",a.json());case 4:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Qi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c){var i,l,s,u,d,f;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c("Setting up Reality Module deployment transactions"),e.next=3,Ji(t,n.chainId,n.safeAddress,r,o).catch((function(e){c("Error while setting up Reality Module deployment transactions",e)}));case 3:if(null!=(l=e.sent)){e.next=6;break}throw new Error("The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE. Should be handled in the 'statusCallback' function.");case 6:if(null==(s=null===(i=l.meta)||void 0===i?void 0:i.expectedModuleAddress)&&(u=new Error("Unable to calculate the Reality Module future address."),c(u.message,u)),null!=s){e.next=10;break}throw new Error("The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.");case 10:return c("Setting up transaction for adding the new snapshot space to the ENS record"),e.next=13,el(t,o.proposal.ensName,s,n.chainId).catch((function(e){c("Error when setting up transactions to add SafeSnap to the Snapshot Space",e)}));case 13:if(d=e.sent,null!=l&&null!=d){e.next=16;break}throw new Error("The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE.");case 16:return f=[].concat(Object(w.a)(l.txs),Object(w.a)(d.txs)),c("Setting up monitoring with OZ Defender"),e.next=20,Ki(n.chainId,s,o.oracle.instanceData.instanceAddress,o.monitoring).catch((function(e){c("Error when setting up monitoring.",e)}));case 20:return c("Proposing transactions to the Safe"),e.next=23,a.txs.send({txs:f}).catch((function(e){c("Error when proposing transactions to the Safe",e)}));case 23:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c){return e.apply(this,arguments)}}(),Ji=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c=V[a].nativeAsset,i={executor:r,bond:I.ethers.utils.parseUnits(o.oracle.bondData.bond.toString(),c.decimals).toString(),timeout:o.oracle.delayData.timeout.toString(),cooldown:o.oracle.delayData.cooldown.toString(),expiration:o.oracle.delayData.expiration.toString(),arbitrator:pe(a,o.oracle.arbitratorData.arbitratorOption),oracle:o.oracle.instanceData.instanceAddress},e.next=4,wi(t,n,"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c",a,i,o.oracle.templateData,!1);case 4:return e.abrupt("return",e.sent);case 5:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}(),$i=function(e,t,a){return Ii.b(["plugins","safeSnap"],{safes:[{network:t,realityAddress:a,multisend:"0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761"}]},e)},el=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Hi(a,r);case 2:if(o=e.sent,c=$i(o,r,n),f=o,m=c,Ii.a(Ii.d(Ii.e(["plugins","safeSnap"],f),Ii.e(["plugins","safeSnap"],m)),!0===_i(m))){e.next=6;break}throw new Error("The new settings file is changed in unexpected ways");case 6:return e.next=8,Ni(JSON.stringify(c));case 8:return i=e.sent.toV0().toString(),l="",e.prev=10,e.next=13,Xi({snapshotSpaceEnsName:a,snapshotSpaceSettings:c,chainId:r});case 13:s=e.sent,u=s.cidV0,l=u,e.next=21;break;case 18:throw e.prev=18,e.t0=e.catch(10),new Error("Failed to pin the new snapshot space settings file. Error from backend: "+e.t0);case 21:if(""!==l&&null!=l){e.next=23;break}throw new Error("Communication with the backend pinning service failed. No CID was returned.");case 23:if(null==i||i===l){e.next=25;break}throw new Error("The CID from the locale browser node (".concat(i,") does not correspond the CID from the pinning service (").concat(l,")"));case 25:return e.next=27,Bi(t,a,"snapshot","ipfs://".concat(i));case 27:return d=e.sent,e.abrupt("return",{txs:[d]});case 29:case"end":return e.stop()}var f,m}),e,null,[[10,18]])})));return function(t,a,n,r){return e.apply(this,arguments)}}(),tl=Object(g.a)((function(){return{label:{marginBottom:4},select:{border:"1px solid ".concat(h.f.tan[300])},selectContainer:{padding:2,boxSizing:"border-box",border:"1px solid ".concat(h.f.tan[300])},icon:{fontSize:"1rem"}}})),al=function(e){var t=tl();return i.a.createElement(J.a,null,e.label&&i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",className:t.label},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,e.label)),e.tooltipMsg&&i.a.createElement(q.a,{item:!0},i.a.createElement(wo.a,{title:e.tooltipMsg},i.a.createElement(ko.a,{className:t.icon})))),i.a.createElement(J.a,{className:t.selectContainer},i.a.createElement(X.a,Object.assign({},Ii.c("tooltipMsg",e),{className:t.select}),e.options.map((function(e){return i.a.createElement(Q.a,{key:e.value,value:e.value},e.label,i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}))})))))},nl=a(1719),rl=function(e){return"Did the Snapshot proposal with the id %s in the ".concat(e," space pass the execution of the array of Module transactions that have the hash 0x%s and does it meet the requirements of the document referenced in the dao requirements record at ").concat(e,"? The hash is the keccak of the concatenation of the individual EIP-712 hashes of the Module transactions. If this question was asked before the corresponding Snapshot proposal was resolved, it should ALWAYS be resolved to INVALID!")},ol="Provide a question. This must include two %s placeholders.\nThe first placeholder is for the id of the proposal (e.g., an IPFS hash).\nThe second is the hash of the concatenation of the EIP-712 transaction hashes.",cl=[{label:"Zodiac Reality Module (default)",value:"default"},{label:"Custom",value:"custom"}],il=[{label:"English",value:"english"}],ll=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},textFieldSmall:{"& .MuiFormLabel-root":{fontSize:12}},select:{border:"1px solid rgba(217, 212, 173, 0.3)"},paperTemplateContainer:{marginTop:4,padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)"},templateQuestion:{fontFamily:"Roboto Mono","& .MuiInputBase-root":{border:"none",fontSize:"0.85rem"}},input:{"& .MuiInputBase-root":{padding:"9px 8px",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},button:{width:"100%",padding:"4px 15px"},buttonContainer:{marginTop:8,cursor:"pointer"},icon:{color:h.f.tan[1e3],fontSize:"1rem",marginTop:3},text:{fontSize:"0.75rem"},tooltipIcon:{fontSize:"1rem"}}})),sl=function(e){var t=e.data,a=e.setData,n=e.ensName,r=ll(),o=function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}},c=function(e){return t[e]};return i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Oracle Template")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"The oracle template creates an appropriate question based on the data of the proposal. We highly recommend using the default Zodiac Reality Module template")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",spacing:2,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(al,{value:c("templateType"),options:cl,onChange:function(e){return r=e.target.value,void a("default"===r?Object(N.a)(Object(N.a)({},t),{},{templateQuestion:rl(n),templateType:r}):Object(N.a)(Object(N.a)({},t),{},{templateQuestion:"",templateType:r}));var r},label:"Select template:",tooltipMsg:"The Zodiac Reality Module type has defaults set for connecting the Reality Module to Safesnap. If you need a more specific setup, use the \u2018Custom\u2019 type."})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(al,{value:c("language"),options:il,disableUnderline:"default"===c("templateType"),label:"Language:",disabled:"default"===c("templateType"),onChange:function(e){var t=e.target;return o("language")(t.value)}})),i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(y.a,null,"Template question preview:"),i.a.createElement(wo.a,{title:ol},i.a.createElement(nl.a,{className:r.tooltipIcon}))),i.a.createElement(h.c,{className:r.paperTemplateContainer},i.a.createElement(h.e,{className:r.templateQuestion,value:c("templateQuestion"),onChange:function(e){var t=e.target;return o("templateQuestion")(t.value)},multiline:!0,minRows:5,disabled:"default"===c("templateType"),placeholder:"default"===c("templateType")?rl(n):ol})))))))},ul=a(381),dl=a.n(ul),fl=["svgRef","title"];function ml(){return(ml=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var bl=function(e){var t=e.svgRef,a=e.title,n=pl(e,fl);return i.a.createElement("svg",ml({width:15,height:12,viewBox:"0 0 15 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,qi||(qi=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z"})))},gl=i.a.forwardRef((function(e,t){return i.a.createElement(bl,ml({svgRef:t},e))})),hl=(a.p,function(){var e=Object(c.useState)(!1),t=Object(x.a)(e,2),a=t[0],n=t[1],r=Object(c.useState)(),o=Object(x.a)(r,2),i=o[0],l=o[1];return{loading:a,error:i,execute:function(){var e=Object(k.a)(C.a.mark((function e(t,a){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n(!0),l(void 0),e.prev=2,e.next=5,Yi({apiKey:t,apiSecret:a}).then((function(e){if(n(!1),200===e.status)return l(!1);l(!0)}));case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(2),n(!1);case 10:case"end":return e.stop()}}),e,null,[[2,7]])})));return function(t,a){return e.apply(this,arguments)}}()}}),El=Object(g.a)((function(e){return{errorIcon:{fill:"rgba(244, 67, 54, 1)",width:"20px"},warningIcon:{fill:"rgba(230, 230, 54, 1)",width:"20px"},fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},loadingContainer:{marginRight:4,padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:14,width:14,border:"1px solid ".concat(h.f.tan[300])},spinner:{width:"8px !important",height:"8px !important",color:"yellow !important",fill:"yellow !important",opacity:"100% !important"},addSpinner:{color:"white !important",fill:"white !important",opacity:"100% !important"},detailsContainer:{width:"95%"},messageContainer:{width:"85%",fill:"rgba(244, 67, 54, 1)"},errorMessageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer",color:"rgba(244, 67, 54, 1)"},warningMessageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer",color:"rgba(230, 230, 54, 1)"},errorMessage:{fontSize:12,color:"rgba(244, 67, 54, 1)",fontWeight:"bolder"},warningMessage:{fontSize:12,color:"rgba(230, 230, 54, 1)"},linkStyle:{color:"rgba(190, 190, 120, 1)"},flexRow:{display:"flex",flexDirection:"row"}}})),vl=Object(qa.a)({switchBase:{"&.Mui-checked":{color:"white"}},colorSecondary:{"&.Mui-checked + .MuiSwitch-track":{backgroundColor:"yellow"}},track:{backgroundColor:"black"}})(Ei.a),yl=function(e){var t=e.status,a=e.message,n=e.link,r=El();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:1},"error"===t&&i.a.createElement(Mo.a,{className:r.errorIcon}),"warning"===t&&i.a.createElement(dl.a,{className:r.warningIcon})),i.a.createElement(q.a,{item:!0,className:r.detailsContainer,xs:11},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0,className:r.messageContainer},i.a.createElement(y.a,{className:"error"===t?r.errorMessage:r.warningMessage},a)),n?i.a.createElement(q.a,{item:!0},i.a.createElement(Ma.a,{className:"error"===t?r.errorMessageDetails:r.warningMessageDetails,href:n,target:"_blank"},"Details")):i.a.createElement(q.a,null))))},Ol=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=El(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useMemo)((function(){return new I.ethers.providers.InfuraProvider(1,"0de1a96486754f8b98f284d093905198")}),[]),f=Object(c.useMemo)((function(){return new I.ethers.providers.InfuraProvider(5,"0de1a96486754f8b98f284d093905198")}),[]),p=V[s.chainId].nativeAsset,b=Object(c.useState)({snapshotEns:"",timeout:172800..toString(),cooldown:172800..toString(),expiration:604800..toString(),bond:"0.1"}),g=Object(x.a)(b,2),E=g[0],v=g[1],O=Object(c.useState)(!1),j=Object(x.a)(O,2),S=j[0],T=j[1],A=Object(c.useState)(!1),R=Object(x.a)(A,2),M=R[0],B=R[1],D=Object(c.useState)(!1),L=Object(x.a)(D,2),F=L[0],U=L[1],H=Object(c.useState)(""),_=Object(x.a)(H,2),G=_[0],W=_[1],z=Object(c.useState)(!1),K=Object(x.a)(z,2),Y=K[0],Z=K[1],X=Object(c.useState)(!1),Q=Object(x.a)(X,2),$=Q[0],ee=Q[1],te=!!E.snapshotEns&&E.snapshotEns.includes(".eth")&&!S&&M&&F,ae=Object(c.useState)({snapshotEns:te,bond:!!E.bond}),ne=Object(x.a)(ae,2),re=ne[0],oe=ne[1],ce=Object(c.useState)(!1),ie=Object(x.a)(ce,2),le=ie[0],se=ie[1],de=Object(c.useState)(""),fe=Object(x.a)(de,2),pe=fe[0],be=fe[1],ge=Object(c.useState)(""),he=Object(x.a)(ge,2),Ee=he[0],ve=he[1],ye=Object(c.useState)(!1),Oe=Object(x.a)(ye,2),xe=Oe[0],we=Oe[1],je=Object(c.useState)(""),Ce=Object(x.a)(je,2),ke=Ce[0],Se=Ce[1],Ne=Object(c.useState)([]),Ie=Object(x.a)(Ne,2),Te=Ie[0],Ae=Ie[1],Re=Object(c.useState)(""),Me=Object(x.a)(Re,2),Be=Me[0],De=Me[1],Le=Object(c.useState)(""),Pe=Object(x.a)(Le,2),Fe=Pe[0],Ue=Pe[1],Ve=Object(c.useState)(""),He=Object(x.a)(Ve,2),_e=He[0],Ge=He[1],We=Object(c.useState)("form"),ze=Object(x.a)(We,2),Ke=ze[0],Ye=ze[1],Ze=Object.values(re).every((function(e){return e})),qe=/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.test(ke)&&!Te.includes(ke),Xe=Ze&&(!le||void 0!==pe&&void 0!==Ee&&Te.length>0),Qe=Object(c.useState)(!1),Je=Object(x.a)(Qe,2),$e=Je[0],et=Je[1],tt=Object(c.useCallback)(Object(k.a)(C.a.mark((function e(){var t,a,n,r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=5===s.chainId?f:d,e.next=3,t.resolveName(E.snapshotEns);case 3:if(a=e.sent,console.log({address:a}),!a){e.next=24;break}return e.next=8,Hi(E.snapshotEns,s.chainId);case 8:return n=e.sent,e.next=11,Li(E.snapshotEns,"daorequirements",t);case 11:if(r=e.sent,W(r[0]),U(void 0!==n),void 0===n){e.next=22;break}return ee(!!(null===(o=n.plugins)||void 0===o?void 0:o.safeSnap)),e.next=18,Pi(t,E.snapshotEns,s.safeAddress);case 18:c=e.sent,Z(c),console.log({isController:c,snapshotSpace:n}),console.log({snapshotSpace:n});case 22:e.next=24;break;case 24:case"end":return e.stop()}}),e)}))),[E.snapshotEns,s.chainId,s.safeAddress,d,f]),at=Oi()((function(){(U(!1),W(""),Z(!1),ee(!1),B(!1),E.snapshotEns&&E.snapshotEns.includes(".eth"))&&(T(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,tt();case 2:T(!1),B(!0);case 4:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()())}),300);Object(c.useEffect)((function(){at()}),[E.snapshotEns]);var nt=hl(),rt=nt.loading,ot=nt.execute,ct=nt.error,it=Oi()(Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return we(!1),e.next=3,ot(pe,Ee);case 3:we(!0);case 4:case"end":return e.stop()}}),e)}))),300);Object(c.useEffect)((function(){pe&&Ee&&it()}),[pe,Ee]),Object(c.useEffect)((function(){if(s.chainId){var e=1===s.chainId?"1":100===s.chainId?"1500":137===s.chainId?"1000":"1";v((function(t){return Object(N.a)(Object(N.a)({},t),{},{bond:e})}))}}),[s.chainId]),Object(c.useEffect)((function(){oe({snapshotEns:te,bond:!!E.bond})}),[E,S,te]);var lt=function(e,t,a){v(Object(N.a)(Object(N.a)({},E),{},Object(P.a)({},e,t)))},st=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r,o,c,i,d,f,m,b,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return et(!0),e.prev=1,r=I.ethers.utils.parseUnits(E.bond,p.decimals),o=Object(N.a)(Object(N.a)({},E),{},{oracle:ue(s.chainId),arbitrator:me(s.chainId),executor:s.safeAddress,bond:r.toString()}),c=rl(o.snapshotEns),i={templateType:"default",language:"english",category:"DAO proposal",templateQuestion:c},e.next=8,wi(u,s.safeAddress,"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c",s.chainId,o,i);case 8:if(d=e.sent,f=Object(w.a)(d.txs),m=null===(t=d.meta)||void 0===t?void 0:t.expectedModuleAddress,!Y||1!==s.chainId){e.next=19;break}if(null!=m){e.next=14;break}throw new Error("The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.");case 14:return e.next=16,el(u,o.snapshotEns,m,s.chainId);case 16:b=e.sent,g=b.txs,f.push(g[0]);case 19:if(!le){e.next=23;break}return h={apiKey:pe,secretKey:Ee,discordKey:Be,email:Te,slackKey:"",telegram:{botToken:Fe,chatId:_e}},e.next=23,Ki(s.chainId,m,o.oracle,h);case 23:return e.next=25,l.txs.send({txs:f});case 25:n&&n(),a&&a(),e.next=32;break;case 29:e.prev=29,e.t0=e.catch(1),console.log("Error deploying module: ",e.t0);case 32:et(!1);case 33:case"end":return e.stop()}}),e,null,[[1,29]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Kleros Snapshot Module",description:"Execute transactions for successful Snapshot proposals using Reality.eth, secured by Kleros.",icon:"reality",tags:["Stackable","From Kleros"],hideButton:!0,readMoreLink:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module"},"form"===Ke?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:E.snapshotEns,onChange:function(e){return lt("snapshotEns",e.target.value)},label:"Snapshot Name",placeholder:"gnosis.eth",rightIcon:i.a.createElement(i.a.Fragment,null,S?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):M&&F?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner})):null)}),!S&&M&&!te&&i.a.createElement(yl,{message:"This Snapshot space does not exist.",status:"error"})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Timeout",defaultValue:E.timeout,defaultUnit:"days",onChange:function(e){return lt("timeout",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:E.cooldown,defaultUnit:"days",onChange:function(e){return lt("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:E.expiration,defaultUnit:"days",onChange:function(e){return lt("expiration",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Bond",prefix:p.symbol,color:"secondary",value:E.bond,onChange:function(e){var t=e.target.value||"0",a=t.startsWith("0")&&t.length>1?t.substr(1):t;a=a.startsWith(".")?"0"+a:a;try{I.ethers.utils.parseUnits(a,p.decimals),lt("bond",a)}catch(n){console.warn("invalid bond",t,n)}}}))),i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(y.a,{variant:"body1"},"Configure Monitoring")),i.a.createElement(q.a,{xs:6,style:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"space-between"}},i.a.createElement("div",null),i.a.createElement(vl,{value:le,onClick:function(){se(!le)}}))),le&&i.a.createElement(q.a,{container:!0,direction:"column",spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(y.a,{variant:"body2"},"Setting up an effective monitoring strategy is critical for the security of your safe. First, you need to"," ",i.a.createElement(Ma.a,{className:r.linkStyle,underline:"always",href:"https://defender.openzeppelin.com/#/auth/sign-in",target:"_blank"},"create an Open Zeppelin account"),".")),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:pe,onChange:function(e){be(e.target.value)},label:"API Key",placeholder:"3pwZzZZZzzZZZzzZZzZZZAAaaAAaaZZzz",rightIcon:rt?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):xe&&!ct&&i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner}))})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:Ee,onChange:function(e){ve(e.target.value)},label:"API Secret",placeholder:"2LUwZwwuUuuUUzzZZdDddooodudDDdaaDDdaAAAddDDadDzZZzdDDdcCCdDDaaAA",rightIcon:rt?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):xe&&!ct&&i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner}))})),xe&&ct&&i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(yl,{message:"These credentials are wrong.",status:"error"})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Email"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(required)")),i.a.createElement(y.a,{variant:"body2"},"Enter as many email addresses as you need"),i.a.createElement(h.e,{placeholder:"john@doe.com",value:ke,onChange:function(e){Se(e.target.value)},onKeyDown:function(e){"Enter"===e.key&&qe&&(Ae([].concat(Object(w.a)(Te),[ke])),Se(""))},rightIcon:i.a.createElement(i.a.Fragment,null,qe?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(vi.a,{size:"small",onClick:function(){Ae([].concat(Object(w.a)(Te),[ke])),Se("")}}," ",i.a.createElement(m.Icon,{size:"sm",type:"add",color:"primary"}))):null)}),Te.length>0?Te.map((function(e){return i.a.createElement(q.a,{container:!0,key:e},i.a.createElement(q.a,{item:!0,xs:1},i.a.createElement(vi.a,{size:"small",onClick:function(){return Ae(Te.filter((function(t){return t!==e})))}},i.a.createElement(m.Icon,{size:"sm",type:"delete",color:"warning"}))),i.a.createElement(q.a,{item:!0,xs:11},i.a.createElement(y.a,null,e)))})):i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},qe?"Press Enter or click + to add this email":"(No emails entered, at least one is required)")),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Discord Integration"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(optional)")),i.a.createElement(q.a,{container:!0,style:{display:"flex",flexDirection:"row",justifyContent:"space-between"}},i.a.createElement(y.a,{variant:"body2"},"Include the Discord channel's url key"),i.a.createElement(Ma.a,{className:r.linkStyle,href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks",target:"_blank"},"Learn more")),i.a.createElement(h.e,{value:Be,onChange:function(e){De(e.target.value)},placeholder:"https://discord.com/api/webhooks/.../"})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Telegram Integration"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(optional)")),i.a.createElement(q.a,{container:!0,style:{display:"flex",flexDirection:"row",justifyContent:"space-between"}},i.a.createElement(y.a,{variant:"body2"},"Include the Telegram bot token and Chat ID"),i.a.createElement(Ma.a,{className:r.linkStyle,href:"https://core.telegram.org/bots#6-botfather",target:"_blank"},"Learn more")),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"row",alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{placeholder:"123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",value:Fe,onChange:function(e){Ue(e.target.value)}})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{placeholder:"1234567890",value:_e,onChange:function(e){Ge(e.target.value)}})))))),i.a.createElement(Ar,{fullWidth:!0,startIcon:i.a.createElement(Oc,null),onClick:function(){Ye("confirm")},disabled:!Xe,style:{marginTop:"16px"}},Xe||!le?"Add Module":rt?"Validating OpenZeppelin Credentials...":!xe||ct?"Missing OpenZeppelin API":"Missing Email")):i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,null,"It's almost ready! Just a reminder:"),M&&(te?Y&&1===s.chainId?$?i.a.createElement("div",null,"SafeSnap plugin is already installed, and will be overwritten."):i.a.createElement("div",null,"The SafeSnap plugin will be automatically installed."):i.a.createElement("div",{style:{marginTop:"4px"}},i.a.createElement(yl,{message:"Install SafeSnap after creating the module.",link:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module#safesnap",status:"warning"})):i.a.createElement(yl,{message:"This Snapshot space does not exist.",status:"error"})),M&&""===G&&i.a.createElement(yl,{message:"Missing DAO requirements ENS record.",link:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module#missing-daorequirements",status:"warning"}),i.a.createElement(q.a,{container:!0,spacing:2,style:{display:"flex",flexDirection:"row",marginTop:"16px"}},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Ar,{fullWidth:!0,disabled:$e,startIcon:i.a.createElement(Oc,{style:{rotate:"270deg"}}),onClick:function(){return Ye("form")}},"Return")),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Ar,{fullWidth:!0,disabled:$e,startIcon:$e?i.a.createElement(m.Loader,{size:"xs",className:r.addSpinner}):i.a.createElement(Oc,null),onClick:function(){st()}},"Add Module")),$e&&le&&i.a.createElement(q.a,{xs:12,style:{marginLeft:"8px"}},i.a.createElement("div",null,"This can take around a minute, please wait...")))))},xl=Object(g.a)((function(e){return{addButton:{marginTop:e.spacing(2)},addTransactionButton:{marginTop:e.spacing(1)},addIcon:{stroke:e.palette.common.white,width:20,height:20},inputParam:{marginTop:e.spacing(2)},errorMessage:{marginTop:e.spacing(1),color:"red"}}})),wl=function(e){var t=e.onSubmit,a=e.open,n=e.onClose,r=dr(),o=r.sdk,l=r.safe,s=r.provider,u=xl(),d=Object(c.useState)({owner:!1,avatar:!1,target:!1,domainId:!0,sender:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({owner:l.safeAddress,avatar:l.safeAddress,target:l.safeAddress,domainId:0,sender:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,!a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},O=function(){var e=Object(k.a)(C.a.mark((function e(){var a,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,a=Object(N.a)({},h),r=De(s,l.safeAddress,l.chainId,a),e.next=5,o.txs.send({txs:r});case 5:t&&t(),n&&n(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.error("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{hideButton:!0,open:a,onClose:n,title:"Connext Module",description:"This module allows for execution of transactions initiated by a designated address on the other chain via Connext.",tags:["From Connext"],icon:"connext",readMoreLink:"https://github.com/gnosis/zodiac-module-connext/"},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(co,{placeholder:"Origin Sender Address",label:"Origin sender address",param:Ve.g.fromString("address"),onChange:function(e,t){return v("sender",e,t)}}),i.a.createElement(co,{placeholder:"Connext origin domain ID",label:"Connext origin domain ID",className:u.inputParam,param:Ve.g.fromString("uint256"),onChange:function(e,t){return v("domainId",e,t)}}),i.a.createElement(y.a,{className:u.errorMessage},be(l.chainId)?null:"Not supported network for the Module"),i.a.createElement(Ar,{fullWidth:!0,disableElevation:!0,className:u.addButton,variant:"contained",disabled:m.domainId||m.sender||!be(l.chainId),startIcon:i.a.createElement(Oc,null),onClick:O},"Add Module"))},jl=function(e){var t=e.selected,a=e.onClose,n=e.onSubmit;return i.a.createElement(i.a.Fragment,null,i.a.createElement(Kc,{open:t===Fe.TELLOR,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.TELLOR)}))}),i.a.createElement(Zc,{open:t===Fe.OPTIMISTIC_GOVERNOR,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.OPTIMISTIC_GOVERNOR)}))}),i.a.createElement(Xc,{open:t===Fe.DELAY,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.DELAY)}))}),i.a.createElement(ei,{open:t===Fe.BRIDGE,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.BRIDGE)}))}),i.a.createElement(ai,{open:t===Fe.EXIT,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.EXIT)}))}),i.a.createElement(oi,{open:t===Fe.ROLES_V1,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.ROLES_V1)}))}),i.a.createElement(li,{open:t===Fe.ROLES_V2,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.ROLES_V2)}))}),i.a.createElement(hi,{open:t===Fe.REALITY_ETH,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.REALITY_ETH)}))}),i.a.createElement(Ol,{open:t===Fe.KLEROS_REALITY,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.KLEROS_REALITY)}))}),i.a.createElement(wl,{open:t===Fe.CONNEXT,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.CONNEXT)}))}),i.a.createElement(Jc,{open:t===Fe.UNKNOWN,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.UNKNOWN)}))}))},Cl=Object(g.a)((function(e){return{root:{padding:e.spacing(1.5)},gridContainer:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(180px, 1fr))",gap:e.spacing(2)},paper:{padding:e.spacing(2.5,2)},title:{marginBottom:e.spacing(2)},introBox:{gridColumn:"1/3","@media (max-width:930px)":{gridColumn:"1/2"}},firstModule:{gridColumn:1},link:{color:e.palette.text.primary}}})),kl=function(){var e=Cl(),t=ba(),a=Object(p.useSafeAppsSDK)().safe,n=ga((function(e){return Rt(e).length>0})),r=Object(c.useState)(),l=Object(x.a)(r,2),s=l[0],u=l[1],d=M.b[a.chainId],f=n?"Add another mod":"Start by adding a mod";return i.a.createElement("div",{className:e.root},i.a.createElement("div",{className:e.gridContainer},i.a.createElement("div",{className:e.introBox},i.a.createElement(h.c,{variant:"outlined",className:e.paper},i.a.createElement(y.a,{variant:"h5",className:e.title},f),i.a.createElement(y.a,{variant:"body2"},"Built according to an open standard, the Zodiac collection of tools are mods that support, expand, and transform how organizations operate. Learn more about Zodiac in"," ",i.a.createElement("a",{href:"https://gnosisguild.mirror.xyz/OuhG5s2X5uSVBx1EK4tKPhnUc91Wh9YM0fwSnC8UNcg",target:"_blank",rel:"noopener noreferrer",className:e.link},"this article")," ","and about Gnosis Safe modules more generally in"," ",i.a.createElement("a",{href:"https://help.gnosis-safe.io/en/articles/4934378-what-is-a-module",target:"_blank",rel:"noopener noreferrer",className:e.link},"this article"),"."))),i.a.createElement(uc,{title:"Bridge Module",description:"Enables an address on one chain to control an avatar on another chain using an Arbitrary Message Bridge (AMB)",icon:"bridge",onClick:function(){return u(Fe.BRIDGE)},className:e.firstModule,available:!!d[M.d.BRIDGE]}),i.a.createElement(uc,{title:"Delay Modifier",description:"Enables a time delay between when a module initiates a transaction and when it can be executed",icon:"delay",onClick:function(){return u(Fe.DELAY)},available:!!d[M.d.DELAY]}),i.a.createElement(uc,{title:"Exit Module",description:"Enables participants to redeem a designated token for a proportional share of this account\u2019digital assets",icon:"exit",onClick:function(){return u(Fe.EXIT)},available:!!d[M.d.EXIT_ERC20]}),i.a.createElement(uc,{title:"Roles Modifier",description:"Allows avatars to enforce granular, role-based, permissions for attached modules",icon:"roles",onClick:function(){return u(Fe.ROLES_V2)},available:!!d[M.d.ROLES_V2]}),i.a.createElement(uc,{title:"Reality Module",description:"Enables on-chain execution based on the outcome of events reported by the Reality.eth oracle",icon:"reality",onClick:function(){return t(ea(!0))},available:[o.MAINNET,o.GOERLI].includes(a.chainId)}),i.a.createElement(uc,{title:"Reality Module",description:"Enables on-chain execution based on the outcome of events reported by the Reality.eth oracle",icon:"reality",onClick:function(){return u(Fe.REALITY_ETH)},available:[o.MAINNET,o.GOERLI].includes(a.chainId)}),i.a.createElement(uc,{title:"Kleros Snapshot Module",description:"Execute transactions for successful Snapshot proposals using Reality.eth, secured by Kleros.",icon:"reality",onClick:function(){return u(Fe.KLEROS_REALITY)},available:fi.includes(a.chainId)}),i.a.createElement(uc,{title:"Tellor Module",description:"Enables on-chain execution of successful Snapshot proposals reported by the Tellor oracle",icon:"tellor",onClick:function(){return u(Fe.TELLOR)},available:!!d[M.d.TELLOR]}),i.a.createElement(uc,{title:"UMA oSnap Module",description:"Enables on-chain execution of successful Snapshot proposals utilizing UMA's optimistic oracle.",icon:"optimisticGov",onClick:function(){return u(Fe.OPTIMISTIC_GOVERNOR)},available:!0}),i.a.createElement(uc,{title:"Governor Module",description:"Enables an Open Zeppelin Governor contract as a module.",icon:"ozGov",onClick:function(){return t(ta(!0))},available:!!d[M.d.OZ_GOVERNOR]}),i.a.createElement(uc,{title:"Connext Module",description:"Enables an address on one chain to control an avatar on another chain using Connext as the messaging layer.",icon:"connext",onClick:function(){return u(Fe.CONNEXT)},available:!!d[M.d.CONNEXT]}),i.a.createElement(uc,{title:"Roles Modifier v1",description:"Legacy version of the Roles Modifier",icon:"roles",deprecated:!0,onClick:function(){return u(Fe.ROLES_V1)},available:!!d[M.d.ROLES_V1]}),i.a.createElement(uc,{title:"Custom Module",description:"Enable a custom contract as a module",icon:"custom",onClick:function(){return u(Fe.UNKNOWN)},available:!0})),i.a.createElement(jl,{selected:s,onClose:function(){return u(void 0)},onSubmit:function(){t(Kt(a)),t($t(!0))}}))},Sl=Object(g.a)((function(e){return{content:{padding:e.spacing(2.5),marginTop:e.spacing(3)}}})),Nl=function(e){var t=e.address,a=e.abi,n=Sl();return i.a.createElement(i.a.Fragment,null,i.a.createElement(Jo,{value:"read",disabled:!0}),i.a.createElement(h.c,{borderStyle:"double",className:n.content},i.a.createElement(Oo,{preview:!0,address:t,abi:a})))},Il=Object(g.a)((function(e){return{root:{padding:e.spacing(3)},paper:{padding:e.spacing(2.5),maxWidth:500},title:{marginBottom:e.spacing(2)},header:{display:"grid",gridTemplateColumns:"50px auto",gridGap:e.spacing(2),alignItems:"center",marginBottom:e.spacing(3)},addressText:{margin:e.spacing(0,2,0,3),fontWeight:"bold"},icon:{marginLeft:"16px"},buttons:{marginTop:e.spacing(3),opacity:.5}}}));function Tl(){var e=ga(Ht);if(!e)return null;var t=Ze(e.module);return t&&t.abi?i.a.createElement(Nl,{address:e.address,abi:t.abi}):null}var Al=function(){var e=Il(),t=1===ga(Vt);return i.a.createElement("div",{className:e.root},i.a.createElement("div",{className:e.header},i.a.createElement(xa.a,{variant:"circle",width:50,height:50}),i.a.createElement(xa.a,{variant:"rect",width:380,height:20})),t?i.a.createElement(Tl,null):i.a.createElement(h.c,{borderStyle:"double",className:e.paper},i.a.createElement(y.a,{variant:"h5",className:e.title},"Waiting on module approval"),i.a.createElement(y.a,null,"Once this module transaction has been approved by the other signers, you will be able to read and write to it.")))},Rl=a(1720),Ml=a(711),Bl=a(518),Dl=a(706),Ll=a(1721),Pl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{padding:"9px 8px",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}}}})),Fl=function(e){var t=e.data,a=e.setData,n=Pl(),r=1===Object(p.useSafeAppsSDK)().safe.chainId?Ql:Jl,o=Object(c.useState)(""),l=Object(x.a)(o,2),s=l[0],u=l[1];Object(c.useEffect)((function(){if(t&&r.length&&""===s){var e=r.filter((function(e){return e.label.includes(t.instanceAddress)}));u(e[0].value)}}),[t,r,s]);var d=function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}},f=function(e){return t[e]};return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Oracle Instance")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"The oracle instance sets the appropriate bond token. It's recommended to use the default (ETH) oracle instance unless you have a specific reason to use something like a native token which can potentially be more prone to price manipulation.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(al,{value:s,options:r,disableUnderline:!0,label:"Select oracle:",onChange:function(e){!function(e){if("custom"!==e){var t=e.substr(e.indexOf("-")+1),a=e.substr(0,e.indexOf("-"));u(e),d("instanceAddress")(t),d("instanceType")(a)}else d("instanceType")(e)}(e.target.value)}})),"custom"===f("instanceType")&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",spacing:1},i.a.createElement(q.a,{item:!0,sm:10},i.a.createElement(h.e,{label:"Contract Address",value:f("instanceAddress"),borderStyle:"double",className:n.input,onChange:function(e){return d("instanceAddress")(e.target.value)}})),i.a.createElement(q.a,{item:!0,sm:2},i.a.createElement(y.a,{style:{marginTop:15}},"WEENUS")))))},Ul=function(e,t,a){var n=parseInt(t),r=parseInt(a);switch(e){case"timeout":if(n<86400)return!1;break;case"cooldown":if(n<=0)return!1;break;case"expiration":if(0===n)return!0;if(a&&n=86400&&a<172800)return!1;break;case"cooldown":if(a>=0&&a<172800)return!1;break;case"expiration":if(0===a)return!1;if(a>=86400&&a<432e3)return!1}return!0},Hl=Object(g.a)((function(){return{errorIcon:{fill:"rgba(244, 67, 54, 1)"},warningIcon:{fill:h.f.tan[800]},message:{fontSize:12,color:"rgba(244, 67, 54, 1)"},warningMessage:{fontSize:12,color:h.f.tan[800]}}})),_l=function(e){var t=e.type,a=e.message,n=Hl();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},"error"===t&&i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:n.errorIcon})," "),"warning"===t&&i.a.createElement(q.a,{item:!0},i.a.createElement(Do.a,{className:n.warningIcon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:"error"===t?n.message:n.warningMessage},a)))},Gl=function(e){var t=e.type,a=e.delayValue,n=e.dependsDelayValue,r=Ul("timeout",parseInt(a)),o=Ul("cooldown",parseInt(a)),l=Ul("expiration",parseInt(a),n),s=Vl("timeout",parseInt(a)),u=Vl("cooldown",parseInt(a)),d=Vl("expiration",parseInt(a)),f=Object(c.useState)(void 0),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(void 0),h=Object(x.a)(g,2),E=h[0],v=h[1],y=Object(c.useState)(void 0),O=Object(x.a)(y,2),w=O[0],j=O[1];return Object(c.useEffect)((function(){return r?s?void b(void 0):b({type:"warning",message:"We highly recommend that your timeout delay exceeds 48 hours."}):b({type:"error",message:"Your timeout delay must exceed 24 hours."})}),[r,s]),Object(c.useEffect)((function(){return o?u?void v(void 0):v({type:"warning",message:"We highly recommend that your cooldown delay exceeds 48 hours."}):v({type:"error",message:"Your cooldown delay must exceed 0"})}),[o,u]),Object(c.useEffect)((function(){return l?d?void j(void 0):j({type:"warning",message:"We highly recommend that your expiration delay exceeds cooldown + 5 days."}):j({type:"error",message:"Your expiration delay must exceeds cooldown + 1 days."})}),[l,d]),i.a.createElement(c.Fragment,null,"timeout"===t&&p&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:p.type,message:p.message})),"cooldown"===t&&E&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:E.type,message:E.message})),"expiration"===t&&w&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:w.type,message:w.message})))},Wl=Object(g.a)((function(){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"}}})),zl=function(e){var t=e.data,a=e.setData,n=Wl(),r=function(e){return t[e]},o=r("timeout"),c=r("cooldown"),l=r("expiration"),s=Ul("timeout",o),u=Ul("cooldown",c),d=Ul("expiration",l,c);return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Delay Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"These Parameters are very important for your DAO's security and should be considered carefully. Allowing enough time in these configurations will enable the safe to have a final chance to veto or circumvent any potential malicious proposals that have snuck through.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:6,alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:s?"secondary":"error",alertType:s?void 0:"error",label:"Timeout",tooltipMsg:"Duration that answers can be submitted to the oracle (resets when a new answer is submitted)",valueUnit:r("timeoutUnit"),value:o,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{timeout:e,timeoutUnit:n}))}})),i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:u?"secondary":"error",alertType:u?void 0:"error",label:"Cooldown",tooltipMsg:"Duration required before the transaction can be executed (after the timeout has expired).",valueUnit:r("cooldownUnit"),value:c,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{cooldown:e,cooldownUnit:n}))}})),i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:d?"secondary":"error",alertType:d?void 0:"error",label:"Expiration",tooltipMsg:"Duration that a transaction is valid in seconds (or 0 if valid forever) after the cooldown (note this applies to all proposals on this module).",valueUnit:r("expirationUnit"),value:null!==l&&void 0!==l?l:0,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{expiration:e,expirationUnit:n}))}})))),i.a.createElement(Gl,{type:"timeout",delayValue:parseInt(o)}),i.a.createElement(Gl,{type:"cooldown",delayValue:parseInt(c)}),i.a.createElement(Gl,{type:"expiration",delayValue:parseInt(l),dependsDelayValue:parseInt(c)}))},Kl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},error:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}}}})),Yl=function(e){var t=e.data,a=e.setData,n=Kl(),r=t["bond"];return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Bond")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"Minimum bond required for an answer to be accepted. New answers must be submitted with double the previous bond. For more on why a bond is required in an escalation-game-based oracle, read more in the"," ",i.a.createElement(Ma.a,{underline:"always",href:"http://reality.eth.link/app/docs/html/whitepaper.html",target:"_blank",color:"inherit"},"Reality.eth whitepaper."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Bond",color:"secondary",borderStyle:"double",className:r<.1?n.error:n.input,prefix:"ETH",value:r,onChange:function(e){return function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}}("bond")(e.target.value)}})),r<.1&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:"warning",message:"We highly recommend that your bond exceeds 0.1 ETH."})))},Zl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"}}})),ql=function(e){var t,a=e.data,n=e.setData,r=Zl();return i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Arbitration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"An arbitrator is responsible for providing a final answer to a question when there is a dispute, in exchange for a fee. In most cases, the bond escalation-game eliminates the need for this. However, if you feel it's necessary to include a backup arbitration strategy incase of a dispute, you can select one from below. Read more in the"," ",i.a.createElement(Ma.a,{underline:"always",href:"https://reality.eth.link/app/docs/html/arbitrators.html",target:"_blank",color:"inherit"},"Reality.eth arbitrators documentation"),".")))),i.a.createElement(q.a,{item:!0},i.a.createElement(al,{value:(t="arbitratorOption",a[t]),options:[{label:"No arbitration (highest bond wins)",value:oe.NO_ARBITRATOR},{label:"Kleros",value:oe.KLEROS}],disableUnderline:!0,label:"Arbitrator:",onChange:function(e){var t=e.target;return function(e){return function(t){return n(Object(N.a)(Object(N.a)({},a),{},Object(P.a)({},e,t)))}}("arbitratorOption")(t.value)}})))},Xl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},icon:{fill:"white",width:"20px"},divider:{marginTop:8,marginBottom:8},warningModal:{maxWidth:650},errorPaperContainer:{width:"100%",padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)",border:0,borderRadius:4,display:"inline-block","& .MuiTypography-root":{fontFamily:"Roboto Mono"}}}})),Ql=[{label:"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c",value:"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c"},{label:"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9",value:"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9"}],Jl=[{label:"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f",value:"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f"}],$l=function(e){var t=e.handleBack,a=e.handleNext,n=e.setupData,r=Xl(),o=1===Object(p.useSafeAppsSDK)().safe.chainId?Ql:Jl,l=Object(c.useState)(!1),s=Object(x.a)(l,2),u=s[0],d=s[1];if(null==(null===n||void 0===n?void 0:n.proposal.ensName))throw new Error("ENS name is not set");var f=Object(c.useState)({templateType:"default",language:"english",category:"DAO proposal",templateQuestion:rl(null===n||void 0===n?void 0:n.proposal.ensName)}),m=Object(x.a)(f,2),b=m[0],g=m[1],E=Object(c.useState)({instanceAddress:o[0].value.substr(o[0].value.indexOf("-")+1),instanceType:o[0].value.substr(0,o[0].value.indexOf("-"))}),v=Object(x.a)(E,2),w=v[0],j=v[1],C=Object(c.useState)({timeout:172800,timeoutUnit:"days",cooldown:172800,cooldownUnit:"days",expiration:604800,expirationUnit:"days"}),k=Object(x.a)(C,2),S=k[0],N=k[1],I=Object(c.useState)({bond:.1}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=S.timeout,B=S.cooldown,D=S.expiration,L=A.bond,P=Ul("timeout",M),F=Ul("cooldown",B),U=Ul("expiration",D,B),V=Vl("timeout",M),H=Vl("cooldown",B),_=Vl("expiration",D),G=Object(c.useState)({arbitratorOption:oe.NO_ARBITRATOR}),W=Object(x.a)(G,2),z=W[0],K=W[1],Y=function(){return{templateData:b,instanceData:w,delayData:S,bondData:A,arbitratorData:z}};if(Object(c.useEffect)((function(){if(n&&n.oracle){var e=n.oracle,t=e.bondData,a=e.delayData,r=e.instanceData,o=e.templateData,c=e.arbitratorData;R(t),N(a),j(r),g(o),K(c)}}),[n]),null==(null===n||void 0===n?void 0:n.proposal.ensName))throw new Error("The ENS name is not available, it needs to already be in the setupData, before initiating this step.");return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Set up the Oracle")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Now, it's time to set up the oracle for your reality module. The oracle ensures the results of proposals are brought accurately on-chain. The Reality.eth oracle uses a mechanism known as the"," ",i.a.createElement(Xa,{underline:"always",href:"https://reality.eth.limo/app/docs/html/whitepaper.html",target:"_blank",color:"inherit"},"escalation game")," ","to generate correct answers that can be used as inputs for smart contracts. The following parameters are very important for your DAO's security and should be considered carefully.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(sl,{data:b,setData:g,ensName:null===n||void 0===n?void 0:n.proposal.ensName})),i.a.createElement(q.a,{item:!0},i.a.createElement(Fl,{data:w,setData:j})),i.a.createElement(q.a,{item:!0},i.a.createElement(zl,{data:S,setData:N})),i.a.createElement(q.a,{item:!0},i.a.createElement(Yl,{data:A,setData:R})),i.a.createElement(q.a,{item:!0},i.a.createElement(ql,{data:z,setData:K})),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return t(Y())}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:[P,F,U].includes(!1),onClick:function(){if([V,H,_].includes(!1)||L<.1)return d(!0);a(Y())}},"Next"))))),i.a.createElement(h.b,{className:r.warningModal,open:u,isOpen:u,onClose:function(){return d(!u)},children:i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:r.icon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4"},"Security Risk Detected")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"The following security risks have been detected. We highly recommend that you resolve them before moving forward, as these can leave to loss of funds.")),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:r.errorPaperContainer},i.a.createElement(Gl,{type:"timeout",delayValue:M}),i.a.createElement(Gl,{type:"cooldown",delayValue:B}),i.a.createElement(Gl,{type:"expiration",delayValue:D,dependsDelayValue:B}),L<.1&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:"warning",message:"We highly recommend that your bond exceeds 0.1 ETH."})))),i.a.createElement(q.a,{item:!0,className:r.divider},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,alignItems:"center",justifyContent:"center",spacing:3},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",onClick:function(){return a(Y())}},"Proceed")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",onClick:function(){return d(!1)}},"Resolve (Recommended)")))))}))},es=Object(g.a)((function(e){return{icon:{fill:"white",width:"20px"},paperContainer:{padding:e.spacing(2),background:"rgba(244, 67, 54, 0.1)",border:"1px solid rgba(244, 67, 54, 0.3)","&, &:before, &:after":{border:"1px solid rgba(244, 67, 54, 0.3)"}},addressPaperContainer:{width:"100%",padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)",border:0,borderRadius:4,display:"inline-block","& .MuiTypography-root":{fontFamily:"Roboto Mono"}}}})),ts=function(e){var t=e.title,a=e.type,n=e.address,r=es();return i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:r.icon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4"},t)))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"controller"===a&&"The safe you are currently using with Zodiac is not the controller of the ENS you've entered. Try one of the following: ","owner"===a&&"The ENS that you've entered is not owned by a safe. This gives unilateral control to the individual with this address: ","safesnap"===a&&"The Snapshot space has already installed the Safesnap plugin.","snapshot"===a&&t.includes("Invalid")&&"The current snapshot settings file is invalid. Check the browser console for validation details. The schema for validating the settings file can be found","snapshot"===a&&t.includes("Invalid")&&i.a.createElement(i.a.Fragment,null," ",i.a.createElement(Xa,{underline:"always",href:"https://github.com/snapshot-labs/snapshot.js/blob/master/src/schemas/space.json",target:"_blank",color:"inherit"},"here.")),"snapshot"===a&&!t.includes("Invalid")&&"The ENS you've entered is not setup with a Snapshot space. To setup a snapshot space with this ENS, follow the guide","snapshot"===a&&!t.includes("Invalid")&&i.a.createElement(i.a.Fragment,null," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.snapshot.org/spaces/create",target:"_blank",color:"inherit"},"here.")))),n&&i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"double",className:r.paperContainer},i.a.createElement(h.c,{borderStyle:"single",className:r.addressPaperContainer},i.a.createElement(y.a,{variant:"body2"},n)))),["controller","owner"].includes(a)&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"controller"===a&&"- Check that your ENS is typed correctly.","owner"===a&&"We highly recommend transferring the ENS to a multisig safe before continuing.")),"controller"===a&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"- Update your ENS controller settings via the"," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.ens.domains/contract-api-reference/.eth-permanent-registrar/controller",target:"_blank",color:"inherit"},"ENS."))))},as=Object(g.a)((function(e){return{message:{fontSize:12,color:"rgba(244, 67, 54, 1)"},messageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer"},errorIcon:{fill:"rgba(244, 67, 54, 1)",width:"20px"},detailsContainer:{width:"95%"},messageContainer:{width:"85%"}}})),ns=function(e){var t=e.status,a=e.message,n=e.type,r=e.address,o=as(),l=Object(c.useState)(!1),s=Object(x.a)(l,2),u=s[0],d=s[1],f=function(){switch(n){case"controller":return"Safe not controller of ENS";case"owner":return"Security Risk Detected";case"snapshot":return(null===a||void 0===a?void 0:a.includes("invalid"))?"Invalid Snapshot settings file":"Snapshot space not found";case"safesnap":return"Safesnap plugin is already installed";default:return""}}();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},"error"===t&&i.a.createElement(Mo.a,{className:o.errorIcon}),"warning"===t&&i.a.createElement(dl.a,{className:o.errorIcon})),i.a.createElement(q.a,{item:!0,className:o.detailsContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0,className:o.messageContainer},i.a.createElement(y.a,{className:o.message},a)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:o.messageDetails,onClick:function(){return d(!u)}},"Details")))),i.a.createElement(h.b,{open:u,isOpen:u,onClose:function(){return d(!u)},children:i.a.createElement(ts,{title:f,type:n,address:r})}))},rs=function(e,t,a,n,r,o,c){if(!t){if("snapshot"===e&&!r)return"error";if("snapshot"===e&&!o)return"error";if("controller"===e&&!a)return"error";if("safesnap"===e&&c)return"error";if("owner"===e&&!n)return"warning"}return null},os=function(e,t,a,n,r,o){return"snapshot"!==e||n?"snapshot"!==e||r?"controller"!==e||t?"owner"!==e||a?"safesnap"===e&&o?"The plugin is already installed on the Snapshot space.":null:"The safe is not the owner of the ENS name. We highly recommend transferring the ENS to this safe or enter a different ENS before continuing.":"The safe must be the controller of the ENS name.":"Your snapshot settings file is invalid.":"The ENS name should have a Snapshot space created."},cs=a(265),is=a.n(cs),ls=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},doneIcon:{marginRight:4,fill:"#A8E07E",width:"16px"},errorIcon:{marginRight:4,fill:"rgba(244, 67, 54, 1)",width:"16px"},loadingContainer:{marginRight:4,padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:14,width:14,border:"1px solid ".concat(h.f.tan[300])},spinner:{width:"8px !important",height:"8px !important",color:"".concat(h.f.tan[300]," !important")},loading:{width:"15px !important",height:"15px !important",marginRight:8},radio:{marginLeft:-2,padding:2,"& ~ .MuiFormControlLabel-label":{fontSize:12,marginLeft:4},"&$checked":{color:h.f.tan[1e3]}},checked:{},textSubdued:{color:"rgba(255 255 255 / 70%)"},textFieldSmall:{"& .MuiFormLabel-root":{fontSize:12}},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}},errorContainer:{margin:8,display:"flex",alignItems:"center"}}})),ss=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=dr(),o=r.safe,l=r.provider,s=ls(),u=Object(c.useState)(""),d=Object(x.a)(u,2),f=d[0],p=d[1],b=Object(c.useState)(""),g=Object(x.a)(b,2),E=g[0],v=g[1],w=Object(c.useState)(!1),j=Object(x.a)(w,2),S=j[0],N=j[1],I=Object(c.useState)(!1),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object(c.useState)(!1),B=Object(x.a)(M,2),D=B[0],L=B[1],P=Object(c.useState)(!1),F=Object(x.a)(P,2),U=F[0],V=F[1],H=Object(c.useState)(!1),_=Object(x.a)(H,2),G=_[0],W=_[1],z=Object(c.useState)(!1),K=Object(x.a)(z,2),Y=K[0],Z=K[1],X=Object(c.useState)(!1),Q=Object(x.a)(X,2),$=Q[0],ee=Q[1];Object(c.useEffect)((function(){l&&n&&n.proposal&&p(n.proposal.ensName)}),[]),Object(c.useEffect)((function(){f&&(f.includes(".eth")?(ee(!0),Z(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,te();case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()()):(ee(!1),L(!1),N(!1)))}),[f]);var te=function(){var e=Object(k.a)(C.a.mark((function e(){var t,a,n,r,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,l.resolveName(f);case 2:if(!(t=e.sent)){e.next=26;break}return e.next=6,Hi(f,o.chainId);case 6:return a=e.sent,n=_i(a),e.next=10,Di(l,f,o.safeAddress);case 10:return r=e.sent,e.next=13,Pi(l,f,o.safeAddress);case 13:return c=e.sent,(i=null===a||void 0===a?void 0:a.plugins)&&R(!!i.safeSnap),!0!==n&&(console.log("The current snapshot space is not valid. Valid snapshot space schema. Errors:"),console.log(JSON.stringify(_i(a),void 0,2))),V(!!a),W(!0===n),N(r),L(c),v(t),Z(!1),e.abrupt("return");case 26:return v(""),Z(!1),N(!1),L(!1),V(!1),W(!1),R(!1),e.abrupt("return");case 34:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),ae=function(){return{ensName:f}};return i.a.createElement(h.c,{borderStyle:"single",className:s.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Configure Proposal Space")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Add your preferred proposal type below to get started. If you're unsure, we recommend starting with Snapshot.")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Don't have a snapshot space setup yet?"," ",i.a.createElement(Xa,{underline:"always",href:Rn(o,"https://snapshot.org/#/setup?step=1"),target:"_blank",color:"inherit"},"Get started here."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Proposal Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:s.textSubdued},"Enter your snapshot space ENS domain below to get started. The Safe must be the controller of this ENS domain.")),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{value:f,onChange:function(e){var t,a=e.target;""===(t=a.value)?(L(!1),N(!1),V(!1),W(!1),p("")):p(t)},label:"Enter the Snapshot ENS name.",placeholder:"ex: gnosis.eth",borderStyle:"double",className:"".concat(s.textFieldSmall," ").concat(!f.includes(".eth")||Y||U&&D&&S?s.input:s.inputError),rightIcon:i.a.createElement(i.a.Fragment,null,Y&&i.a.createElement(J.a,{className:s.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:s.spinner})),f.includes(".eth")&&!Y&&(!U||!D||!S)&&i.a.createElement(Mo.a,{className:s.errorIcon}),f.includes(".eth")&&!Y&&U&&D&&S&&i.a.createElement(is.a,{className:s.doneIcon}))}),i.a.createElement("br",null),i.a.createElement("br",null),$&&i.a.createElement(i.a.Fragment,null,i.a.createElement(ns,{type:"snapshot",status:rs("snapshot",Y,!1,!1,U,G,!1),message:os("snapshot",!1,!1,U,G,!1)}),i.a.createElement(ns,{type:"safesnap",status:rs("safesnap",Y,!1,!1,!1,!1,A),message:os("safesnap",!1,!1,!1,!1,A)}),i.a.createElement(ns,{type:"controller",status:rs("controller",Y,D,!1,!1,!1,!1),message:os("controller",D,!1,!1,!1,!1)}),i.a.createElement(ns,{type:"owner",status:rs("owner",Y,!1,S,!1,!1,!1),message:os("owner",!1,S,!1,!1,!1),address:E}))))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(ae())}},"Cancel")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:!D||A,onClick:function(){return t(ae())}},"Next"))))))},us=Object(g.a)((function(e){return{circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:25,width:25,border:"1px solid ".concat(h.f.tan[300]),background:h.f.blue[500]},label:{display:"inline",fontFamily:"Roboto Mono",cursor:"pointer","&:hover":{textDecoration:"underline"}}}})),ds=function(e){var t=e.label,a=e.number,n=e.disabled,r=e.onClick,o=us();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center",onClick:function(){!n&&r()}},i.a.createElement(q.a,{item:!0},i.a.createElement(J.a,{className:o.circle},i.a.createElement(y.a,null,a))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:o.label},t)))},fs=a(383),ms=a.n(fs),ps=a(753),bs=a.n(ps),gs=a(752),hs=a.n(gs),Es=a(382),vs=a.n(Es),ys=Object(g.a)((function(e){return{message:{fontSize:"0.9rem"},messageError:{fontSize:"0.9rem",color:"rgba(244, 67, 54, 1)"},circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,background:h.f.tan[1e3]},loadingContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid ".concat(h.f.tan[300])},errorContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.3)"},errorIcon:{width:"12px",height:"12px",color:"#F44336"},loading:{width:"12px !important",height:"12px !important",color:"".concat(h.f.tan[300]," !important")},doneIcon:{fill:"black",width:"16px"}}})),Os=function(e){var t=e.statusLog,a=ys();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},t.map((function(e,n){return i.a.createElement(q.a,{item:!0,xs:12,key:"status-".concat(n)},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center",key:n},i.a.createElement(q.a,{item:!0},t.length>n+1&&!e.error&&i.a.createElement(J.a,{className:a.circle},i.a.createElement(is.a,{className:a.doneIcon})),t.length===n+1&&!e.error&&i.a.createElement(J.a,{className:a.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:a.loading})),t.length===n+1&&e.error&&i.a.createElement(J.a,{className:a.errorContainer},i.a.createElement(vs.a,{className:a.errorIcon}))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:e.error?a.messageError:a.message},e.msg))))})))},xs=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},paperTemplateContainer:{marginTop:4,padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)"},textSubdued:{color:"rgba(255 255 255 / 70%)"},icon:{fill:"white",cursor:"pointer"},collapse:{textDecoration:"underline",cursor:"pointer"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},textarea:{"& .MuiInputBase-root":{padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},link:{fontFamily:"Roboto Mono",fontSize:12,textDecoration:"underline",fontWeight:"bold"},label:{fontFamily:"Roboto Mono",fontSize:12,fontWeight:"bold"},loading:{width:"15px !important",height:"15px !important"}}})),ws=[{label:"Proposal",number:1,section:0},{label:"Oracle",number:2,section:1},{label:"Monitoring",number:3,section:2}],js=i.a.createElement(y.a,{variant:"body2"},"This will add a time delay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours)."),Cs=function(e){var t=e.handleBack,a=e.handleNext,n=e.goToStep,r=e.delayModules,l=e.setupData,s=e.loading,u=e.statusLog,d=xs(),f=Object(p.useSafeAppsSDK)().safe,b=Object(c.useState)(),g=Object(x.a)(b,2),E=g[0],v=g[1],w=Object(c.useState)(!1),j=Object(x.a)(w,2),C=j[0],k=j[1],S=Object(c.useState)(void 0),N=Object(x.a)(S,2),I=N[0],A=N[1],R=Object(c.useState)(1===r.length?r[0].address:""),M=Object(x.a)(R,2),B=M[0],D=M[1],L=l&&l.monitoring;return Object(c.useEffect)((function(){var e,t;l&&l.proposal&&v((e=f.chainId,t=l.proposal.ensName,(e===o.GOERLI?"https://testnet.snapshot.org":"https://snapshot.org")+"/#/".concat(t))),l&&l.oracle&&A(l.oracle)}),[l]),i.a.createElement(h.c,{borderStyle:"single",className:d.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:d.container},!C&&i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:d.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Review")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Here is an overview of your reality module configuration. Please review carefully. Once you've confirmed that the details are correct, you can submit the transaction which will add the reality module to this safe, and automatically integrate the SafeSnap plugin with the snapshot space you've include.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),ws.map((function(e){return i.a.createElement(i.a.Fragment,{key:e.label},i.a.createElement(q.a,{item:!0},i.a.createElement(ds,{label:e.label,number:e.number,disabled:s,onClick:function(){return n(e.section)}})),"Proposal"===e.label&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Snapshot Space:"),i.a.createElement(Ma.a,{color:"inherit",href:E,target:"_blank",className:d.link},E)),"Oracle"===e.label&&I&&l&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Template question preview:"),i.a.createElement(h.c,{className:d.paperTemplateContainer},i.a.createElement(y.a,null,l.oracle.templateData.templateQuestion))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Oracle Address:"),i.a.createElement(Ma.a,{color:"inherit",href:"".concat(H[f.chainId],"/search?f=0&q=").concat(I.instanceData.instanceAddress),target:"_blank",className:d.link},I.instanceData.instanceAddress)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Timeout:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.timeout).div(Lo[I.delayData.timeoutUnit]).toString()," ",I.delayData.timeoutUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Cooldown:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.cooldown).div(Lo[I.delayData.cooldownUnit]).toString()," ",I.delayData.cooldownUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Expiration:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.expiration).div(Lo[I.delayData.expirationUnit]).toString()," ",I.delayData.expirationUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Bond:"),i.a.createElement(y.a,{className:d.label},I.bondData.bond," ETH")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Arbitrator:"),i.a.createElement(y.a,{className:d.label},0===I.arbitratorData.arbitratorOption&&"No arbitration (highest bond wins)",1===I.arbitratorData.arbitratorOption&&"Kleros")))),"Monitoring"===e.label&&L&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"API key/secret:"),i.a.createElement(y.a,{className:d.label},"Valid")),L.email.length>0&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Emails:"),L.email.map((function(e,t){return i.a.createElement(y.a,{className:d.label,key:t},"- ",e)}))),""!==L.discordKey&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Discord:"),i.a.createElement(y.a,{className:d.label},L.discordKey)),""!==L.telegram.botToken&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Telegram:"),i.a.createElement(y.a,{className:d.label},"Bot token: ",L.telegram.botToken),i.a.createElement(y.a,{className:d.label},"Chat ID: ",L.telegram.chatId)),""!==L.slackKey&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Slack:"),i.a.createElement(y.a,{className:d.label},L.slackKey)))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)))})),r.length>=1&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:js,modules:r,value:B,onChange:function(e){return D(e)},type:Fe.DELAY}))))),u.length>0&&i.a.createElement(q.a,{item:!0,onClick:function(){return k(!C)}},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},C?i.a.createElement(bs.a,{className:d.icon}):i.a.createElement(hs.a,{className:d.icon})),i.a.createElement(q.a,{item:!0,className:d.collapse},i.a.createElement(y.a,null,C?"Show More":"Show Less")))),u.length>0&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:d.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Setting up Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(Os,{statusLog:u})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:t,disabled:s},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",startIcon:s?i.a.createElement(m.Loader,{className:d.loading,size:"sm",color:"background"}):i.a.createElement(ms.a,null),disabled:s,onClick:function(){k(!0),a(l)}},"Submit"))))))},ks=a(755),Ss=Object(g.a)((function(e){return{paperContainer:{background:"rgba(0, 0, 0, 0.2)"},message:{fontSize:12,color:"rgba(244, 67, 54, 1)"}}})),Ns={control:function(e,t){return Object(N.a)(Object(N.a)({},e),{},{background:"none",border:"none",fontFamily:"Roboto Mono !important",color:"yellow !important",boxShadow:(t.isFocused,null),"&:hover":{border:"none"}})},option:function(e){return Object(N.a)(Object(N.a)({},e),{},{color:"white",backgroundColor:"#101010",cursor:"pointer"})},menu:function(e){return Object(N.a)(Object(N.a)({},e),{},{borderRadius:0,backgroundColor:"#101010",marginTop:0})},menuList:function(e){return Object(N.a)(Object(N.a)({},e),{},{padding:0})},multiValue:function(e){return Object(N.a)(Object(N.a)({},e),{},{color:"white !important",background:h.f.tan[300],maxWidth:"calc(28% - 4px)","&:hover":{background:h.f.tan[300]},"& > div":{color:"white !important"},"& > div[role=button]:hover":{cursor:"pointer",color:"blue",background:h.f.tan[500]}})}},Is=function(e){var t=Ss();return i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{className:t.paperContainer,borderStyle:"double"},i.a.createElement(ks.a,Object.assign({},e,{isMulti:!0,styles:Ns,options:e.options,theme:function(e){return Object(N.a)(Object(N.a)({},e),{},{colors:Object(N.a)(Object(N.a)({},e.colors),{},{font:"#101010",primary25:"#101010",primary:"#101010",neutral80:"white"})})}})))),e.invalidText&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:t.message},e.invalidText)))},Ts=function(e){var t=Object(c.useRef)();return Object(c.useEffect)((function(){t.current=e}),[e]),t.current},As=Object(g.a)((function(e){return{message:{fontSize:"0.9rem"},messageError:{fontSize:"0.8rem",color:"rgba(244, 67, 54, 1)"},circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,background:h.f.tan[1e3]},loadingContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid ".concat(h.f.tan[300])},errorContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.3)"},errorIcon:{width:"12px",height:"12px",color:"#F44336"},loading:{width:"12px !important",height:"12px !important",color:"".concat(h.f.tan[300]," !important")},doneIcon:{fill:"black",width:"16px"}}})),Rs=function(e){var t=e.status,a=e.message,n=As();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},"success"===t&&i.a.createElement(J.a,{className:n.circle},i.a.createElement(is.a,{className:n.doneIcon})),"loading"===t&&i.a.createElement(J.a,{className:n.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:n.loading})),"error"===t&&i.a.createElement(J.a,{className:n.errorContainer},i.a.createElement(vs.a,{className:n.errorIcon}))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:"error"===t?n.messageError:n.message},a)))},Ms=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},textSubdued:{color:"rgba(255 255 255 / 70%)"},inputContainer:{width:"50%"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}},textarea:{"& .MuiInputBase-root":{padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},spinner:{width:"8px !important",height:"8px !important",color:"".concat(h.f.tan[300]," !important")}}})),Bs={apiKey:"",secretKey:"",email:[],discordKey:"",telegram:{botToken:"",chatId:""},slackKey:""},Ds=function(e){var t=e.handleBack,a=e.handleNext,n=e.setupData,r=Ms(),o=hl(),l=o.loading,s=o.execute,u=o.error,d=null===n||void 0===n?void 0:n.monitoring,f=Object(c.useState)(null!==d&&void 0!==d?d:Bs),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)([]),E=Object(x.a)(g,2),v=E[0],w=E[1],j=Object(c.useState)(!1),S=Object(x.a)(j,2),I=S[0],T=S[1],A=Object(c.useState)(!1),R=Object(x.a)(A,2),M=R[0],B=R[1],D=p.apiKey,L=p.secretKey,F=p.email,U=p.discordKey,V=p.slackKey,H=p.telegram,_=Ts(D),G=Ts(L);Object(c.useEffect)((function(){if(d&&d.email.length){var e=[];d.email.forEach((function(t){return e.push({label:t,value:t})})),w(e)}}),[d]),Object(c.useEffect)((function(){l||[D,L].includes("")||M||(B(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,s(D,L);case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()())}),[D,L,l,M,s]),Object(c.useEffect)((function(){_===D&&G===L||!M||B(!1)}),[D,L,_,G,M]);var W=function(e,t){if(e.preventDefault(),["chatId","botToken"].includes(t)){var a=Object(N.a)({},p.telegram),n=Object(N.a)(Object(N.a)({},a),{},Object(P.a)({},t,e.target.value));b(Object(N.a)(Object(N.a)({},p),{},{telegram:n}))}else b(Object(N.a)(Object(N.a)({},p),{},Object(P.a)({},t,e.target.value)))};return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Configure Monitoring")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Setting up an effective monitoring strategy is critical for the security of your safe. In order to set up the monitoring for this module, you'll need to first"," ",i.a.createElement(Xa,{underline:"always",href:"https://defender.openzeppelin.com/#/auth/sign-in",target:"_blank",color:"inherit"},"create an Open Zeppelin account."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"API Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Include the API Key and Secret Key from your Open Zeppelin account below. Follow the Open Zeppelin guide ","",i.a.createElement(Xa,{underline:"always",href:"https://docs.openzeppelin.com/defender/guide-factory#generate-api-key",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"API Key",placeholder:"0f9u8yuiahkjdh8qhiflahfjajdhafa",borderStyle:"double",value:p.apiKey,onChange:function(e){return W(e,"apiKey")},className:u?r.inputError:r.input})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"API Secret",placeholder:"hkjdh8qhiflahfjajdhafa0f9u8yuiahkjdh8qhiflahfjajdhafa",value:p.secretKey,onChange:function(e){return W(e,"secretKey")},borderStyle:"double",className:u?r.inputError:r.input})),i.a.createElement(q.a,{item:!0},i.a.createElement(Rs,{status:l?"loading":u?"error":u||"boolean"!==typeof u?null:"success",message:l?"Validating API credentials...":u?"The API credentials that you have provided are not valid. Please verify that you have the correct information.":u||"boolean"!==typeof u?null:"API credentials are valid."})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Email")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Add as many emails as you'd like.")),i.a.createElement(q.a,{item:!0},i.a.createElement(Is,{invalidText:I?"Please provide a valid email":void 0,onChange:function(e){return function(e){var t,a=null===(t=e[e.length-1])||void 0===t?void 0:t.value;!function(e){return/\S+@\S+\.\S+/.test(e)}(a)&&null!=a?T(!0):(T(!1),w(e),b(Object(N.a)(Object(N.a)({},p),{},{email:e.map((function(e){return e.value}))})))}(e)},value:v})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Discord")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Discord integration, include the Discord channel's url including key below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Discord Key",placeholder:"key",borderStyle:"double",className:r.input,value:p.discordKey,onChange:function(e){return W(e,"discordKey")}})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Telegram")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Telegram integration, include the telegram bot token and chat ID below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://core.telegram.org/bots#6-botfather",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"row",alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,className:r.inputContainer},i.a.createElement(h.e,{label:"Bot token",placeholder:"abc",borderStyle:"double",className:r.input,value:p.telegram.botToken,onChange:function(e){return W(e,"botToken")}})),i.a.createElement(q.a,{item:!0,className:r.inputContainer},i.a.createElement(h.e,{label:"Chat ID",placeholder:"123",borderStyle:"double",className:r.input,value:p.telegram.chatId,onChange:function(e){return W(e,"chatId")}})))))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Slack")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Slack integration, include the Slack channel's url including key below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.openzeppelin.com/defender/sentinel#notifications",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Slack Channel URL",placeholder:"https://slack.com/url/key",borderStyle:"double",className:r.input,value:p.slackKey,onChange:function(e){return W(e,"slackKey")}})))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return t(p)}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",type:"submit",disabled:function(){var e=H.botToken,t=H.chatId;return!(!l&&!u)||(""===e&&""!==t||""!==e&&""===t||""===e&&""===t&&""===U&&""===V&&0===F.length)}(),onClick:function(){return a(p)}},"Next"))))))},Ls=["proposal","oracle","monitoring","review"],Ps=Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},container:{display:"flex",flexDirection:"column"},tag:{background:e.palette.secondary.main},paperContainer:{padding:e.spacing(2)},paperTitle:{margin:0},step:{"& text":{fontFamily:"Roboto Mono"},"& .step-label":{textTransform:"capitalize",display:"inline",fontFamily:"Roboto Mono","&.clickable":{cursor:"pointer","&:hover":{textDecoration:"underline"}}}},stepperRoot:{backgroundColor:"transparent",border:"none",padding:e.spacing(0),"& .MuiStepIcon-active":{color:e.palette.secondary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"},"& .MuiStepIcon-completed":{background:e.palette.text.primary,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%",color:e.palette.secondary.main},"& .Mui-disabled .MuiStepIcon-root":{color:e.palette.primary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"}}}})),Fs=function(){var e=Ps(),t=dr(),a=t.sdk,n=t.safe,r=t.provider,o=ga(Dt),l=ba(),s=ga(Rt),u=Object(c.useState)(s.length),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)([]),b=Object(x.a)(p,2),g=b[0],E=b[1],v=Object(c.useState)(0),w=Object(x.a)(v,2),j=w[0],S=w[1],I=Object(c.useState)({proposal:!1,oracle:!1,monitoring:!1,review:!1}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object(c.useState)(!1),B=Object(x.a)(M,2),D=B[0],L=B[1],F=Object(c.useState)(),U=Object(x.a)(F,2),V=U[0],H=U[1],_=function(e,t,a){return function(n){S(e),R(Object(N.a)(Object(N.a)({},A),{},Object(P.a)({},t,a))),H(Object(N.a)(Object(N.a)({},V),{},Object(P.a)({},t,n)))}},G=function(){var e=Object(k.a)(C.a.mark((function e(t){var o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(o=[],L(!0),null!=V){e.next=5;break}throw L(!1),new Error("No setup data");case 5:return c=""!==t||null==t?n.safeAddress:t,i=function(e,t){if(null!=t)throw"OpenError"===t.name?o.push({error:!0,msg:t.toString()+"This error can be caused by add/track blockers. Please disable any blockers (for instance, the Brave Shield) and try again."}):o.push({error:!0,msg:t.toString()}),t;o.push({error:!1,msg:e}),E(o)},e.prev=7,e.next=10,Qi(r,a,n,c,V,i);case 10:e.next=16;break;case 12:e.prev=12,e.t0=e.catch(7),L(!1),console.error(e.t0);case 16:l(Kt(n)),l($t(!0));case 18:case"end":return e.stop()}}),e,null,[[7,12]])})));return function(t){return e.apply(this,arguments)}}();return Object(c.useEffect)((function(){D&&s.length>f&&(m(s.length),L(!1),l(ea(!1)))}),[l,D,f,s]),i.a.createElement("div",{className:e.root},i.a.createElement(q.a,{container:!0,spacing:2,className:e.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0},i.a.createElement(h.a,{icon:"reality",size:60})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h5"},"Reality Module"),i.a.createElement(mc,{className:e.tag,tags:["Stackable","From Gnosis Guild"]})))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{gutterBottom:!0},"Allows Reality.eth questions to execute a transaction when resolved."," ",i.a.createElement(Xa,{underline:"always",href:"https://zodiac.wiki/index.php/Category:Reality_Module",target:"_blank",color:"inherit"},"Read more here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:e.paperContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",style:{marginBottom:15}},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",gutterBottom:!0,className:e.paperTitle},"Add Reality Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"outlined",onClick:function(){return l(ea(!1))}},"Cancel"))),i.a.createElement(Ml.a,{activeStep:j,className:e.stepperRoot,orientation:"vertical"},Ls.map((function(t,a){return i.a.createElement(Bl.a,{key:t,className:e.step},i.a.createElement(Dl.a,{onClick:function(){return e=a,void(A[t]&&S(e));var e}},i.a.createElement(y.a,{variant:"h6",className:ja()(a<=j&&"clickable","step-label")},t)," "),i.a.createElement(Ll.a,null,"proposal"===t&&i.a.createElement(ss,{handleNext:_(a+1,t,!0),handleBack:function(){return l(ea(!1))},setupData:V}),"oracle"===t&&i.a.createElement($l,{handleNext:_(a+1,t,!0),handleBack:_(j-1,t,!1),setupData:V}),"monitoring"===t&&i.a.createElement(Ds,{handleNext:_(a+1,t,!0),handleBack:_(j-1,t,!1),setupData:V}),"review"===t&&i.a.createElement(Cs,{handleNext:G,handleBack:_(j-1,t,!1),goToStep:S,setupData:V,delayModules:o,loading:D,statusLog:g})))})))))))},Us=a(710),Vs=a(508),Hs=a(476),_s=["function getVotes(address account) external view returns (uint256)","function getPastVotes(address account, uint256 blockNumber) external view returns (uint256)","function getPastTotalSupply(uint256 blockNumber) external view returns (uint256)","function delegates(address account) external view returns (address)","function delegate(address delegatee) external","function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external"],Gs="0xD028d504316FEc029CFa36bdc3A8f053F6E5a6e4",Ws=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},radio:{marginLeft:-2,padding:2,"& ~ .MuiFormControlLabel-label":{fontSize:12,marginLeft:4},"&$checked":{color:h.f.tan[1e3]}},checked:{},errorColor:{color:"rgba(244, 67, 54, 1)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}}}})),zs={tokenAddress:void 0,tokenName:"",tokenSymbol:"",initialAmount:1e5,tokenConfiguration:"existingToken"},Ks=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=Ws(),o=n.token,l=Object(c.useState)(o),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=function(e){return function(){var t=Object(k.a)(C.a.mark((function t(a){var n;return C.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=new I.ethers.Contract(a,_s,e),t.prev=1,t.next=4,Promise.all([n.getVotes(Gs),n.getPastVotes(Gs,1234),n.getPastTotalSupply(1234),n.callStatic.delegates(Gs)]);case 4:n.functions.delegateBySig.name,t.next=11;break;case 7:return t.prev=7,t.t0=t.catch(1),console.log(t.t0),t.abrupt("return",!1);case 11:return t.abrupt("return",!0);case 12:case"end":return t.stop()}}),t,null,[[1,7]])})));return function(e){return t.apply(this,arguments)}}()}(dr().provider),E=u.tokenAddress,v=u.tokenName,w=u.tokenSymbol,j=u.tokenConfiguration,S=u.initialAmount,T=function(){return{tokenAddress:E,tokenName:v,tokenSymbol:w,tokenConfiguration:j,initialAmount:S}},A=function(e,t){d(Object(N.a)(Object(N.a)({},u),{},Object(P.a)({},t,e.target.value)))};Object(c.useEffect)((function(){[E].includes(void 0)||function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(e.t0=I.ethers.utils.isAddress(E),!e.t0){e.next=5;break}return e.next=4,g(E);case 4:e.t0=e.sent;case 5:if(!e.t0){e.next=9;break}b(!0),e.next=10;break;case 9:b(!1);case 10:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()()}),[E,g]);var R="existingToken"===j?!(p&&![E].includes("")):"ERC721"!==j&&"ERC20"!==j||!![v,w].includes("");return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Setup Token for Voting")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"The following token will enable members to vote on proposals with this governor contract. The token must be ERC20Votes compatible.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Token Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2"},"Do you have an existing token in your safe that you'd like to use as the token for voting in this contract?"),i.a.createElement(Us.a,{"aria-label":"Token Configuration",name:"Token Configuration",value:j,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{tokenConfiguration:e.target.value}))}},i.a.createElement(Vs.a,{value:"existingToken",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Existing Token"}),i.a.createElement(Vs.a,{value:"ERC20",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Deploy a new ERC20 for voting."}),i.a.createElement(Vs.a,{value:"ERC721",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Deploy a new ERC721 for voting."}))),"existingToken"===j&&i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Token Address",value:E,placeholder:"0xDf33060F476511F806C72719394da1Ad64",borderStyle:"double",className:[E].includes("")||[E].includes(void 0)||p?r.input:r.inputError,onChange:function(e){return A(e,"tokenAddress")}}),![E].includes(void 0)&&!p&&i.a.createElement(Hs.a,{className:r.errorColor},"Please provide a valid address")),("ERC20"===j||"ERC721"===j)&&i.a.createElement(c.Fragment,null,i.a.createElement(q.a,{item:!0,style:{width:"-webkit-fill-available"}},i.a.createElement(q.a,{container:!0,spacing:2,justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,xs:9},i.a.createElement(h.e,{label:"Token Name",value:v,placeholder:"MyToken",borderStyle:"double",className:r.input,onChange:function(e){return A(e,"tokenName")},tooltipMsg:"The same as collection name in OpenSea, e.g. Nouns"})),i.a.createElement(q.a,{item:!0,xs:3},i.a.createElement(h.e,{label:"Token Symbol",value:w,placeholder:"TKN",borderStyle:"double",className:r.input,onChange:function(e){return A(e,"tokenSymbol")},tooltipMsg:"e.g. LOOT"}))))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(T())}},"Cancel")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:R,onClick:function(){return t(T())}},"Next"))))))},Ys=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},icon:{fill:"white",cursor:"pointer"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},label:{fontFamily:"Roboto Mono, monospace",fontSize:12,fontWeight:"bold"},loading:{width:"15px !important",height:"15px !important"},value:{fontFamily:"Roboto Mono, monospace",fontWeight:"bold",color:"white"},underline:{textDecoration:"underline"}}})),Zs=[{label:"Token",number:1,section:0},{label:"Governor",number:2,section:1}],qs=function(e){var t=e.handleBack,a=e.handleNext,n=e.goToStep,r=e.setupData,o=e.loading,c=Ys(),l=null===r||void 0===r?void 0:r.token,s=null===r||void 0===r?void 0:r.governor,u=Object(p.useSafeAppsSDK)().safe;return i.a.createElement(h.c,{borderStyle:"single",className:c.paperContainer},i.a.createElement(q.a,{container:!0,spacing:3,className:c.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:c.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Review")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Please take a final look at your OZ Governor Module details.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),Zs.map((function(e){return i.a.createElement(i.a.Fragment,{key:e.label},i.a.createElement(q.a,{item:!0},i.a.createElement(ds,{label:e.label,number:e.number,disabled:o||"Governor"===e.label,onClick:function(){return n(e.section)}})),"Token"===e.label&&l&&i.a.createElement(i.a.Fragment,null,l.tokenAddress&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Token:"),i.a.createElement(Ma.a,{target:"_blank",href:"".concat(H[u.chainId],"/token/").concat(l.tokenAddress),className:c.value},l.tokenAddress)),l.tokenName&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Token Name:"),i.a.createElement(y.a,{className:c.value},l.tokenName)),l.tokenSymbol&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Token Symbol:"),i.a.createElement(y.a,{className:c.value},l.tokenSymbol))),"Governor"===e.label&&s&&i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Name:"),i.a.createElement(y.a,{className:c.value},s.daoName)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Delay:"),i.a.createElement(y.a,{className:c.value},s.votingDelayInBlocks," blocks")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Period:"),i.a.createElement(y.a,{className:c.value},s.votingPeriodInBlocks," blocks")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Proposal Threshold:"),i.a.createElement(y.a,{className:c.value},s.proposalThreshold,"%")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Quorum (%):"),i.a.createElement(y.a,{className:c.value},s.quorumPercent,"%"))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)))})),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:t,disabled:o},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",startIcon:o?i.a.createElement(m.Loader,{className:c.loading,size:"sm",color:"background"}):i.a.createElement(ms.a,null),onClick:function(){a(r)}},"Deploy and Enable Module"))))))};var Xs,Qs,Js,$s,eu,tu,au=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i,l){var s,u,d,f,m,p;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=a){e.next=2;break}throw new Error("No safe address provided");case 2:if(null!=n){e.next=4;break}throw new Error("No token address provided");case 4:if(null!=r){e.next=6;break}throw new Error("No name provided");case 6:if(null!=o){e.next=8;break}throw new Error("No voting delay provided");case 8:if(null!=c){e.next=10;break}throw new Error("No voting period provided");case 10:if(null!=i){e.next=12;break}throw new Error("No proposal threshold provided");case 12:if(null!=l){e.next=14;break}throw new Error("No quorum percent provided");case 14:if(!(l>100||l<0)){e.next=16;break}throw new Error("Quorum percent must be between 0 and 100");case 16:return s={values:[a,a,"0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761",n,r,o.toString(),c.toString(),i.toString(),l.toString(),"0"],types:["address","address","address","address","string","uint256","uint256","uint256","uint256","uint64"]},u=Date.now().toString(),e.next=20,t.getNetwork();case 20:return d=e.sent.chainId,f=Object(M.f)(M.d.OZ_GOVERNOR,s,t,d,u),m=f.transaction,p=f.expectedModuleAddress,e.abrupt("return",{txs:[Object(N.a)(Object(N.a)({},m),{},{value:m.value.toString()})],meta:{expectedAddress:p}});case 23:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c,i,l){return e.apply(this,arguments)}}(),nu=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=a){e.next=2;break}throw new Error("No safe address provided");case 2:if(null!=n){e.next=4;break}throw new Error("No token name provided");case 4:if(null!=r){e.next=6;break}throw new Error("No token symbol provided");case 6:if("ERC20"===o||"ERC721"===o){e.next=8;break}throw new Error("Invalid token kind");case 8:return c={values:[a,n,r],types:["address","string","string"]},i=Date.now().toString(),e.next=12,t.getNetwork();case 12:return l=e.sent.chainId,s=Object(M.f)("ERC20"===o?M.d.ERC20_VOTES:M.d.ERC721_VOTES,c,t,l,i),u=s.transaction,d=s.expectedModuleAddress,e.abrupt("return",{txs:[Object(N.a)(Object(N.a)({},u),{},{value:u.value.toString()})],meta:{expectedAddress:d}});case 15:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}(),ru=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i,l,s,u){var d,f,m,p,b,g,h,E;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=s||null!=u){e.next=4;break}throw new Error("No token address or create token args provided");case 4:if(null==s||null==u){e.next=6;break}throw new Error("Both token address and create token args provided");case 6:if(d=[],null==u){e.next=17;break}return e.next=10,nu(t,n,u.name,u.symbol,u.kind);case 10:if(f=e.sent,m=f.txs,p=f.meta,d.push.apply(d,Object(w.a)(m)),null!=(null===p||void 0===p?void 0:p.expectedAddress)){e.next=16;break}throw new Error("No expected address returned from token deployment");case 16:s=p.expectedAddress;case 17:if(null!=s){e.next=19;break}throw new Error("No token address provided. Should not be possible. Either the token address should be provided or a new token should be deployed.");case 19:return e.next=21,au(t,n,s,r,o,c,i,l);case 21:if(b=e.sent,g=b.txs,h=b.meta,d.push.apply(d,Object(w.a)(g)),null!=(null===h||void 0===h?void 0:h.expectedAddress)){e.next=27;break}throw new Error("The expected value is missing");case 27:return E=je(n,h.expectedAddress),d.push(E),e.abrupt("return",a.txs.send({txs:d}).catch((function(e){throw console.error(e),new Error("Error when proposing transactions to the Safe")})));case 30:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c,i,l,s,u){return e.apply(this,arguments)}}(),ou=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}}}})),cu={daoName:"",votingDelayInBlocks:0,votingPeriodInBlocks:50400,proposalThreshold:0,quorumPercent:4},iu=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=ou(),o=n.governor,l=Object(c.useState)(o),s=Object(x.a)(l,2),u=s[0],d=s[1],f=function(e,t){d(Object(N.a)(Object(N.a)({},u),{},Object(P.a)({},t,e.target.value)))},m=function(){return u},p=u.daoName,b=u.votingDelayInBlocks,g=u.votingPeriodInBlocks,E=u.proposalThreshold,v=u.quorumPercent;return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Setup OZ Governor Contract")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Configure your governor contract. It can always be changed later, so don't worry too much about getting it perfect the first time.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"DAO Name:",value:p,placeholder:"My Governor",borderStyle:"double",className:r.input,onChange:function(e){return f(e,"daoName")}})),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Voting Delay Configurations")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"Configure a delay modifier to determine the duration required before voting (Cooldown), and the amount of time that the proposal will be valid (Expiration).")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:6,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Voting Delay (in blocks)",value:b,type:"number",placeholder:"0",borderStyle:"double",className:r.input,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{votingDelayInBlocks:parseInt(e.target.value)}))},tooltipMsg:"The time between proposal submission and when voting starts."})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Voting Period (in blocks)",value:g,type:"number",placeholder:"50400",borderStyle:"double",className:r.input,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{votingPeriodInBlocks:parseInt(e.target.value)}))},tooltipMsg:"The number of blocks between when a proposal's voting period starts and ends."})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Voting Thresholds")))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Proposal Threshold",color:"secondary",borderStyle:"double",className:r.input,type:"number",value:E,tooltipMsg:"How many tokens must someone own before they can submit a proposal to the DAO?",onChange:function(e){return f(e,"proposalThreshold")}})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.d,{label:"Quorum (%):",defaultValue:v,hasInput:!0,onChangeSlider:function(e){"number"===typeof e&&v!==e&&e>=0&&d(Object(N.a)(Object(N.a)({},u),{},{quorumPercent:e}))}})),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(m())}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:!(![p].includes("")&&v>=0&&v<=100),onClick:function(){return t(m())}},"Next"))))))},lu=["token","governor","review"],su=Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},paperTitle:{margin:0},step:{"& text":{fontFamily:"Roboto Mono"},"& .step-label":{textTransform:"capitalize",display:"inline",fontFamily:"Roboto Mono","&.clickable":{cursor:"pointer","&:hover":{textDecoration:"underline"}}}},stepperRoot:{backgroundColor:"transparent",border:"none",padding:e.spacing(0),"& .MuiStepIcon-active":{color:e.palette.secondary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"},"& .MuiStepIcon-completed":{background:e.palette.text.primary,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%",color:e.palette.secondary.main},"& .Mui-disabled .MuiStepIcon-root":{color:e.palette.primary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"}}}})),uu=function(){var e=su(),t=dr(),a=t.sdk,n=t.safe,r=t.provider,o=ba(),l=Object(c.useState)(0),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)({token:!1,governor:!1,review:!1}),E=Object(x.a)(g,2),v=E[0],w=E[1],j=Object(c.useState)({token:zs,governor:cu,review:{}}),S=Object(x.a)(j,2),I=S[0],T=S[1],A=function(e,t,a){return function(n){d(e),w(Object(N.a)(Object(N.a)({},v),{},Object(P.a)({},t,a))),T(Object(N.a)(Object(N.a)({},I),{},Object(P.a)({},t,n)))}},R=function(){var e=Object(k.a)(C.a.mark((function e(){var t,c,i,l,s,u,d,f,m,p,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(b(!0),null!=I){e.next=4;break}throw b(!1),new Error("No setup data");case 4:return t=I.token,c=t.tokenAddress,i=t.tokenSymbol,l=t.tokenConfiguration,s=t.tokenName,u=I.governor,d=u.daoName,f=u.votingDelayInBlocks,m=u.votingPeriodInBlocks,p=u.proposalThreshold,g=u.quorumPercent,e.prev=6,h=void 0,"ERC20"!==l&&"ERC721"!==l||(h={name:s,symbol:i,kind:l}),e.next=11,ru(r,a,n.safeAddress,d,f,m,p,g,c,h);case 11:e.sent.safeTxHash&&(o(Kt(n)),o($t(!0))),e.next=19;break;case 15:e.prev=15,e.t0=e.catch(6),b(!1),console.error(e.t0);case 19:case"end":return e.stop()}}),e,null,[[6,15]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement("div",{className:e.root},i.a.createElement(q.a,{container:!0,spacing:2,className:e.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0},i.a.createElement(h.a,{icon:"ozGov",size:60})),i.a.createElement(q.a,{item:!0,style:{display:"flex",alignItems:"center"}},i.a.createElement(y.a,{variant:"h5"},"Governor Module")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{gutterBottom:!0},"Enables an Open Zeppelin Governor contract as a module."," ",i.a.createElement(Xa,{underline:"always",href:"https://blog.openzeppelin.com/governor-smart-contract/",target:"_blank",color:"inherit"},"Read more here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:e.paperContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",style:{marginBottom:15}},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",gutterBottom:!0,className:e.paperTitle},"Add Governor Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"outlined",onClick:function(){return o(ta(!1))}},"Cancel"))),i.a.createElement(Ml.a,{activeStep:u,className:e.stepperRoot,orientation:"vertical"},lu.map((function(t,a){return i.a.createElement(Bl.a,{key:t,className:e.step},i.a.createElement(Dl.a,{onClick:function(){return e=a,void(v[t]&&d(e));var e}},i.a.createElement(y.a,{variant:"h6",className:ja()(a<=u&&"clickable","step-label")},t)," "),i.a.createElement(Ll.a,null,"token"===t&&i.a.createElement(Ks,{handleNext:A(a+1,t,!0),handleBack:function(){return o(ta(!1))},setupData:I}),"governor"===t&&i.a.createElement(iu,{handleNext:A(a+1,t,!0),handleBack:A(u-1,t,!1),setupData:I}),"review"===t&&i.a.createElement(qs,{handleNext:R,handleBack:A(a-1,t,!0),setupData:I,goToStep:d,loading:p})))})))))))},du=function(){var e=ga(At),t=ga(Ht),a=ga((function(e){return e.modules.loadingModules})),n=ga((function(e){return e.modules.realityModuleScreen})),r=ga((function(e){return e.modules.OzGovernorModuleScreen}));return e?i.a.createElement(oc,{module:e}):t?i.a.createElement(Al,null):n?i.a.createElement(Fs,null):r?i.a.createElement(uu,null):a?null:i.a.createElement(kl,null)},fu=a(514),mu=Object(g.a)((function(e){return{root:{marginBottom:e.spacing(2)},container:{"&.MuiPaper-root":{display:"flex",flexDirection:"row",alignItems:"center","&::before":Object(h.g)(-5,h.f.tan[300])}},header:{"&.MuiPaper-root":{padding:e.spacing(.5,2,.5,.5),"&::before":Object(h.g)(-5,h.f.tan[300])}},txBuilder:{"&.MuiPaper-root":{padding:e.spacing(.5,.5,.5,2),cursor:"pointer",transition:"0.2s ease all","&::before":Object(h.g)(-5,h.f.tan[300]),"&:hover":{background:"rgba(217, 212, 173, 0.15)"}}},img:{display:"block",width:36,height:36},title:{marginLeft:e.spacing(1)},bagIcon:{marginLeft:e.spacing(2),stroke:"white"},badge:{color:e.palette.common.white,display:"flex",position:"relative",transform:"none",textAlign:"center",background:"none",fontSize:16},badgeRoot:{display:"flex",justifyContent:"center",alignItems:"center",height:36,width:36,borderRadius:60,border:"1px solid ".concat(h.f.tan[300]),padding:e.spacing(.5)},txBuilderTitle:{marginRight:e.spacing(3)},circleIconContainer:{padding:e.spacing(.5)},banner:{"&.MuiPaper-root":{flexGrow:1,position:"relative",borderWidth:1,borderColor:h.f.tan[300],backgroundColor:h.f.tan[100],margin:e.spacing(0,2),"&::before":Object(h.g)(-5,h.f.tan[300])}}}})),pu=function(){var e=mu(),t=ba(),a=ga(Lr);return i.a.createElement(Pa,{className:e.root},i.a.createElement(h.c,{elevation:0,borderStyle:"double",rounded:"left",variant:"elevation",className:ja()(e.container,e.header)},i.a.createElement(h.a,{icon:"zodiac"}),i.a.createElement(y.a,{variant:"h5",className:e.title},"Zodiac")),i.a.createElement(h.c,{elevation:0,className:e.banner}),i.a.createElement(h.c,{borderStyle:"double",onClick:function(){return t(oa())},elevation:0,rounded:"right",className:ja()(e.container,e.txBuilder)},i.a.createElement(y.a,{className:e.txBuilderTitle},"Bundle Transactions"),i.a.createElement(h.c,{rounded:"full",variant:"outlined",className:e.circleIconContainer},i.a.createElement(fu.a,{showZero:!0,badgeContent:a.length,color:a.length?"error":"primary",classes:{badge:e.badge,root:e.badgeRoot}}))))},bu=a(310),gu=a(507),hu=["svgRef","title"];function Eu(){return(Eu=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var yu=function(e){var t=e.svgRef,a=e.title,n=vu(e,hu);return i.a.createElement("svg",Eu({width:9,height:16,viewBox:"0 0 9 16",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Xs||(Xs=i.a.createElement("circle",{cx:1.5,cy:2,r:1.5,fill:"#B2B5B2"})),Qs||(Qs=i.a.createElement("circle",{cx:1.5,cy:14,r:1.5,fill:"#B2B5B2"})),Js||(Js=i.a.createElement("circle",{cx:1.5,cy:8,r:1.5,fill:"#B2B5B2"})),$s||($s=i.a.createElement("circle",{cx:7.5,cy:2,r:1.5,fill:"#B2B5B2"})),eu||(eu=i.a.createElement("circle",{cx:7.5,cy:14,r:1.5,fill:"#B2B5B2"})),tu||(tu=i.a.createElement("circle",{cx:7.5,cy:8,r:1.5,fill:"#B2B5B2"})))},Ou=i.a.forwardRef((function(e,t){return i.a.createElement(yu,Eu({svgRef:t},e))})),xu=(a.p,Object(g.a)((function(e){return{icon:{color:e.palette.primary.main,width:20,height:20},iconContainer:{height:54,cursor:"pointer",padding:e.spacing(2,.5),marginRight:e.spacing(1)},button:{marginRight:e.spacing(1.5),color:e.palette.text.secondary},label:{color:e.palette.text.primary}}}))),wu=function(e){var t=e.edit,a=void 0!==t&&t,n=e.disabled,r=void 0!==n&&n,o=e.onCancel,c=e.onEdit,l=e.onSave,s=e.onDelete,u=xu();return a?i.a.createElement(i.a.Fragment,null,i.a.createElement(Ar,{disabled:r,className:u.button,onClick:l},"Save Changes"),i.a.createElement(Ar,{onClick:o,className:u.button,classes:{label:u.label},variant:"outlined"},"Cancel")):i.a.createElement(i.a.Fragment,null,i.a.createElement(J.a,{className:u.iconContainer,onClick:c},i.a.createElement(m.Icon,{type:"edit",size:"md",className:u.icon})),i.a.createElement(J.a,{className:u.iconContainer,onClick:s},i.a.createElement(m.Icon,{type:"delete",size:"md",className:u.icon})))},ju=Object(g.a)((function(e){return{root:{position:"relative",borderRadius:8},label:{marginBottom:e.spacing(.5)},field:{padding:e.spacing(1,0,1,1)}}})),Cu=function(e){var t=e.label,a=e.value,n=ju();return i.a.createElement("div",{className:n.root},i.a.createElement(y.a,{noWrap:!0,className:n.label},t),i.a.createElement(h.c,{borderStyle:"double",className:n.field},i.a.createElement(y.a,{noWrap:!0},a)))},ku=function(e){var t=e.edit?e.paramInputProps.map((function(e,t){return i.a.createElement(q.a,{item:!0,key:t,xs:12,md:6},i.a.createElement(co,Object.assign({key:t},e)))})):e.func.inputs.map((function(t,a){return i.a.createElement(q.a,{item:!0,key:a,xs:12,md:6},i.a.createElement(Cu,{label:"".concat(t.name," (").concat(t.type,")"),value:lt(t,e.params[a])}))}));return i.a.createElement(q.a,{container:!0,spacing:2},t)},Su=a(1723),Nu=["address","name"],Iu=Object(g.a)((function(e){return{name:{marginRight:e.spacing(1)},avatar:{"& img":{width:20,height:20}}}})),Tu=function(e){var t=e.address,a=e.name,n=Object(Ca.a)(e,Nu),r=Iu(),o=i.a.createElement(i.a.Fragment,null,a?i.a.createElement("b",{className:r.name},a):null,_a(t));return i.a.createElement(Su.a,Object.assign({},n,{avatar:i.a.createElement(Ra,{showAvatar:!0,showHash:!1,avatarSize:"sm",hash:t,className:r.avatar}),label:o}))},Au=Object(g.a)((function(e){return{title:{padding:e.spacing(2,.5,2,0),marginRight:e.spacing(1),display:"flex",alignItems:"center",flexDirection:"row",flexGrow:1},clickable:{cursor:"pointer"},moduleChip:{marginRight:e.spacing(1),fontSize:14}}})),Ru=function(e){var t=e.edit,a=e.open,n=e.transaction,r=e.onToggle,o=Au();return i.a.createElement(J.a,{className:ja()(o.title,Object(P.a)({},o.clickable,!t)),onClick:r},n.module?i.a.createElement(Tu,{className:o.moduleChip,address:n.module.address,name:n.module.name}):null,i.a.createElement(Su.a,{label:i.a.createElement("b",null,n.func.name)}),i.a.createElement(Or,null),t?null:i.a.createElement(bo,{up:a}))},Mu=Object(g.a)((function(e){return{container:{marginTop:"0 !important",padding:0},collapsableContainer:{margin:0,padding:e.spacing(1,2,2,2)},dragging:{borderColor:"#31AAB7",borderStyle:"solid",borderWidth:2},noDragging:{transform:"none !important"},dropAnimation:{transitionDuration:"0.001s !important"},grip:{display:"flex",cursor:"grab",padding:e.spacing(2)}}})),Bu=function(e){var t,a=e.open,n=e.edit,r=void 0!==n&&n,o=e.headerButtonProps,c=e.headerTitleProps,l=e.blockFieldsProps,s=e.drag,u=Mu();return i.a.createElement(Gr,Object.assign({open:a,innerRef:s.provider.innerRef},s.provider.draggableProps,{containerClassName:u.collapsableContainer,className:ja()(u.container,(t={},Object(P.a)(t,u.dragging,s.snapshot.isDragging),Object(P.a)(t,u.noDragging,!s.snapshot.isDragging),Object(P.a)(t,u.dropAnimation,s.snapshot.isDropAnimating),t)),content:i.a.createElement(ku,l)}),i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement("div",Object.assign({className:u.grip},s.provider.dragHandleProps),i.a.createElement(Ou,null)),i.a.createElement(Ru,Object.assign({open:a,edit:r},c)),i.a.createElement(wu,Object.assign({edit:r},o))))},Du=Object(g.a)((function(e){return{root:{position:"relative",paddingBottom:e.spacing(2.5)},placeholder:{position:"absolute",width:"100%",borderColor:"#31AAB7",borderStyle:"solid",borderWidth:0,borderBottomWidth:e.spacing(.5),"&.place-after":{bottom:e.spacing(1)},"&.place-before":{top:e.spacing(-1)}}}})),Lu=Object(qa.a)((function(e){return{root:{height:56,backgroundColor:e.palette.primary.light}}}))(gu.a),Pu=function(e){var t=e.index,a=e.isOver,n=e.isOverBefore,r=e.transaction,o=e.onUpdate,l=e.onDelete,s=Du(),u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)(!1),b=Object(x.a)(p,2),g=b[0],h=b[1],E=r.id,v=r.params,y=r.func,O=function(){m(!0),h(!0)},w=function(){g||m(!f)},j=function(){h(!1)},C=function(){l(E)};return i.a.createElement(bu.b,{draggableId:E,index:t},(function(e,t){return i.a.createElement("div",{className:ja()(s.root,{over:a})},g?i.a.createElement(Wr,{func:y,defaultParams:v},(function(a){var n=a.paramInputProps,c=a.areParamsValid,l=a.getParams;return i.a.createElement(Bu,{edit:!0,open:f,drag:{provider:e,snapshot:t},blockFieldsProps:{edit:!0,paramInputProps:n},headerTitleProps:{transaction:r,onToggle:w},headerButtonProps:{disabled:!c,onCancel:j,onSave:function(){return e=l(),o(E,e),void h(!1);var e}}})})):i.a.createElement(Bu,{open:f,drag:{provider:e,snapshot:t},blockFieldsProps:{edit:!1,params:v,func:y},headerTitleProps:{transaction:r,onToggle:w},headerButtonProps:{onEdit:O,onDelete:C}}),a&&i.a.createElement("div",{className:ja()(s.placeholder,{"place-after":!n,"place-before":n})}),t.isDragging&&i.a.createElement(Lu,{elevation:0}))}))},Fu=Object(g.a)((function(e){return{root:{width:"100%",display:"flex",flexGrow:1,outline:"none",padding:e.spacing(1.5),marginBottom:e.spacing(2),backgroundColor:"#0d0b217a",border:"1px solid rgba(217, 212, 173, 0.3)",overflowY:"auto"}}})),Uu=function(e){var t=e.transactions,a=Fu(),n=ba(),r=Object(c.useState)(),o=Object(x.a)(r,2),l=o[0],s=o[1],u=Object(c.useState)(),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useCallback)((function(e,a){var r=t.map(Rr).map((function(t){return t.id!==e?t:Object(N.a)(Object(N.a)({},t),{},{params:a})}));n(da(r))}),[n,t]),b=Object(c.useCallback)((function(e){var a=Array.from(t).map(Rr),r=a.findIndex((function(t){return t.id===e}));r>=0&&(a.splice(r,1),n(da(a)))}),[n,t]);return i.a.createElement("div",{className:a.root},i.a.createElement(bu.a,{onDragStart:function(e){m(e.source.index)},onDragUpdate:function(e){e.destination&&e.destination.index!==e.source.index?s(e.destination.index):s(void 0)},onDragEnd:function(e){if(s(void 0),m(void 0),e.destination){var a=Array.from(t).map(Rr),r=a.splice(e.source.index,1),o=Object(x.a)(r,1)[0];a.splice(e.destination.index,0,o),n(da(a))}}},i.a.createElement(bu.c,{droppableId:"transactions"},(function(e){return i.a.createElement("div",Object.assign({ref:e.innerRef,style:{width:"100%"}},e.droppableProps),t.map((function(e,t){return i.a.createElement(Pu,{index:t,key:e.id,transaction:e,isOver:t===l,isOverBefore:!!f&&t = {\n ETH: { symbol: \"ETH\", decimals: 18 },\n XDAI: { symbol: \"xDai\", decimals: 18 },\n MATIC: { symbol: \"MATIC\", decimals: 18 },\n BNB: { symbol: \"BNB\", decimals: 18 },\n AVAX: { symbol: \"AVAX\", decimals: 18 },\n}\n\nexport const NETWORKS: Record = {\n [NETWORK.MAINNET]: {\n chainId: NETWORK.MAINNET,\n name: \"mainnet\",\n shortName: \"eth\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.GOERLI]: {\n chainId: NETWORK.GOERLI,\n name: \"goerli\",\n shortName: \"gor\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.OPTIMISM]: {\n chainId: NETWORK.OPTIMISM,\n name: \"optimism\",\n shortName: \"oeth\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.GNOSIS_CHAIN]: {\n chainId: NETWORK.GNOSIS_CHAIN,\n name: \"gnosis_chain\",\n shortName: \"gno\",\n nativeAsset: NATIVE_ASSET.XDAI,\n },\n [NETWORK.BSC]: {\n chainId: NETWORK.BSC,\n name: \"binance_smart_chain\",\n shortName: \"bnb\",\n nativeAsset: NATIVE_ASSET.BNB,\n },\n [NETWORK.POLYGON]: {\n chainId: NETWORK.POLYGON,\n name: \"polygon\",\n shortName: \"matic\",\n nativeAsset: NATIVE_ASSET.MATIC,\n },\n [NETWORK.ARBITRUM]: {\n chainId: NETWORK.ARBITRUM,\n name: \"arbitrum\",\n shortName: \"arb1\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.AVALANCHE]: {\n chainId: NETWORK.AVALANCHE,\n name: \"avalanche\",\n shortName: \"avax\",\n nativeAsset: NATIVE_ASSET.AVAX,\n },\n}\n\nexport const NETWORK_NATIVE_ASSET: Record = {\n [NETWORK.MAINNET]: NATIVE_ASSET.ETH,\n [NETWORK.GOERLI]: NATIVE_ASSET.ETH,\n [NETWORK.OPTIMISM]: NATIVE_ASSET.ETH,\n [NETWORK.GNOSIS_CHAIN]: NATIVE_ASSET.XDAI,\n [NETWORK.POLYGON]: NATIVE_ASSET.MATIC,\n [NETWORK.BSC]: NATIVE_ASSET.BNB,\n [NETWORK.ARBITRUM]: NATIVE_ASSET.ETH,\n [NETWORK.AVALANCHE]: NATIVE_ASSET.AVAX,\n}\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n height: \"calc(100% - 70px)\",\n gridTemplateColumns: \"390px 1fr\",\n gridGap: theme.spacing(0.5),\n overflow: \"hidden\",\n padding: theme.spacing(0.5),\n },\n leftPanel: {\n overflowY: \"auto\",\n },\n content: {\n overflowY: \"auto\",\n },\n}));\n\ninterface AppLayoutProps {\n left: React.ReactElement;\n}\n\nexport const AppLayout: React.FC = ({ children, left }) => {\n const classes = useStyles();\n return (\n \n {left}\n \n {children}\n \n \n );\n};\n","import { Interface } from \"@ethersproject/abi\"\nimport { abi as SafeAbi } from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/gnosis_safe_l2.json\"\n\nexport const AddressOne = \"0x0000000000000000000000000000000000000001\"\n\nexport const buildTransaction = (\n iface: Interface,\n to: string,\n method: string,\n params: any[],\n value?: string,\n) => {\n return {\n to,\n data: iface.encodeFunctionData(method, params),\n value: value || \"0\",\n }\n}\n\nexport { SafeAbi }\n","import { NETWORK } from \"./networks\"\n\nconst isDev = process.env.NODE_ENV === \"development\"\nconst REACT_APP_ETHERSCAN_KEY = process.env.REACT_APP_ETHERSCAN_KEY\nif (!REACT_APP_ETHERSCAN_KEY) {\n throw new Error(\"REACT_APP_ETHERSCAN_KEY is not set\")\n}\n\nconst REACT_APP_GNOSISSCAN_KEY = process.env.REACT_APP_GNOSISSCAN_KEY\nif (!isDev && !REACT_APP_GNOSISSCAN_KEY) {\n throw new Error(\"REACT_APP_GNOSISSCAN_KEY is not set\")\n}\n\nconst REACT_APP_POLYGONSCAN_KEY = process.env.REACT_APP_POLYGONSCAN_KEY\nif (!isDev && !REACT_APP_POLYGONSCAN_KEY) {\n throw new Error(\"REACT_APP_POLYGONSCAN_KEY is not set\")\n}\n\nconst REACT_APP_BSCSCAN_KEY = process.env.REACT_APP_BSCSCAN_KEY\nif (!isDev && !REACT_APP_BSCSCAN_KEY) {\n throw new Error(\"REACT_APP_BSCSCAN_KEY is not set\")\n}\n\nconst REACT_APP_OPTIMISTIC_ETHERSCAN_KEY = process.env.REACT_APP_OPTIMISTIC_ETHERSCAN_KEY\nif (!isDev && !REACT_APP_OPTIMISTIC_ETHERSCAN_KEY) {\n throw new Error(\"REACT_APP_OPTIMISTIC_ETHERSCAN_KEY is not set\")\n}\n\nconst REACT_APP_ARBISCAN_KEY = process.env.REACT_APP_ARBISCAN_KEY\nif (!isDev && !REACT_APP_ARBISCAN_KEY) {\n throw new Error(\"REACT_APP_ARBISCAN_KEY is not set\")\n}\n\nconst REACT_APP_SNOWTRACE_KEY = process.env.REACT_APP_SNOWTRACE_KEY\nif (!isDev && !REACT_APP_SNOWTRACE_KEY) {\n throw new Error(\"REACT_APP_SNOWTRACE_KEY is not set\")\n}\n\ninterface ExplorerData {\n networkExplorerName: string\n networkExplorerUrl: string\n networkExplorerApiUrl: string\n safeTransactionApi: string\n safeUrl: string\n explorerApiKey?: string\n verifyContractUrl: string\n}\n\nexport const EXPLORERS_CONFIG: Record = {\n [NETWORK.MAINNET]: {\n networkExplorerName: \"Etherscan\",\n networkExplorerUrl: \"https://etherscan.io\",\n networkExplorerApiUrl: \"https://api.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-mainnet.safe.global/\",\n safeUrl: \"https://app.safe.global/eth:\",\n verifyContractUrl: \"https://etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ETHERSCAN_KEY,\n },\n [NETWORK.GOERLI]: {\n networkExplorerName: \"Etherscan\",\n networkExplorerUrl: \"https://goerli.etherscan.io\",\n networkExplorerApiUrl: \"https://api-goerli.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-goerli.safe.global/\",\n safeUrl: \"https://app.safe.global/gor:\",\n verifyContractUrl: \"https://goerli.etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ETHERSCAN_KEY,\n },\n [NETWORK.GNOSIS_CHAIN]: {\n networkExplorerName: \"GnosisScan\",\n networkExplorerUrl: \"https://gnosisscan.io\",\n networkExplorerApiUrl: \"https://api.gnosisscan.io/api\",\n safeUrl: \"https://app.safe.global/gno:\",\n safeTransactionApi: \"https://safe-transaction-gnosis-chain.safe.global/\",\n verifyContractUrl: \"https://gnosisscan.io/verifyContract\",\n explorerApiKey: REACT_APP_GNOSISSCAN_KEY,\n },\n [NETWORK.POLYGON]: {\n networkExplorerName: \"Polygonscan\",\n networkExplorerUrl: \"https://polygonscan.com\",\n networkExplorerApiUrl: \"https://api.polygonscan.com/api\",\n safeUrl: \"https://app.safe.global/matic:\",\n safeTransactionApi: \"https://safe-transaction-polygon.safe.global/\",\n verifyContractUrl: \"https://polygonscan.com/verifyContract\",\n explorerApiKey: REACT_APP_POLYGONSCAN_KEY,\n },\n [NETWORK.BSC]: {\n networkExplorerName: \"Bscscan\",\n networkExplorerUrl: \"https://bscscan.com/\",\n networkExplorerApiUrl: \"https://api.bscscan.com/api\",\n safeUrl: \"https://app.safe.global/bsc:\",\n safeTransactionApi: \"https://safe-transaction-bsc.safe.global/\",\n verifyContractUrl: \"https://bscscan.com/verifyContract\",\n explorerApiKey: REACT_APP_BSCSCAN_KEY,\n },\n [NETWORK.OPTIMISM]: {\n networkExplorerName: \"Optimism\",\n networkExplorerUrl: \"https://optimistic.etherscan.io/\",\n networkExplorerApiUrl: \"https://api-optimistic.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-optimism.safe.global/\",\n safeUrl: \"https://app.safe.global/oeth:\",\n verifyContractUrl: \"https://optimistic.etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_OPTIMISTIC_ETHERSCAN_KEY,\n },\n [NETWORK.ARBITRUM]: {\n networkExplorerName: \"Arbiscan\",\n networkExplorerUrl: \"https://arbiscan.io/\",\n networkExplorerApiUrl: \"https://api.arbiscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-arbitrum.safe.global/\",\n safeUrl: \"https://app.safe.global/arb1:\",\n verifyContractUrl: \"https://arbiscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ARBISCAN_KEY,\n },\n [NETWORK.AVALANCHE]: {\n networkExplorerName: \"Snowtrace\",\n networkExplorerUrl: \"https://snowtrace.io/\",\n networkExplorerApiUrl: \"https://api.snowtrace.io/api\",\n safeTransactionApi: \"https://safe-transaction-avalanche.safe.global/\",\n safeUrl: \"https://app.safe.global/avax:\",\n verifyContractUrl: \"https://snowtrace.io/verifyContract\",\n explorerApiKey: REACT_APP_SNOWTRACE_KEY,\n },\n}\n\nexport const getNetworkExplorerInfo = (chainId: number) => {\n const networkBaseConfig = EXPLORERS_CONFIG[chainId as NETWORK]\n if (!networkBaseConfig) return\n return {\n name: networkBaseConfig.networkExplorerName,\n url: networkBaseConfig.networkExplorerUrl,\n apiUrl: networkBaseConfig.networkExplorerApiUrl,\n apiKey: networkBaseConfig.explorerApiKey,\n safeTransactionApi: networkBaseConfig.safeTransactionApi,\n safeUrl: networkBaseConfig.safeUrl,\n verifyUrl: networkBaseConfig.verifyContractUrl,\n }\n}\n\nexport const getExplorerInfo = (chainId: number, hash: string) => {\n const explorerData = getNetworkExplorerInfo(chainId)\n if (!explorerData) return\n const type = hash.length > 42 ? \"tx\" : \"address\"\n return () => ({\n url: `${explorerData.url}/${type}/${hash}`,\n alt: explorerData.name,\n })\n}\n","import { Contract, ethers } from \"ethers\"\nimport { Coin, NETWORK, NETWORKS } from \"../utils/networks\"\n\nconst REALITY_ETH_ERC20_CONTRACT_ABI = [\"function token() view returns (address)\"]\n\nconst ERC20_CONTRACT_ABI = [\n \"function name() view returns (string)\",\n \"function symbol() view returns (string)\",\n \"function decimals() public view returns (uint8)\",\n]\n\nexport const ERC721_CONTRACT_ABI = [\n \"function supportsInterface(bytes4 interfaceID) external view returns (bool)\",\n]\n\nexport async function getArbitratorBondToken(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n chainId: number,\n): Promise<{ isERC20: boolean; coin: Coin }> {\n try {\n const realityEthErc20Contract = new Contract(\n address,\n REALITY_ETH_ERC20_CONTRACT_ABI,\n provider,\n )\n const tokenAddress: string = await realityEthErc20Contract.token()\n const tokenContract = new Contract(tokenAddress, ERC20_CONTRACT_ABI, provider)\n const coin: Coin = {\n symbol: await tokenContract.symbol(),\n decimals: await tokenContract.decimals(),\n }\n return { isERC20: true, coin }\n } catch (err) {\n return {\n isERC20: false,\n coin: NETWORKS[chainId as NETWORK].nativeAsset,\n }\n }\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckmark = function SvgCheckmark(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 15,\n height: 12,\n viewBox: \"0 0 15 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z\",\n fill: \"#001428\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckmark, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkmark.23e86834.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useEffect, useState } from \"react\"\nimport { Box, Grid, InputLabel, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { getCollateral } from \"../../services\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const collateralOptions = {\n USDC: \"USDC\",\n WETH: \"WETH\",\n}\n\nexport function scaleBondDecimals(bond: string, isWeth: boolean): number {\n if (isWeth) {\n return Number(bond) * Math.pow(10, 18)\n } else {\n return Number(bond) * Math.pow(10, 6)\n }\n}\n\n// List of chain IDs where OG is available.\nconst optimisticGovernorAvailability: number[] = [\n NETWORK.MAINNET,\n NETWORK.POLYGON,\n NETWORK.GOERLI,\n NETWORK.GNOSIS_CHAIN,\n NETWORK.OPTIMISM,\n NETWORK.ARBITRUM,\n NETWORK.AVALANCHE,\n]\n\ntype Option = keyof typeof collateralOptions\n\ninterface CollateralSelectProps {\n defaultAddress?: string\n defaultOption?: string\n label: string\n chainId: number\n\n onChange(collateral: string): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n select: {\n marginBottom: -1,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"100%\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n}))\n\nexport const CollateralSelect = ({\n onChange,\n defaultOption = collateralOptions.USDC,\n label,\n chainId,\n}: CollateralSelectProps) => {\n const classes = useStyles()\n const [option, setOption] = useState(defaultOption)\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleCollateralOptionChange = (newOption: string) => {\n handleClose()\n const newOptionKey = Object.keys(collateralOptions).find(\n (k) => collateralOptions[`${k}` as Option] === newOption,\n ) as Option\n setOption(newOption)\n const isWeth = newOptionKey === \"WETH\" ? true : false\n const newCollateral = getCollateral(chainId, isWeth)\n onChange(newCollateral)\n }\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n return (\n
\n {label}\n \n \n value as string}\n onChange={(evt) => handleCollateralOptionChange(evt.target.value as string)}\n >\n {Object.keys(collateralOptions).map((optionKey) => {\n if (\n !optimisticGovernorAvailability.includes(chainId) &&\n optionKey === \"WETH\"\n ) {\n return null\n }\n return (\n \n {collateralOptions[`${optionKey}` as Option]}\n \n \n \n )\n })}\n \n \n \n
\n )\n}\n","import { BigNumber, Contract, ethers } from \"ethers\"\nimport { Interface } from \"@ethersproject/abi\"\nimport {\n calculateProxyAddress,\n deployAndSetUpModule,\n getModuleFactoryAndMasterCopy,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { AddressOne, buildTransaction, SafeAbi } from \"./helpers\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { getNetworkExplorerInfo } from \"../utils/explorers\"\nimport { SafeTransaction, SafeStatusResponse } from \"../store/modules/models\"\nimport { NETWORK } from \"../utils/networks\"\nimport { ERC721_CONTRACT_ABI } from \"./reality-eth\"\nimport { scaleBondDecimals } from \"components/input/CollateralSelect\"\n\ntype JsonRpcProvider = ethers.providers.JsonRpcProvider\n\nexport enum ARBITRATOR_OPTIONS {\n NO_ARBITRATOR,\n KLEROS,\n OTHER,\n}\n\nexport type TxWitMeta = {\n txs: BaseTransaction[]\n meta?: { [key: string]: string }\n}\n\ninterface TellorModuleParams {\n owner: string\n executor: string\n oracle?: string\n cooldown: string\n expiration: string\n}\n\ninterface OptimisticGovernorModuleParams {\n executor: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n}\n\ninterface DelayModuleParams {\n executor: string\n cooldown: string\n expiration: string\n}\n\nexport interface RolesModifierParams {\n target: string\n multisend: string\n}\n\nexport interface AMBModuleParams {\n amb: string\n controller: string\n executor: string\n chainId: string\n}\n\nexport interface ExitModuleParams {\n executor: string\n tokenContract: string\n}\n\nexport interface ConnextModuleParams {\n domainId: number\n sender: string\n owner: string\n avatar: string\n target: string\n}\n\nexport function getTellorOracle(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.POLYGON:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.GOERLI:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.OPTIMISM:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.ARBITRUM:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n }\n return \"\"\n}\n\nexport function getDefaultOracle(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\"\n case NETWORK.BSC:\n return \"0xa925646Cae3721731F9a8C886E5D1A7B123151B9\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xE78996A233895bE74a66F451f1019cA9734205cc\"\n case NETWORK.POLYGON:\n return \"0x60573B8DcE539aE5bF9aD7932310668997ef0428\"\n case NETWORK.GOERLI:\n return \"0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\"\n case NETWORK.OPTIMISM:\n return \"0x0eF940F7f053a2eF5D6578841072488aF0c7d89A\"\n case NETWORK.ARBITRUM:\n return \"0x5D18bD4dC5f1AC8e9bD9B666Bd71cB35A327C4A9\"\n case NETWORK.AVALANCHE:\n return \"0xD88cd78631Ea0D068cedB0d1357a6eabe59D7502\"\n }\n return \"\"\n}\n\nexport function getFinder(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x40f941E48A552bF496B154Af6bf55725f18D77c3\"\n case NETWORK.POLYGON:\n return \"0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64\"\n case NETWORK.GOERLI:\n return \"0xE60dBa66B85E10E7Fd18a67a6859E241A243950e\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xeF684C38F94F48775959ECf2012D7E864ffb9dd4\"\n case NETWORK.OPTIMISM:\n return \"0x278d6b1aA37d09769E519f05FcC5923161A8536D\"\n case NETWORK.ARBITRUM:\n return \"0xB0b9f73B424AD8dc58156C2AE0D7A1115D1EcCd1\"\n case NETWORK.AVALANCHE:\n return \"0xCFdC4d6FdeC25e339ef07e25C35a482A6bedcfE0\"\n }\n return \"\"\n}\n\nexport function getCollateral(chainId: number, isWeth: boolean): string {\n if (isWeth) {\n return getWETHAddress(chainId)\n } else {\n return getUSDCAddress(chainId)\n }\n}\n\nfunction getUSDCAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"\n case NETWORK.POLYGON:\n return \"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\"\n case NETWORK.GOERLI:\n return \"0x07865c6E87B9F70255377e024ace6630C1Eaa37F\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83\"\n case NETWORK.OPTIMISM:\n return \"0x7F5c764cBc14f9669B88837ca1490cCa17c31607\"\n case NETWORK.ARBITRUM:\n return \"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8\"\n case NETWORK.AVALANCHE:\n return \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\"\n }\n return \"\"\n}\n\nfunction getWETHAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"\n case NETWORK.POLYGON:\n return \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\"\n case NETWORK.GOERLI:\n return \"0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1\"\n case NETWORK.OPTIMISM:\n return \"0x4200000000000000000000000000000000000006\"\n case NETWORK.ARBITRUM:\n return \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\"\n case NETWORK.AVALANCHE:\n return \"0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB\"\n }\n return \"\"\n}\n\nexport function getKlerosAddress(chainId: number): string {\n // TODO: Add addresses when Kleros becomes available.\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xf72cfd1b34a91a64f9a98537fe63fbab7530adca\"\n case NETWORK.GOERLI:\n return \"0xba08deb3f07a9c55052777fed84a86be8e5ebc1c\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x29f39de98d750eb77b5fafb31b2837f079fce222\"\n case NETWORK.POLYGON:\n return \"0x5AFa42b30955f137e10f89dfb5EF1542a186F90e\"\n }\n return \"\"\n}\n\nexport function getArbitrator(chainId: number, arbitratorOption: number): string {\n switch (arbitratorOption) {\n case ARBITRATOR_OPTIONS.NO_ARBITRATOR:\n // Setting the oracle as the arbitrator is equivalent to setting a null arbitrator.\n return getDefaultOracle(chainId)\n case ARBITRATOR_OPTIONS.KLEROS:\n return getKlerosAddress(chainId)\n case ARBITRATOR_OPTIONS.OTHER:\n return \"\"\n }\n return \"\"\n}\n\nexport function getConnextAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x8898B472C54c31894e3B9bb83cEA802a5d0e63C6\"\n case NETWORK.POLYGON:\n return \"0x11984dc4465481512eb5b777E44061C158CF2259\"\n case NETWORK.GOERLI:\n return \"0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x5bB83e95f63217CDa6aE3D181BA580Ef377D2109\"\n case NETWORK.OPTIMISM:\n return \"0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA\"\n case NETWORK.ARBITRUM:\n return \"0xEE9deC2712cCE65174B561151701Bf54b99C24C8\"\n }\n return \"\"\n}\n\nexport function deployTellorModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: TellorModuleParams,\n) {\n const type = KnownContracts.TELLOR\n const { owner, oracle, cooldown, expiration, executor } = args\n const oracleAddress = oracle || getTellorOracle(chainId)\n\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"uint32\", \"uint32\"],\n values: [owner, safeAddress, executor, oracleAddress, cooldown, expiration],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n\nexport function deployDelayModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: DelayModuleParams,\n) {\n const { cooldown, expiration, executor } = args as unknown as DelayModuleParams\n const {\n transaction: delayModuleDeploymentTx,\n expectedModuleAddress: delayModuleExpectedAddress,\n } = deployAndSetUpModule(\n KnownContracts.DELAY,\n {\n types: [\"address\", \"address\", \"address\", \"uint256\", \"uint256\"],\n values: [safeAddress, safeAddress, executor, cooldown, expiration],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableDelayModuleTransaction = enableModule(\n safeAddress,\n delayModuleExpectedAddress,\n )\n\n return [\n {\n ...delayModuleDeploymentTx,\n value: delayModuleDeploymentTx.value.toString(),\n },\n enableDelayModuleTransaction,\n ]\n}\n\nexport function deployBridgeModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: AMBModuleParams,\n) {\n const { executor, controller, amb, chainId: ambChainId } = args\n\n const { transaction, expectedModuleAddress } = deployAndSetUpModule(\n KnownContracts.BRIDGE,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"address\", \"bytes32\"],\n values: [\n safeAddress,\n safeAddress,\n executor,\n amb,\n controller,\n ethers.utils.hexZeroPad(BigNumber.from(ambChainId).toHexString(), 32),\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const enableModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n\n return [\n {\n ...transaction,\n value: transaction.value.toString(),\n },\n enableModuleTransaction,\n ]\n}\n\nexport function deployCirculatingSupplyContract(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n token: string,\n saltNonce: string,\n isERC721?: boolean,\n) {\n const type: KnownContracts = isERC721\n ? KnownContracts.CIRCULATING_SUPPLY_ERC721\n : KnownContracts.CIRCULATING_SUPPLY_ERC20\n\n const { moduleFactory, moduleMastercopy: circulatingSupplyContract } =\n getModuleFactoryAndMasterCopy(type, provider, chainId)\n\n const encodedInitParams = new ethers.utils.AbiCoder().encode(\n [\"address\", \"address\", \"address[]\"],\n [safeAddress, token, [safeAddress]],\n )\n const moduleSetupData = circulatingSupplyContract.interface.encodeFunctionData(\n \"setUp\",\n [encodedInitParams],\n )\n\n const expectedAddress = calculateProxyAddress(\n moduleFactory as Contract,\n circulatingSupplyContract.address,\n moduleSetupData,\n saltNonce,\n )\n\n const deployData = moduleFactory.interface.encodeFunctionData(\"deployModule\", [\n circulatingSupplyContract.address,\n moduleSetupData,\n saltNonce,\n ])\n\n const transaction = {\n data: deployData,\n to: moduleFactory.address,\n value: \"0\",\n }\n return {\n transaction,\n expectedAddress,\n }\n}\n\nexport async function deployExitModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: ExitModuleParams,\n) {\n const txs: BaseTransaction[] = []\n const { executor, tokenContract } = args\n\n let isERC721 = false\n try {\n const ERC721Contract = new Contract(tokenContract, ERC721_CONTRACT_ABI, provider)\n isERC721 = await ERC721Contract.supportsInterface(\"0x80ac58cd\")\n } catch (err) {\n console.warn(\"deployExitModule: error determining token type\")\n }\n\n const {\n transaction: deployCirculationSupplyTx,\n expectedAddress: circulatingSupplyAddress,\n } = deployCirculatingSupplyContract(\n provider,\n safeAddress,\n chainId,\n tokenContract,\n Date.now().toString(),\n isERC721,\n )\n\n txs.push(deployCirculationSupplyTx)\n\n const type = isERC721 ? KnownContracts.EXIT_ERC721 : KnownContracts.EXIT_ERC20\n\n const { transaction, expectedModuleAddress } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"address\"],\n values: [\n safeAddress,\n safeAddress,\n executor,\n tokenContract,\n circulatingSupplyAddress,\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n txs.push({\n ...transaction,\n value: transaction.value.toString(),\n })\n\n const enableModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n txs.push(enableModuleTransaction)\n\n return txs\n}\n\nexport async function fetchSafeModulesAddress(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n) {\n const safe = new Contract(safeAddress, SafeAbi, provider)\n const [modules] = await safe.getModulesPaginated(AddressOne, 50)\n return modules as string[]\n}\n\nexport function enableModule(safeAddress: string, module: string) {\n return buildTransaction(new Interface(SafeAbi), safeAddress, \"enableModule\", [module])\n}\n\nexport async function disableModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n module: string,\n) {\n const modules = await fetchSafeModulesAddress(provider, safeAddress, chainId)\n if (!modules.length) throw new Error(\"Safe does not have enabled modules\")\n let prevModule = AddressOne\n if (modules.length > 1) {\n const moduleIndex = modules.findIndex((m) => m.toLowerCase() === module.toLowerCase())\n if (moduleIndex > 0) prevModule = modules[moduleIndex - 1]\n }\n const params = [prevModule, module]\n return {\n params,\n ...buildTransaction(new Interface(SafeAbi), safeAddress, \"disableModule\", params),\n }\n}\n\nexport const callContract = (\n provider: JsonRpcProvider,\n chainId: number,\n address: string,\n abi: ContractInterface,\n method: string,\n data: any[] = [],\n) => {\n const contract = new Contract(address, abi, provider)\n return contract.functions[method](...data)\n}\n\nexport async function fetchSafeBalanceInfo(chainId: number, safeAddress: string) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) return []\n\n const url = new URL(\n `api/v1/safes/${safeAddress}/balances/?trusted=false&exclude_spam=false`,\n network.safeTransactionApi,\n )\n\n const request = await fetch(url.toString())\n const response = await request.json()\n console.log(\"response\", response)\n return response.results\n}\n\nexport async function fetchSafeTransactions(\n chainId: number,\n safeAddress: string,\n params: Record,\n) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) return []\n\n const url = new URL(\n `api/v1/safes/${safeAddress}/transactions`,\n network.safeTransactionApi,\n )\n\n Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, value))\n\n const request = await fetch(url.toString())\n const response = await request.json()\n\n return response.results as SafeTransaction[]\n}\n\nexport async function fetchSafeStatusFromAPI(chainId: number, safeAddress: string) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) throw new Error(\"invalid network\")\n\n const url = new URL(`api/v1/safes/${safeAddress}`, network.safeTransactionApi)\n\n const request = await fetch(url.toString())\n const response = await request.json()\n return response as SafeStatusResponse\n}\n\nexport function deployRolesV1Modifier(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RolesModifierParams,\n) {\n const { target, multisend } = args\n const { transaction: deployAndSetupTx, expectedModuleAddress: expectedRolesAddress } =\n deployAndSetUpModule(\n KnownContracts.ROLES_V1,\n {\n types: [\"address\", \"address\", \"address\"],\n values: [safeAddress, safeAddress, target],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableModuleTx = enableModule(safeAddress, expectedRolesAddress)\n\n const rolesContract = getModuleInstance(\n KnownContracts.ROLES_V1,\n expectedRolesAddress,\n provider,\n )\n\n const setMultisendTx = buildTransaction(\n rolesContract.interface,\n rolesContract.address,\n \"setMultisend\",\n [multisend],\n )\n\n return [\n {\n ...deployAndSetupTx,\n value: deployAndSetupTx.value.toHexString(),\n },\n enableModuleTx,\n setMultisendTx,\n ]\n}\n\nexport function deployRolesV2Modifier(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RolesModifierParams,\n) {\n const { target, multisend } = args\n const { transaction: deployAndSetupTx, expectedModuleAddress: expectedRolesAddress } =\n deployAndSetUpModule(\n KnownContracts.ROLES_V2,\n {\n types: [\"address\", \"address\", \"address\"],\n values: [safeAddress, safeAddress, target],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableModuleTx = enableModule(safeAddress, expectedRolesAddress)\n\n const rolesContract = getModuleInstance(\n KnownContracts.ROLES_V2,\n expectedRolesAddress,\n provider,\n )\n\n const MULTISEND_SELECTOR = \"0x8d80ff0a\"\n const MULTISEND_UNWRAPPER = \"0x93B7fCbc63ED8a3a24B59e1C3e6649D50B7427c0\"\n const setUnwrapperTx = {\n to: rolesContract.address,\n data: rolesContract.interface.encodeFunctionData(\"setTransactionUnwrapper\", [\n multisend,\n MULTISEND_SELECTOR,\n MULTISEND_UNWRAPPER,\n ]),\n value: \"0\",\n }\n\n return [\n {\n ...deployAndSetupTx,\n value: deployAndSetupTx.value.toHexString(),\n },\n enableModuleTx,\n setUnwrapperTx,\n ]\n}\n\nexport function deployOptimisticGovernorModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: OptimisticGovernorModuleParams,\n isWeth: boolean,\n) {\n const type = KnownContracts.OPTIMISTIC_GOVERNOR\n\n const { executor, collateral, bond, rules, identifier, liveness } = args\n\n const scaledBond = scaleBondDecimals(bond, isWeth).toString()\n\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"uint256\", \"string\", \"bytes32\", \"uint64\"],\n values: [executor, collateral, scaledBond, rules, identifier, liveness],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n\nexport function deployConnextModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: ConnextModuleParams,\n) {\n const type = KnownContracts.CONNEXT\n const { domainId, sender, owner, avatar, target } = args\n const connextAddress = getConnextAddress(chainId)\n const {\n transaction: connextModuleDeploymentTx,\n expectedModuleAddress: connextModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"uint32\", \"address\"],\n values: [owner, avatar, target, sender, domainId, connextAddress],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const connextModuleTransactions: BaseTransaction[] = [\n {\n ...connextModuleDeploymentTx,\n value: connextModuleDeploymentTx.value.toString(),\n },\n ]\n\n const enableConnextModuleTransaction = enableModule(\n safeAddress,\n connextModuleExpectedAddress,\n )\n connextModuleTransactions.push(enableConnextModuleTransaction)\n\n return connextModuleTransactions\n}\n","import { ContractInterface } from \"@ethersproject/contracts\"\nimport { ContractAbis, KnownContracts } from \"@gnosis.pm/zodiac\"\n\nexport enum ModuleType {\n TELLOR = \"tellor\",\n OPTIMISTIC_GOVERNOR = \"optimisticGovernor\",\n REALITY_ETH = \"realityETH\",\n REALITY_ERC20 = \"realityERC20\",\n DELAY = \"delay\",\n BRIDGE = \"bridge\",\n EXIT = \"exit\",\n ROLES_V1 = \"roles_v1\",\n ROLES_V2 = \"roles_v2\",\n OZ_GOVERNOR = \"ozGovernor\",\n KLEROS_REALITY = \"klerosReality\",\n CONNEXT = \"connext\",\n UNKNOWN = \"unknown\",\n}\n\nexport const MODULE_NAMES: Record = {\n [ModuleType.TELLOR]: \"Tellor Module\",\n [ModuleType.OPTIMISTIC_GOVERNOR]: \"UMA oSnap Module\",\n [ModuleType.REALITY_ERC20]: \"Reality Module\",\n [ModuleType.REALITY_ETH]: \"Reality Module\",\n [ModuleType.KLEROS_REALITY]: \"Kleros Reality Module\",\n [ModuleType.UNKNOWN]: \"Unknown Module\",\n [ModuleType.BRIDGE]: \"Bridge Module\",\n [ModuleType.DELAY]: \"Delay Modifier\",\n [ModuleType.ROLES_V1]: \"Roles Modifier (v1)\",\n [ModuleType.ROLES_V2]: \"Roles Modifier (v2)\",\n [ModuleType.EXIT]: \"Exit Module\",\n [ModuleType.OZ_GOVERNOR]: \"Governor Module\",\n [ModuleType.CONNEXT]: \"Connext Module\",\n}\n\nexport const MODULE_ABIS: Record = {\n [ModuleType.TELLOR]: ContractAbis[KnownContracts.TELLOR],\n [ModuleType.OPTIMISTIC_GOVERNOR]: ContractAbis[KnownContracts.OPTIMISTIC_GOVERNOR],\n [ModuleType.REALITY_ERC20]: ContractAbis[KnownContracts.REALITY_ERC20],\n [ModuleType.REALITY_ETH]: ContractAbis[KnownContracts.REALITY_ETH],\n [ModuleType.KLEROS_REALITY]: ContractAbis[KnownContracts.REALITY_ETH],\n [ModuleType.UNKNOWN]: [],\n [ModuleType.BRIDGE]: ContractAbis[KnownContracts.BRIDGE],\n [ModuleType.DELAY]: ContractAbis[KnownContracts.DELAY],\n [ModuleType.ROLES_V1]: ContractAbis[KnownContracts.ROLES_V1],\n [ModuleType.ROLES_V2]: ContractAbis[KnownContracts.ROLES_V2],\n [ModuleType.EXIT]: ContractAbis[KnownContracts.EXIT_ERC20],\n [ModuleType.OZ_GOVERNOR]: ContractAbis[KnownContracts.OZ_GOVERNOR],\n [ModuleType.CONNEXT]: ContractAbis[KnownContracts.CONNEXT],\n}\n\nexport enum ModuleOperation {\n CREATE,\n REMOVE,\n}\n\nexport interface Module {\n id: string\n name?: string\n address: string\n type: ModuleType\n subModules: Module[]\n owner?: string\n parentModule: string\n}\n\nexport interface ModuleContract {\n address: string\n implAddress: string\n type: ModuleType\n name?: string\n abi?: ContractInterface\n}\n\nexport interface ModuleContractMetadata {\n type: ModuleType\n name?: string\n abi: ContractInterface\n}\n\nexport interface DelayModule extends Module {\n type: ModuleType.DELAY\n expiration: number\n cooldown: number\n}\n\nexport interface TellorModule extends Module {\n type: ModuleType.TELLOR\n owner: string\n executor: string\n oracle: string\n expiration: number\n cooldown: number\n}\n\nexport interface OptimisticGovernorModule extends Module {\n type: ModuleType.OPTIMISTIC_GOVERNOR\n finder: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n}\n\nexport interface RealityModule extends Module {\n type: ModuleType.REALITY_ETH\n executor: string\n oracle: string\n expiration: number\n bond: string\n templateId: string\n cooldown: number\n arbitrator: string\n}\n\nexport interface ConnextModule extends Module {\n type: ModuleType.CONNEXT\n domainId: string\n sender: string\n owner: string\n avatar: string\n target: string\n connext: string\n}\n\nexport interface ModulesState {\n operation: Operation\n current?: Module\n currentPendingModule?: PendingModule\n loadingModules: boolean\n list: Module[]\n reloadCount: number\n safeThreshold: number\n pendingModules: PendingModule[]\n moduleAdded: boolean\n realityModuleScreen: boolean\n OzGovernorModuleScreen: boolean\n}\n\nexport type Operation = \"read\" | \"write\"\n\nexport interface DataDecoded {\n method: string\n parameters: { name?: string; value?: string }[]\n}\n\nexport interface MultiSendDataDecoded extends DataDecoded {\n method: \"multiSend\"\n parameters: {\n name: \"transactions\"\n type: \"bytes\"\n value: string\n valueDecoded: DecodedTransaction[]\n }[]\n}\n\nexport interface RawTransaction {\n to: string\n data: string\n value: string\n nonce: number\n operation: 0 | 1\n}\n\nexport interface DecodedTransaction extends RawTransaction {\n dataDecoded: DataDecoded\n}\n\nexport interface SafeTransaction extends DecodedTransaction {\n safe: string\n gasToken: string\n}\n\nexport interface SafeStatusResponse {\n address: string\n nonce: number\n threshold: number\n owners: string[]\n masterCopy: string\n modules: string[]\n fallbackHandler: string\n guard: string\n version: string\n}\n\nexport interface PendingModule {\n operation: ModuleOperation\n module: ModuleType\n address: string\n executor: string\n}\n","import { Contract, ethers } from \"ethers\"\nimport {\n MODULE_ABIS,\n MODULE_NAMES,\n ModuleContractMetadata,\n ModuleType,\n} from \"../store/modules/models\"\nimport { NETWORK } from \"./networks\"\n\nconst GNOSIS_GENERIC_PROXY_CONTRACT_BYTECODE =\n \"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea265627a7a72315820d8a00dc4fe6bf675a9d7416fc2d00bb3433362aa8186b750f76c4027269667ff64736f6c634300050e0032\"\n\nconst GNOSIS_GENERIC_PROXY_CONTRACT_ABI = [\n \"function masterCopy() external view returns (address)\",\n]\n\nexport function getModuleType(type: string): ModuleType {\n const moduleType = Object.keys(ModuleType).find((moduleType) => moduleType === type)\n if (!moduleType) return ModuleType.UNKNOWN\n return moduleType as ModuleType\n}\n\nexport function getModuleContractMetadata(\n module: ModuleType,\n): ModuleContractMetadata | undefined {\n if (module === ModuleType.UNKNOWN) return\n return { type: module, name: MODULE_NAMES[module], abi: MODULE_ABIS[module] }\n}\n\nexport function isGnosisGenericProxy(bytecode: string) {\n return bytecode.toLowerCase() === GNOSIS_GENERIC_PROXY_CONTRACT_BYTECODE\n}\n\nexport function isGenericProxy(bytecode: string) {\n if (bytecode.length !== 92) return false\n return (\n bytecode.startsWith(\"0x363d3d373d3d3d363d73\") &&\n bytecode.endsWith(\"5af43d82803e903d91602b57fd5bf3\")\n )\n}\n\nexport function getGenericProxyMaster(bytecode: string) {\n return \"0x\" + bytecode.substr(22, 40)\n}\n\nexport async function getProxyMaster(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n chainId: NETWORK,\n) {\n const contract = new Contract(address, GNOSIS_GENERIC_PROXY_CONTRACT_ABI, provider)\n\n const [masterAddress] = await contract.functions.masterCopy()\n\n return masterAddress\n}\n","import {\n defaultAbiCoder,\n FunctionFragment,\n Interface,\n ParamType,\n} from \"@ethersproject/abi\"\nimport memoize from \"lodash.memoize\"\nimport { getNetworkExplorerInfo } from \"./explorers\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n getGenericProxyMaster,\n getModuleContractMetadata,\n getProxyMaster,\n isGenericProxy,\n isGnosisGenericProxy,\n} from \"./modulesValidation\"\nimport { ModuleContract, ModuleType } from \"../store/modules/models\"\nimport retry from \"async-retry\"\nimport { BigNumber, ethers } from \"ethers\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport { getContractsModuleType, getModuleName } from \"../store/modules/helpers\"\n\nexport function isWriteFunction(method: FunctionFragment) {\n if (!method.stateMutability) return true\n return ![\"view\", \"pure\"].includes(method.stateMutability)\n}\n\nexport function isReadFunction(method: FunctionFragment) {\n return !isWriteFunction(method)\n}\n\nexport function getReadFunction(abi: ContractInterface) {\n const inter = abi instanceof Interface ? abi : new Interface(abi as any)\n return inter.fragments\n .filter(FunctionFragment.isFunctionFragment)\n .map(FunctionFragment.from)\n .filter(isReadFunction)\n}\n\nexport function getWriteFunction(abi: ContractInterface) {\n const inter = abi instanceof Interface ? abi : new Interface(abi as any)\n return inter.fragments\n .filter(FunctionFragment.isFunctionFragment)\n .map(FunctionFragment.from)\n .filter(isWriteFunction)\n}\n\nexport const fetchContractSourceCode = memoize(\n (chainId: number, contractAddress: string) =>\n retry(\n async (bail) => {\n const network = getNetworkExplorerInfo(chainId)\n\n if (!network) throw new Error(\"Network data not found\")\n\n const { apiUrl, apiKey } = network\n\n const urlParams: Record = {\n module: \"contract\",\n action: \"getsourcecode\",\n address: contractAddress,\n }\n\n if (apiKey) {\n urlParams.apiKey = apiKey\n }\n\n const params = new URLSearchParams(urlParams)\n\n const response = await fetch(`${apiUrl}?${params}`)\n\n if (!response.ok) throw new Error(\"Could not fetch contract source code\")\n\n const { status, result } = await response.json()\n if (status === \"0\") throw new Error(\"Could not fetch contract source code\")\n\n const data = result[0] as { ABI: string; ContractName: string }\n\n if (!data.ContractName) bail(new Error(\"Contract is not verified\"))\n\n return data\n },\n { retries: 4, minTimeout: 1000 },\n ),\n (chainId: number, contractAddress: string) => `${chainId}_${contractAddress}`,\n)\n\nexport function isBasicFunction(func: FunctionFragment) {\n return !func.inputs.length\n}\n\nexport function isOneResult(func: FunctionFragment) {\n return (\n func.outputs?.length === 1 && func.outputs && func.outputs[0]?.baseType !== \"array\"\n )\n}\n\nexport function validateFunctionParamValue(param: ParamType, value: any): boolean {\n try {\n defaultAbiCoder.encode([param], [value])\n return true\n } catch (error) {\n return false\n }\n}\n\nexport function validateFunctionParams(func: FunctionFragment, params: any[]): boolean {\n try {\n defaultAbiCoder.encode(func.inputs, params)\n return true\n } catch (error) {\n return false\n }\n}\n\n/**\n * Formats and Validate a param value.\n * @param param - Contract Function Param.\n * @param value - Value.\n */\nexport function formatParamValue(param: ParamType, value: string): any {\n let _value = value\n if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n try {\n _value = JSON.parse(_value)\n } catch (e) {\n throw new Error(\"Input must be of type \" + param.baseType)\n }\n }\n\n if (!validateFunctionParamValue(param, _value)) {\n throw new Error(\"Input must be of type \" + param.type)\n }\n\n return _value\n}\n\n/**\n * Formats and Validate a param value.\n * @param param - Contract Function Param.\n * @param value - Value.\n */\nexport function formatDisplayParamValue(param: ParamType, value: any): string {\n if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n try {\n return JSON.stringify(value)\n } catch (e) {\n console.warn(\"formatDisplayParamValue: value is not an object\", value, e)\n }\n }\n return value.toString()\n}\n\nexport const getModuleData = memoize(\n async (\n provider: ethers.providers.JsonRpcProvider,\n safeSDK: SafeAppsSDK,\n chainId: number,\n address: string,\n ): Promise => {\n const bytecode = await safeSDK.eth.getCode([address])\n\n if (isGenericProxy(bytecode)) {\n const masterAddress = getGenericProxyMaster(bytecode)\n const module: ModuleContract = await getModuleData(\n provider,\n safeSDK,\n chainId,\n masterAddress,\n )\n return { ...module, address }\n }\n\n if (isGnosisGenericProxy(bytecode)) {\n const masterAddress = await getProxyMaster(provider, address, chainId)\n const module: ModuleContract = await getModuleData(\n provider,\n safeSDK,\n chainId,\n masterAddress,\n )\n return { ...module, address }\n }\n\n const type = getContractsModuleType(chainId, address)\n if (type !== ModuleType.UNKNOWN) {\n return {\n type,\n address,\n implAddress: address,\n name: getModuleName(type),\n ...getModuleContractMetadata(type),\n }\n }\n\n try {\n const { ABI, ContractName } = await fetchContractSourceCode(chainId, address)\n\n return {\n address,\n implAddress: address,\n name: ContractName,\n abi: ABI,\n type: ModuleType.UNKNOWN,\n }\n } catch (error) {\n return { address, implAddress: address, type: ModuleType.UNKNOWN }\n }\n },\n (sdk, chainId, address, provider) => `${chainId}_${address}_${provider}`,\n)\n\nexport function formatValue(\n baseType: string,\n value: string | BigNumber | boolean,\n): string {\n if (baseType === \"array\" || baseType === \"tuple\") {\n value = JSON.stringify(value)\n }\n\n return value.toString()\n}\n","import { Contract as MultiCallContract, Provider as MultiCallProvider } from \"ethcall\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n ContractAddresses,\n ContractVersions,\n getModuleInstance,\n KnownContracts,\n SupportedNetworks,\n} from \"@gnosis.pm/zodiac\"\nimport { getModuleData } from \"../../utils/contracts\"\nimport {\n DataDecoded,\n DecodedTransaction,\n DelayModule,\n Module,\n MODULE_NAMES,\n ModuleContract,\n ModuleOperation,\n ModuleType,\n MultiSendDataDecoded,\n PendingModule,\n RealityModule,\n SafeTransaction,\n} from \"./models\"\nimport { Contract, ethers } from \"ethers\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const AddressOne = \"0x0000000000000000000000000000000000000001\"\n\nexport function isDelayModule(module: Module): module is DelayModule {\n return module.type === ModuleType.DELAY\n}\n\nexport function isRealityModule(module: Module): module is RealityModule {\n return (\n module.type === ModuleType.REALITY_ETH || module.type === ModuleType.REALITY_ERC20\n )\n}\n\nexport const sanitizeModule = async (\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n sdk: SafeAppsSDK,\n chainId: number,\n parentModule: string,\n parentModulesList: string[] = [moduleAddress],\n): Promise => {\n const module = await getModuleData(provider, sdk, chainId, moduleAddress)\n\n if (module.type === ModuleType.DELAY) {\n return await fetchDelayModule(provider, moduleAddress, sdk, chainId, parentModule)\n }\n\n const subModules = await fetchSubModules(\n provider,\n moduleAddress,\n module.abi,\n sdk,\n chainId,\n parentModulesList,\n )\n\n const owner = await fetchModuleOwner(provider, moduleAddress, module.abi, chainId)\n\n return {\n owner,\n subModules,\n id: moduleAddress,\n name: module.name,\n type: module.type,\n address: moduleAddress,\n parentModule: parentModule,\n }\n}\n\nexport async function fetchDelayModule(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n sdk: SafeAppsSDK,\n chainId: NETWORK,\n parentModule: string,\n): Promise {\n const delayModule = await getModuleInstance(KnownContracts.DELAY, address, provider)\n const abi = delayModule.interface.fragments.map((frag) => frag)\n\n try {\n const moduleContract = new MultiCallContract(delayModule.address, abi)\n\n const ethCallProvider = new MultiCallProvider()\n await ethCallProvider.init(provider as any)\n\n const txCooldown = moduleContract.txCooldown()\n const txExpiration = moduleContract.txExpiration()\n const modules = moduleContract.getModulesPaginated(AddressOne, 50)\n\n let [cooldown, expiration, [subModules]] = await ethCallProvider.all([\n txCooldown,\n txExpiration,\n modules,\n ])\n\n if (subModules) {\n const requests = (subModules as string[]).map(\n async (moduleAddress, index): Promise => {\n const subModule = await sanitizeModule(\n provider,\n moduleAddress,\n sdk,\n chainId,\n parentModule,\n )\n return {\n ...subModule,\n id: `${address}_${moduleAddress}_${index}`,\n parentModule: address,\n }\n },\n )\n requests.reverse()\n subModules = await Promise.all(requests)\n }\n\n const owner = await fetchModuleOwner(provider, address, abi, chainId)\n\n return {\n owner,\n address,\n parentModule,\n id: address,\n name: \"Delay Module\",\n type: ModuleType.DELAY,\n subModules: subModules || [],\n expiration: expiration.toString(),\n cooldown: cooldown.toString(),\n }\n } catch (error) {\n console.warn(\"Error fetching delay module\", error)\n return {\n address,\n parentModule,\n id: address,\n name: \"Delay Module\",\n type: ModuleType.UNKNOWN,\n subModules: [],\n }\n }\n}\n\nexport async function fetchSubModules(\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n abi: ModuleContract[\"abi\"],\n sdk: SafeAppsSDK,\n chainId: number,\n parentModulesList: string[] = [],\n): Promise {\n try {\n if (!abi) return []\n const contract = new Contract(moduleAddress, abi, provider)\n contract.interface.getFunction(\"getModulesPaginated(address,uint256)\")\n const [subModules] = await contract.getModulesPaginated(AddressOne, 50)\n const modulesList = [...parentModulesList, ...subModules]\n return await Promise.all(\n subModules\n .filter((module: string) => !parentModulesList.includes(module))\n .map(async (subModuleAddress: string, index: number) => {\n const subModule = await sanitizeModule(\n provider,\n subModuleAddress,\n sdk,\n chainId,\n moduleAddress,\n modulesList,\n )\n return {\n ...subModule,\n id: `${moduleAddress}_${subModuleAddress}_${index}`,\n parentModule: moduleAddress,\n }\n }),\n )\n } catch (e) {\n return []\n }\n}\n\nexport async function fetchModuleOwner(\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n abi: ModuleContract[\"abi\"],\n chainId: NETWORK,\n): Promise {\n try {\n if (!abi) return undefined\n const contract = new Contract(moduleAddress, abi, provider)\n contract.interface.getFunction(\"owner()\")\n return await contract.owner()\n } catch (e) {\n return undefined\n }\n}\n\nexport function isMultiSendDataEncoded(\n dataEncoded: DataDecoded,\n): dataEncoded is MultiSendDataDecoded {\n return dataEncoded.method === \"multiSend\"\n}\n\nexport function getTransactionsFromSafeTransaction(\n safeTransaction: SafeTransaction,\n): DecodedTransaction[] {\n if (\n safeTransaction.dataDecoded &&\n isMultiSendDataEncoded(safeTransaction.dataDecoded)\n ) {\n return safeTransaction.dataDecoded.parameters[0].valueDecoded\n }\n return [safeTransaction]\n}\n\nconst ZODIAC_CONTRACTS_TO_MODULE_TYPE: { [key: string]: ModuleType } = {\n [KnownContracts.TELLOR]: ModuleType.TELLOR,\n [KnownContracts.OPTIMISTIC_GOVERNOR]: ModuleType.OPTIMISTIC_GOVERNOR,\n [KnownContracts.REALITY_ETH]: ModuleType.REALITY_ETH,\n [KnownContracts.REALITY_ERC20]: ModuleType.REALITY_ERC20,\n [KnownContracts.DELAY]: ModuleType.DELAY,\n [KnownContracts.BRIDGE]: ModuleType.BRIDGE,\n [KnownContracts.EXIT_ERC20]: ModuleType.EXIT,\n [KnownContracts.ROLES_V1]: ModuleType.ROLES_V1,\n [KnownContracts.ROLES_V2]: ModuleType.ROLES_V2,\n [KnownContracts.OZ_GOVERNOR]: ModuleType.OZ_GOVERNOR,\n}\n\nexport function getContractsModuleType(\n chainId: number,\n masterCopyAddress: string,\n): ModuleType {\n const contractVersions = ContractVersions[chainId as SupportedNetworks]\n if (!contractVersions) return ModuleType.UNKNOWN\n\n const entry = Object.entries(contractVersions).find(([, addresses]) => {\n return Object.values(addresses).some(\n (address) => address.toLowerCase() === masterCopyAddress.toLowerCase(),\n )\n })\n if (!entry) return ModuleType.UNKNOWN\n return ZODIAC_CONTRACTS_TO_MODULE_TYPE[entry[0]] || ModuleType.UNKNOWN\n}\n\n/**\n * Determine if the safe transaction is a pending add module transaction.\n *\n * @param {object} safeTransaction - Safe Transaction.\n * @param {number} chainId - Chain Id.\n */\nexport function getAddModuleTransactionModuleType(\n safeTransaction: SafeTransaction,\n chainId: number,\n): ModuleType | undefined {\n const factoryAddress = ContractAddresses[chainId as SupportedNetworks]?.factory || \"\"\n const transactions = getTransactionsFromSafeTransaction(safeTransaction)\n\n const masterCopyAddress = transactions\n .map((transaction): string | undefined => {\n if (transaction.to.toLowerCase() === factoryAddress.toLowerCase()) {\n if (!transaction.dataDecoded) {\n // Decode Proxy Factory data locally\n try {\n const result = decodeProxyFactoryTransaction(transaction.data)\n return result[0] // return first parameter (masterCopy)\n } catch (err) {\n console.warn(\"failed to decode proxy factory transaction: \", transaction.data)\n return undefined\n }\n }\n\n if (transaction.dataDecoded.method === \"deployModule\") {\n const param = transaction.dataDecoded.parameters?.find(\n (param) => param.name === \"masterCopy\",\n )\n if (param) return param.value\n }\n }\n return undefined\n })\n .find((x) => x)\n\n return getContractsModuleType(chainId, masterCopyAddress || \"\")\n}\n\nconst MODULE_PROXY_FACTORY_ABI = [\n \"function deployModule(address masterCopy, bytes initializer, uint256 saltNonce) returns (address proxy)\",\n]\n\nfunction decodeProxyFactoryTransaction(data: string) {\n return new ethers.utils.Interface(MODULE_PROXY_FACTORY_ABI).decodeFunctionData(\n \"deployModule\",\n data,\n )\n}\n\nexport function isSafeEnableModuleTransactionPending(transaction: DecodedTransaction) {\n return transaction.dataDecoded && transaction.dataDecoded.method === \"enableModule\"\n}\n\n/**\n * Determine if the safe transaction is a pending remove module transaction.\n *\n * @param {object} transaction - Transaction.\n */\nexport function isRemoveModuleTransactionPending(\n transaction: DecodedTransaction,\n): boolean {\n return transaction.dataDecoded && transaction.dataDecoded.method === \"disableModule\"\n}\n\nexport function getModulesToBeRemoved(\n modules: Module[],\n transactions: SafeTransaction[],\n): PendingModule[] {\n return transactions\n .flatMap(getTransactionsFromSafeTransaction)\n .filter(isRemoveModuleTransactionPending)\n .map((transaction) => {\n const param = transaction.dataDecoded.parameters.find(\n (param) => param.name === \"module\",\n )\n const moduleAddress = param && param.value ? param.value : \"\"\n const current = modules.find((module) => module.address === moduleAddress)\n return {\n address: moduleAddress,\n executor: transaction.to,\n operation: ModuleOperation.REMOVE,\n module: current ? current.type : ModuleType.UNKNOWN,\n }\n })\n}\n\nfunction getModuleTypeForAddTransactions(\n transactions: SafeTransaction[],\n chainId: number,\n): Record {\n return transactions\n .map((safeTransaction) => {\n const enableModuleTx = getTransactionsFromSafeTransaction(safeTransaction)\n .reverse()\n .find(isSafeEnableModuleTransactionPending)\n\n if (!enableModuleTx) return undefined\n\n const type = getAddModuleTransactionModuleType(safeTransaction, chainId)\n const param = enableModuleTx.dataDecoded.parameters?.find(\n (param) => param.name === \"module\",\n )\n const moduleExpectedAddress = param?.value\n if (!type || !moduleExpectedAddress) return undefined\n return { address: moduleExpectedAddress, type }\n })\n .reduce((obj, value): Record => {\n if (value)\n return {\n ...obj,\n [value.address]: value.type,\n }\n return obj\n }, {})\n}\n\nexport function getPendingModulesToEnable(\n transactions: SafeTransaction[],\n chainId: number,\n): PendingModule[] {\n const modulesTypesByContractAddress = getModuleTypeForAddTransactions(\n transactions,\n chainId,\n )\n\n return transactions\n .flatMap(getTransactionsFromSafeTransaction)\n .filter((transaction) => isSafeEnableModuleTransactionPending(transaction))\n .map((transaction): PendingModule => {\n const moduleAddress: string = transaction.dataDecoded.parameters[0].value || \"\"\n const moduleType =\n modulesTypesByContractAddress[moduleAddress] || ModuleType.UNKNOWN\n return {\n address: moduleAddress,\n executor: transaction.to,\n module: moduleType,\n operation: ModuleOperation.CREATE,\n }\n })\n}\n\nexport function isModule(module: PendingModule | Module): module is Module {\n return \"subModules\" in module\n}\n\nexport function flatAllModules(modules: Module[]): Module[] {\n const subModules = modules.flatMap((module) => flatAllModules(module.subModules))\n return [...modules, ...subModules]\n}\n\nexport function isPendingModule(module: Module, pendingModule: PendingModule) {\n return (\n pendingModule.address === module.address &&\n pendingModule.executor === module.parentModule\n )\n}\n\nexport function getModuleName(type?: ModuleType): string {\n return MODULE_NAMES[type || ModuleType.UNKNOWN]\n}\n","import { RootState } from \"../index\";\nimport { isRealityModule, isDelayModule } from \"./helpers\";\nimport { ModuleOperation } from \"./models\";\n\nexport function getCurrentModule(state: RootState) {\n return state.modules.current;\n}\n\nexport function getModulesList(state: RootState) {\n return state.modules.list;\n}\n\nexport function getReloadCount(state: RootState) {\n return state.modules.reloadCount;\n}\n\nexport function getIsLoadingModules(state: RootState) {\n return state.modules.loadingModules;\n}\n\nexport function getDelayModules(state: RootState) {\n return getModulesList(state).filter(isDelayModule);\n}\n\nexport function getRealityModules(state: RootState) {\n return getModulesList(state).filter(isRealityModule);\n}\n\nexport function getOperation(state: RootState) {\n return state.modules.operation;\n}\n\nexport function getPendingModules(state: RootState) {\n return state.modules.pendingModules;\n}\n\nexport function getPendingCreateModuleTransactions(state: RootState) {\n return getPendingModules(state).filter(\n (tx) => tx.operation === ModuleOperation.CREATE\n );\n}\n\nexport function getPendingRemoveModuleTransactions(state: RootState) {\n return getPendingModules(state).filter(\n (tx) => tx.operation === ModuleOperation.REMOVE\n );\n}\n\nexport function getSafeThreshold(state: RootState) {\n return state.modules.safeThreshold;\n}\n\nexport function getCurrentPendingModule(state: RootState) {\n return state.modules.currentPendingModule;\n}\n\nexport function getModuleAdded(state: RootState) {\n return state.modules.moduleAdded;\n}\n\nexport function getRealityModuleScreen(state: RootState) {\n return state.modules.realityModuleScreen;\n}\n","import { createAsyncThunk, createSlice, PayloadAction } from \"@reduxjs/toolkit\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport { Module, ModulesState, Operation, PendingModule } from \"./models\"\nimport {\n fetchSafeStatusFromAPI,\n fetchSafeModulesAddress,\n fetchSafeTransactions,\n} from \"../../services\"\nimport {\n getModulesToBeRemoved,\n getPendingModulesToEnable,\n sanitizeModule,\n} from \"./helpers\"\nimport { getModulesList } from \"./selectors\"\nimport { RootState } from \"../index\"\nimport { ethers } from \"ethers\"\n\nconst initialModulesState: ModulesState = {\n operation: \"read\",\n reloadCount: 0,\n safeThreshold: 1,\n loadingModules: true,\n list: [],\n current: undefined,\n pendingModules: [],\n moduleAdded: false,\n realityModuleScreen: false,\n OzGovernorModuleScreen: false,\n}\n\nexport const fetchModulesList = createAsyncThunk(\n \"modules/fetchModulesList\",\n async (\n params: {\n provider: ethers.providers.JsonRpcProvider\n safeSDK: SafeAppsSDK\n chainId: number\n safeAddress: string\n },\n store,\n ): Promise => {\n const { provider, safeSDK, safeAddress, chainId } = params\n await provider.ready\n const moduleAddresses = await fetchSafeModulesAddress(provider, safeAddress, chainId)\n\n const requests = moduleAddresses.map(async (moduleAddress) => {\n try {\n return await sanitizeModule(\n provider,\n moduleAddress,\n safeSDK,\n chainId,\n safeAddress,\n )\n } catch (error) {\n throw new Error(`Error sanitizing module ${moduleAddress}: ${error}`)\n }\n })\n requests.reverse()\n try {\n const responses = await Promise.all(requests)\n return responses.filter((module): module is Module => module !== undefined)\n } catch (error) {\n console.error(\"Cant fetch modules\", error)\n throw error\n }\n },\n)\n\nexport const fetchPendingModules = createAsyncThunk(\n \"modules/fetchPendingModules\",\n async (\n {\n safeAddress,\n chainId,\n retry = true,\n }: {\n chainId: number\n safeAddress: string\n retry?: boolean\n },\n store,\n ) => {\n const safeStatusFromAPI = await fetchSafeStatusFromAPI(chainId, safeAddress)\n const transactions = await fetchSafeTransactions(chainId, safeAddress, {\n nonce__gte: safeStatusFromAPI.nonce.toString(),\n })\n\n const state = store.getState() as RootState\n const modules = getModulesList(state)\n\n const pendingEnableModules = getPendingModulesToEnable(transactions, chainId)\n\n const pendingRemoveModules = getModulesToBeRemoved(modules, transactions)\n\n const pendingModules: PendingModule[] = [\n ...pendingEnableModules,\n ...pendingRemoveModules,\n ]\n\n if (retry) {\n setTimeout(() => {\n store.dispatch(fetchPendingModules({ safeAddress, chainId, retry: false }))\n }, 4000)\n }\n\n return { safeInfo: safeStatusFromAPI, pendingModules }\n },\n)\n\nexport const modulesSlice = createSlice({\n name: \"modules\",\n initialState: initialModulesState,\n reducers: {\n increaseReloadCount: (state) => {\n state.reloadCount += 1\n },\n setCurrentModule(state, action: PayloadAction) {\n state.current = action.payload\n state.operation = \"read\"\n state.currentPendingModule = undefined\n },\n unsetCurrentModule(state) {\n state.current = undefined\n state.currentPendingModule = undefined\n },\n setOperation(state, action: PayloadAction) {\n state.operation = action.payload\n },\n setCurrentPendingModule(state, action: PayloadAction) {\n state.currentPendingModule = action.payload\n state.current = undefined\n },\n setModuleAdded(state, action: PayloadAction) {\n state.moduleAdded = action.payload\n },\n setRealityModuleScreen(state, action: PayloadAction) {\n state.realityModuleScreen = action.payload\n },\n setOzGovernorModuleScreen(state, action: PayloadAction) {\n state.OzGovernorModuleScreen = action.payload\n },\n },\n extraReducers: (builder) => {\n builder.addCase(fetchModulesList.rejected, (state) => {\n state.loadingModules = false\n })\n builder.addCase(fetchModulesList.fulfilled, (state, action) => {\n state.loadingModules = false\n state.list = action.payload\n const current = state.current\n if (current) {\n // Check if current module got removed\n const isPresent = action.payload.some(\n (module) => module.address === current.address,\n )\n if (!isPresent) {\n state.current = undefined\n }\n }\n })\n builder.addCase(fetchPendingModules.fulfilled, (state, action) => {\n const { safeInfo, pendingModules } = action.payload\n state.safeThreshold = safeInfo.threshold\n state.pendingModules = pendingModules\n })\n },\n})\n\nexport const {\n increaseReloadCount,\n setCurrentModule,\n unsetCurrentModule,\n setOperation,\n setCurrentPendingModule,\n setModuleAdded,\n setRealityModuleScreen,\n setOzGovernorModuleScreen,\n} = modulesSlice.actions\n","var _path, _path2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAvatarEmpty = function SvgAvatarEmpty(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 40,\n height: 40,\n viewBox: \"0 0 40 40\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M39 20H34M20 39V34M1 20H6M20 1V6\",\n stroke: \"#B2B5B2\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.435 33.435L29.8995 29.8995M6.56497 33.435L10.1005 29.8995M6.56497 6.56497L10.1005 10.1005M33.435 6.56497L29.8995 10.1005\",\n stroke: \"#B2B5B2\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAvatarEmpty, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/avatar-empty.8424ad03.svg\";\nexport { ForwardRef as ReactComponent };","import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\nimport {\n AddTransaction,\n SerializedTransaction,\n TransactionBuilderState,\n} from \"./models\";\n\nconst initialModulesState: TransactionBuilderState = {\n open: false,\n addTransaction: {},\n transactions: [],\n};\n\nexport const transactionBuilderSlice = createSlice({\n name: \"transactionBuilder\",\n initialState: initialModulesState,\n reducers: {\n openTransactionBuilder(state) {\n state.open = true;\n },\n closeTransactionBuilder(state) {\n state.open = false;\n },\n setTransactions(state, action: PayloadAction) {\n state.transactions = action.payload;\n },\n addTransaction(state, action: PayloadAction) {\n state.transactions.push(action.payload);\n },\n resetTransactions(state) {\n state.transactions = [];\n },\n setNewTransaction(state, action: PayloadAction) {\n state.addTransaction = action.payload;\n },\n resetNewTransaction(state) {\n state.addTransaction = {};\n },\n },\n});\n\nexport const {\n openTransactionBuilder,\n closeTransactionBuilder,\n setNewTransaction,\n resetNewTransaction,\n resetTransactions,\n addTransaction,\n setTransactions,\n} = transactionBuilderSlice.actions;\n","import { Middleware } from \"@reduxjs/toolkit\";\nimport {\n fetchModulesList,\n fetchPendingModules,\n setCurrentModule,\n setCurrentPendingModule,\n setModuleAdded,\n} from \"./index\";\nimport {\n getCurrentPendingModule,\n getModuleAdded,\n getModulesList,\n getPendingCreateModuleTransactions,\n} from \"./selectors\";\nimport { flatAllModules } from \"./helpers\";\n\nexport const modulesMiddleware: Middleware = (store) => (next) => (action) => {\n if (action.type === fetchModulesList.fulfilled.type) {\n const oldState = store.getState();\n const currentPending = getCurrentPendingModule(oldState);\n const result = next(action);\n if (currentPending) {\n const modulesList = getModulesList(store.getState());\n const allModules = flatAllModules(modulesList);\n const currentModule = allModules.find(\n (module) => module.address === currentPending.address\n );\n if (currentModule) {\n store.dispatch(setCurrentModule(currentModule));\n }\n }\n return result;\n }\n\n if (action.type === fetchPendingModules.fulfilled.type) {\n const oldState = store.getState();\n const result = next(action);\n if (getModuleAdded(oldState)) {\n const oldPendingModules = getPendingCreateModuleTransactions(oldState);\n const newPendingModules = getPendingCreateModuleTransactions(\n store.getState()\n );\n if (\n (!oldPendingModules.length && newPendingModules.length) ||\n (oldPendingModules.length &&\n newPendingModules.length &&\n newPendingModules[0].address !== oldPendingModules[0].address)\n ) {\n store.dispatch(setCurrentPendingModule(newPendingModules[0]));\n store.dispatch(setModuleAdded(false));\n }\n }\n return result;\n }\n\n return next(action);\n};\n","import { Middleware } from \"@reduxjs/toolkit\";\nimport { setCurrentModule } from \"../modules\";\nimport { closeTransactionBuilder } from \"./index\";\n\nexport const transactionBuilderMiddleware: Middleware =\n (store) => (next) => (action) => {\n if (action.type === setCurrentModule.type) {\n store.dispatch(closeTransactionBuilder());\n }\n return next(action);\n };\n","import { configureStore } from \"@reduxjs/toolkit\";\nimport { modulesSlice } from \"./modules\";\nimport { TypedUseSelectorHook, useDispatch, useSelector } from \"react-redux\";\nimport { transactionBuilderSlice } from \"./transactionBuilder\";\nimport { modulesMiddleware } from \"./modules/middleware\";\nimport { transactionBuilderMiddleware } from \"./transactionBuilder/middleware\";\n\nexport const REDUX_STORE = configureStore({\n reducer: {\n modules: modulesSlice.reducer,\n transactionBuilder: transactionBuilderSlice.reducer,\n },\n middleware: (getDefaultMiddleware) =>\n getDefaultMiddleware().concat(\n modulesMiddleware,\n transactionBuilderMiddleware\n ),\n});\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof REDUX_STORE.dispatch;\n\nexport const useRootDispatch = () => useDispatch();\nexport const useRootSelector: TypedUseSelectorHook = useSelector;\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\ntype ColumnProps = HTMLProps;\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n}));\n\nexport const Column = ({ className, ...props }: ColumnProps) => {\n const classes = useStyles();\n return
;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport classNames from \"classnames\";\nimport { Column } from \"../../../components/layout/Column\";\n\nexport interface PanelItemProps {\n active?: boolean;\n sub?: boolean;\n image?: React.ReactElement | null;\n\n onClick?(): void;\n}\n\nexport const PANEL_ITEM_CONTENT_HEIGHT = 56;\nexport const PANEL_ITEM_PADDING = 8;\nexport const PANEL_ITEM_HEIGHT =\n PANEL_ITEM_CONTENT_HEIGHT + PANEL_ITEM_PADDING * 2 + 2;\nexport const PANEL_ITEM_MARGIN = 12;\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: PANEL_ITEM_PADDING,\n transition: \"0.2s ease all\",\n cursor: \"pointer\",\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n active: {\n borderColor: theme.palette.common.white,\n background: \"none\",\n cursor: \"initial\",\n \"&::before\": {\n borderColor: theme.palette.common.white,\n },\n \"&:hover\": {\n background: \"none\",\n },\n },\n spacing: {\n \"& + &, &.sub\": {\n marginTop: PANEL_ITEM_MARGIN,\n },\n },\n moduleItem: {\n display: \"grid\",\n gridTemplateColumns: \"48px 1fr\",\n gridGap: theme.spacing(2),\n\n backgroundColor: \"transparent\",\n\n \"&.sub\": {\n zIndex: 2,\n },\n },\n content: {\n width: \"100%\",\n justifyContent: \"center\",\n },\n image: {\n paddingTop: 2,\n },\n}));\n\nexport const PanelItem: React.FC = ({\n active,\n sub,\n image = null,\n children,\n onClick,\n}) => {\n const classes = useStyles();\n return (\n \n \n
{image}
\n {children}\n
\n \n );\n};\n","import { EthHashInfo } from \"@gnosis.pm/safe-react-components\";\nimport React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => {\n return {\n hashInfo: {\n display: \"inline-flex !important\",\n width: 50,\n height: 50,\n padding: theme.spacing(0.5),\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"50%\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n background: \"rgba(224, 197, 173, 0.1)\",\n\n \"& p\": {\n fontSize: 12,\n color: theme.palette.text.primary + \" !important\",\n },\n \"& .jLVlPg\": {\n margin: 0,\n },\n \"& .jLVlPg > p\": {\n fontWeight: \"bold\",\n fontSize: 14,\n },\n },\n };\n});\n\nexport const HashInfo = (props: Parameters[0]) => {\n const classes = useStyles();\n return ;\n};\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\ntype RowProps = HTMLProps;\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n}));\n\nexport const Row = ({ className, ...props }: RowProps) => {\n const classes = useStyles();\n return
;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { alpha } from \"@material-ui/core/styles\";\nimport classNames from \"classnames\";\nimport { Row } from \"../layout/Row\";\n\nconst useStyles = makeStyles((theme) => ({\n badge: {\n display: \"inline-block\",\n padding: theme.spacing(0.25, 0.5),\n lineHeight: 1,\n whiteSpace: \"nowrap\",\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n },\n primary: {\n backgroundColor: \"rgba(224, 197, 173, 0.1)\",\n },\n secondary: {\n backgroundColor: alpha(theme.palette.primary.light, 0.4),\n },\n}));\n\ninterface BadgeProps extends React.HTMLProps {\n secondary?: string;\n}\n\nexport const Badge: React.FC = ({\n secondary,\n children,\n className,\n ...props\n}) => {\n const classes = useStyles();\n\n if (secondary) {\n return (\n \n \n {children}\n
\n \n {secondary}\n \n \n );\n }\n\n return (\n \n {children}\n \n );\n};\n","import React from \"react\";\nimport { ExplorerButton } from \"@gnosis.pm/safe-react-components\";\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\";\nimport { getExplorerInfo } from \"../../utils/explorers\";\n\ninterface AddressExplorerButtonProps {\n className?: string;\n address: string;\n}\n\nexport const AddressExplorerButton = ({\n address,\n className,\n}: AddressExplorerButtonProps) => {\n const { safe } = useSafeAppsSDK();\n const safeExplorer = getExplorerInfo(safe.chainId, address);\n if (!safeExplorer) return null;\n return ;\n};\n","export function shortAddress(address: string) {\n return address.substr(0, 6) + \"...\" + address.substr(-4);\n}\n\nexport function formatDuration(duration: number) {\n if (duration < 60) {\n if (duration === 1) return `1 second`;\n return `${duration} second`;\n }\n\n if (duration < 3600) {\n const minutes = Math.floor(duration / 60);\n if (minutes === 1) return `1 minute`;\n return `${minutes} minute`;\n }\n\n // Display until 47 hours\n if (duration < 172800) {\n const hours = Math.floor(duration / 3600);\n if (hours === 1) return `1 hour`;\n return `${hours} hour`;\n }\n\n const days = Math.floor(duration / 86400);\n return `${days} day`;\n}\n","import React from \"react\";\nimport { makeStyles, Typography, TypographyProps } from \"@material-ui/core\";\nimport { CopyToClipboardBtn } from \"@gnosis.pm/safe-react-components\";\nimport { AddressExplorerButton } from \"./AddressExplorerButton\";\nimport { shortAddress } from \"../../utils/string\";\nimport classNames from \"classnames\";\n\ninterface AddressProps {\n address: string;\n short?: boolean;\n hideCopyBtn?: boolean;\n hideExplorerBtn?: boolean;\n showOnHover?: boolean;\n gutterBottom?: boolean;\n classes?: {\n icon?: string;\n container?: string;\n };\n TypographyProps?: TypographyProps;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.5),\n justifyContent: \"start\",\n alignItems: \"center\",\n minWidth: 0,\n \"& > *\": {\n gridRow: 1,\n },\n },\n gutterBottom: {\n marginBottom: theme.spacing(1),\n },\n showOnHover: {\n \"& .btn\": {\n visibility: \"hidden\",\n },\n \"&:hover .btn\": {\n visibility: \"initial\",\n },\n },\n}));\n\nexport const Address = ({\n address,\n short = false,\n hideCopyBtn = false,\n hideExplorerBtn = false,\n showOnHover = false,\n gutterBottom = false,\n classes: { icon, container } = {},\n TypographyProps,\n}: AddressProps) => {\n const classes = useStyles();\n\n return (\n \n \n {short ? shortAddress(address) : address}\n \n {hideCopyBtn ? null : (\n \n )}\n {hideExplorerBtn ? null : (\n \n )}\n \n );\n};\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgLoadingCircle = function SvgLoadingCircle(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 34,\n height: 34,\n viewBox: \"0 0 34 34\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M2 17C2 16.4477 1.55228 16 1 16C0.447715 16 0 16.4477 0 17H2ZM10.6248 1.2361C10.1129 1.44332 9.86584 2.02632 10.0731 2.53825C10.2803 3.05018 10.8633 3.2972 11.3752 3.08997L10.6248 1.2361ZM32 17C32 25.2843 25.2843 32 17 32V34C26.3888 34 34 26.3888 34 17H32ZM17 32C8.71573 32 2 25.2843 2 17H0C0 26.3888 7.61116 34 17 34V32ZM17 2C25.2843 2 32 8.71573 32 17H34C34 7.61116 26.3888 0 17 0V2ZM11.3752 3.08997C13.1109 2.38739 15.009 2 17 2V0C14.7474 0 12.5948 0.438641 10.6248 1.2361L11.3752 3.08997Z\",\n fill: \"#FFFFFF\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgLoadingCircle, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/loading-circle.c90af9bb.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { Link, makeStyles, Typography } from \"@material-ui/core\";\nimport { PanelItemProps } from \"./PanelItem\";\nimport { DelayModule } from \"../../../store/modules/models\";\nimport { Badge } from \"../../../components/text/Badge\";\nimport { Address } from \"../../../components/ethereum/Address\";\nimport { formatDuration } from \"../../../utils/string\";\nimport { useRootDispatch } from \"../../../store\";\nimport { setNewTransaction } from \"../../../store/transactionBuilder\";\nimport { setCurrentModule, setOperation } from \"../../../store/modules\";\nimport { Row } from \"../../../components/layout/Row\";\n\ninterface DelayModuleItemProps extends PanelItemProps {\n module: DelayModule;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n },\n}));\n\nexport const DelayModuleItem = ({ module }: DelayModuleItemProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n\n const handleClick = (evt: React.MouseEvent) => {\n evt.stopPropagation(); // Avoid triggering ModuleItem click event.\n\n dispatch(setCurrentModule(module));\n dispatch(setOperation(\"write\"));\n dispatch(\n setNewTransaction({\n func: \"setTxCooldown(uint256)\",\n params: [module.cooldown],\n })\n );\n };\n\n return (\n
\n \n {module.name}\n \n \n \n {formatDuration(module.cooldown)} delay\n \n Change Delay\n \n \n
\n );\n};\n","import { withStyles, Link as MUILink } from \"@material-ui/core\";\n\nexport const Link = withStyles((theme) => ({\n root: {\n color: theme.palette.text.primary,\n textDecoration: \"underline\",\n transition: \"opacity 0.25s ease-in-out\",\n \"&:hover\": {\n opacity: 0.6,\n }\n },\n}))(MUILink);\n","import React from \"react\";\nimport { PanelItem, PanelItemProps } from \"./PanelItem\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Link } from \"../../../components/text/Link\";\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\";\nimport { getNetworkExplorerInfo } from \"../../../utils/explorers\";\n\ninterface ModulePendingItemProps extends PanelItemProps {\n title: string;\n linkText: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n title: {\n marginBottom: theme.spacing(0.5),\n textTransform: \"uppercase\",\n },\n image: {\n width: 50,\n height: 50,\n display: \"inline-flex !important\",\n padding: theme.spacing(0.5),\n alignItems: \"center\",\n justifyContent: \"center\",\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"50%\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n background: \"rgba(224, 197, 173, 0.1)\",\n },\n}));\n\nexport const ModulePendingItem = ({\n image = null,\n linkText,\n title,\n ...props\n}: ModulePendingItemProps) => {\n const classes = useStyles();\n const { safe } = useSafeAppsSDK();\n\n const network = getNetworkExplorerInfo(safe.chainId);\n const link = network\n ? `${network.safeUrl}${safe.safeAddress}/transactions`\n : \"\";\n\n return (\n {image}} {...props}>\n \n {title}\n \n
\n \n {linkText}\n \n
\n
\n );\n};\n","var _path, _path2, _path3;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgDeleteIcon = function SvgDeleteIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 16,\n height: 16,\n viewBox: \"0 0 16 16\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M6.66667 12.0064C7.03533 12.0064 7.33333 11.7084 7.33333 11.3398V7.33976C7.33333 6.9711 7.03533 6.6731 6.66667 6.6731C6.298 6.6731 6 6.9711 6 7.33976V11.3398C6 11.7084 6.298 12.0064 6.66667 12.0064Z\",\n fill: \"#B2B5B2\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M9.33415 12.0064C9.70281 12.0064 10.0008 11.7084 10.0008 11.3398V7.33976C10.0008 6.9711 9.70281 6.6731 9.33415 6.6731C8.96548 6.6731 8.66748 6.9711 8.66748 7.33976V11.3398C8.66748 11.7084 8.96548 12.0064 9.33415 12.0064Z\",\n fill: \"#B2B5B2\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M11.0085 13.034C10.9998 13.2033 10.8365 13.336 10.6771 13.3346H5.31245C5.15912 13.3173 5.00512 13.204 4.99645 13.0293L4.56445 5.33329H11.4225L11.0085 13.034ZM6.66439 3.07729C6.66439 2.85463 6.85306 2.66663 7.07572 2.66663H8.92105C9.14772 2.66663 9.33239 2.85129 9.33239 3.07729V3.99996H6.66439V3.07729ZM13.3328 3.99992H12.1742C12.1702 3.99992 12.1662 3.99659 12.1615 3.99659C12.1535 3.99592 12.1468 3.99992 12.1382 3.99992H10.6655V3.07725C10.6655 2.11592 9.88351 1.33325 8.92085 1.33325H7.07551C6.11351 1.33325 5.33085 2.11592 5.33085 3.07725V3.99992H2.66618C2.29818 3.99992 1.99951 4.29792 1.99951 4.66659C1.99951 5.03525 2.29818 5.33325 2.66618 5.33325H3.22951L3.66484 13.0979C3.70685 13.9713 4.43885 14.6686 5.29151 14.6686C5.30351 14.6686 5.31551 14.6679 5.32751 14.6679H10.6608H10.6988C11.5655 14.6679 12.2982 13.9719 12.3402 13.1026L12.7575 5.33325H13.3328C13.7015 5.33325 13.9995 5.03525 13.9995 4.66659C13.9995 4.29792 13.7015 3.99992 13.3328 3.99992Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgDeleteIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/delete-icon.f2b9a941.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ReactComponent as LoadingCircleImg } from \"../../assets/images/loading-circle.svg\";\n\ninterface LoadingIconProps {\n icon?: React.ReactNode;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n width: 34,\n height: 34,\n },\n floating: {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n icon: {},\n rotate: {\n animationName: \"$rotate\",\n animationDuration: \"2000ms\",\n animationTimingFunction: \"linear\",\n animationIterationCount: \"infinite\",\n },\n \"@keyframes rotate\": {\n \"0%\": {\n transform: \"rotate(0deg)\",\n },\n \"100%\": {\n transform: \"rotate(360deg)\",\n },\n },\n}));\n\nexport const LoadingIcon = ({ icon }: LoadingIconProps) => {\n const classes = useStyles();\n return (\n
\n
\n \n
\n
{icon}
\n
\n );\n};\n","var _circle, _circle2, _circle3, _path, _path2, _path3, _path4, _path5, _path6;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgRemovePendingState = function SvgRemovePendingState(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 37,\n height: 36,\n viewBox: \"0 0 37 36\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 29,\n cy: 4.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 4,\n cy: 17.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 27,\n cy: 31.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path4 || (_path4 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M18.6667 22.0064C19.0353 22.0064 19.3333 21.7084 19.3333 21.3398V17.3398C19.3333 16.9711 19.0353 16.6731 18.6667 16.6731C18.298 16.6731 18 16.9711 18 17.3398V21.3398C18 21.7084 18.298 22.0064 18.6667 22.0064Z\",\n fill: \"#B2B5B2\"\n })), _path5 || (_path5 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M21.3341 22.0064C21.7028 22.0064 22.0008 21.7084 22.0008 21.3398V17.3398C22.0008 16.9711 21.7028 16.6731 21.3341 16.6731C20.9655 16.6731 20.6675 16.9711 20.6675 17.3398V21.3398C20.6675 21.7084 20.9655 22.0064 21.3341 22.0064Z\",\n fill: \"#B2B5B2\"\n })), _path6 || (_path6 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M23.0085 23.0338C22.9998 23.2032 22.8365 23.3358 22.6771 23.3345H17.3125C17.1591 23.3172 17.0051 23.2038 16.9965 23.0292L16.5645 15.3332H23.4225L23.0085 23.0338ZM18.6644 13.0772C18.6644 12.8545 18.8531 12.6665 19.0757 12.6665H20.9211C21.1477 12.6665 21.3324 12.8512 21.3324 13.0772V13.9998H18.6644V13.0772ZM25.3328 13.9998H24.1742C24.1702 13.9998 24.1662 13.9965 24.1615 13.9965C24.1535 13.9958 24.1468 13.9998 24.1382 13.9998H22.6655V13.0771C22.6655 12.1158 21.8835 11.3331 20.9208 11.3331H19.0755C18.1135 11.3331 17.3308 12.1158 17.3308 13.0771V13.9998H14.6662C14.2982 13.9998 13.9995 14.2978 13.9995 14.6665C13.9995 15.0351 14.2982 15.3331 14.6662 15.3331H15.2295L15.6648 23.0978C15.7068 23.9711 16.4388 24.6685 17.2915 24.6685C17.3035 24.6685 17.3155 24.6678 17.3275 24.6678H22.6608H22.6988C23.5655 24.6678 24.2982 23.9718 24.3402 23.1025L24.7575 15.3331H25.3328C25.7015 15.3331 25.9995 15.0351 25.9995 14.6665C25.9995 14.2978 25.7015 13.9998 25.3328 13.9998Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgRemovePendingState, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/remove-pending-state.f6da023c.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { PanelItemProps } from \"./PanelItem\";\nimport { Module } from \"../../../store/modules/models\";\nimport { ModulePendingItem } from \"./ModulePendingItem\";\nimport { LoadingIcon } from \"../../../components/icons/LoadingIcon\";\nimport { ReactComponent as TrashIcon } from \"../../../assets/icons/delete-icon.svg\";\nimport { ReactComponent as RemovePendingStateImg } from \"../../../assets/images/remove-pending-state.svg\";\n\ninterface ModulePendingRemovalProps extends PanelItemProps {\n module: Module;\n instant?: boolean;\n}\n\nexport const ModulePendingRemoval = ({\n instant,\n module,\n ...props\n}: ModulePendingRemovalProps) => {\n if (instant) {\n return (\n } />}\n {...props}\n />\n );\n }\n\n return (\n }\n {...props}\n />\n );\n};\n","import { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport { NETWORK, NETWORKS } from \"./networks\"\n\nexport function safeAppUrl(safeInfo: SafeInfo, appUrl: string) {\n const base = \"https://gnosis-safe.io\"\n const prefix = chainPrefix(safeInfo)\n const pathname = `/app/${prefix}:${safeInfo.safeAddress}/apps`\n const params = new URLSearchParams({ appUrl })\n\n return new URL(`${base}${pathname}?${params}`).href\n}\n\nexport function rolesV1AppUrl(safeInfo: SafeInfo, rolesAddress: string) {\n const base = \"https://roles-v1.gnosisguild.org\"\n const prefix = chainPrefix(safeInfo)\n\n return new URL(`${base}/#/${prefix}:${rolesAddress}`).href\n}\n\nexport function rolesV2AppUrl(safeInfo: SafeInfo, rolesAddress: string) {\n const base = \"https://roles.gnosisguild.org\"\n const prefix = chainPrefix(safeInfo)\n\n return new URL(`${base}/${prefix}:${rolesAddress}`).href\n}\n\nfunction chainPrefix(safeInfo: SafeInfo): string {\n return NETWORKS[safeInfo.chainId as NETWORK].shortName\n}\n","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Address } from \"components/ethereum/Address\"\nimport { Row } from \"components/layout/Row\"\n\nimport React from \"react\"\nimport { Module } from \"store/modules/models\"\nimport { PanelItemProps } from \"./PanelItem\"\nimport { rolesV1AppUrl } from \"utils/url\"\n\ninterface RoleModuleItemProps extends PanelItemProps {\n module: Module\n chainId: number\n}\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n textUnderlineOffset: \"2px\",\n \"&:hover\": {\n opacity: 0.5,\n },\n },\n}))\n\nexport const RolesV1ModuleItem: React.FC = ({ module }) => {\n const classes = useStyles()\n const { safe: safeInfo } = useSafeAppsSDK()\n\n return (\n
\n \n {module.name}\n \n\n \n \n {\n window.location.href = rolesV1AppUrl(safeInfo, module.address)\n }}\n underline=\"always\"\n >\n Edit Roles\n \n \n
\n )\n}\n","var _path, _path2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAddCircleIcon = function SvgAddCircleIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 16,\n height: 17,\n viewBox: \"0 0 16 17\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M14.6668 8.49992C14.6668 12.1818 11.6821 15.1666 8.00016 15.1666C4.31826 15.1666 1.3335 12.1818 1.3335 8.49992C1.3335 4.81802 4.31826 1.83325 8.00016 1.83325C11.6821 1.83325 14.6668 4.81802 14.6668 8.49992ZM2.66667 8.49988C2.66667 11.4454 5.05448 13.8332 8 13.8332C10.9455 13.8332 13.3333 11.4454 13.3333 8.49988C13.3333 5.55436 10.9455 3.16654 8 3.16654C5.05448 3.16654 2.66667 5.55436 2.66667 8.49988Z\",\n fill: \"#B2B5B2\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M8.6665 7.83341H10.6665C11.0347 7.83341 11.3332 8.13189 11.3332 8.50008C11.3332 8.86827 11.0347 9.16675 10.6665 9.16675H8.6665V11.1667C8.6665 11.5349 8.36803 11.8334 7.99984 11.8334C7.63165 11.8334 7.33317 11.5349 7.33317 11.1667V9.16675H5.33317C4.96498 9.16675 4.6665 8.86827 4.6665 8.50008C4.6665 8.13189 4.96498 7.83341 5.33317 7.83341H7.33317V5.83341C7.33317 5.46522 7.63165 5.16675 7.99984 5.16675C8.36803 5.16675 8.6665 5.46522 8.6665 5.83341V7.83341Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAddCircleIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/add-circle-icon.42a49a22.svg\";\nexport { ForwardRef as ReactComponent };","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Address } from \"components/ethereum/Address\"\nimport { Row } from \"components/layout/Row\"\n\nimport React from \"react\"\nimport { Module } from \"store/modules/models\"\nimport { PanelItemProps } from \"./PanelItem\"\nimport { rolesV2AppUrl } from \"utils/url\"\n\ninterface RoleModuleItemProps extends PanelItemProps {\n module: Module\n chainId: number\n}\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n textUnderlineOffset: \"2px\",\n \"&:hover\": {\n opacity: 0.5,\n },\n },\n}))\n\nexport const RolesV2ModuleItem: React.FC = ({ module }) => {\n const classes = useStyles()\n const { safe: safeInfo } = useSafeAppsSDK()\n\n return (\n
\n \n {module.name}\n \n\n \n \n {\n window.location.href = rolesV2AppUrl(safeInfo, module.address)\n }}\n underline=\"always\"\n >\n View Roles\n \n \n
\n )\n}\n","import { HashInfo } from \"../../../components/ethereum/HashInfo\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { PANEL_ITEM_CONTENT_HEIGHT, PanelItem, PanelItemProps } from \"./PanelItem\"\nimport React from \"react\"\nimport { Module, ModuleType } from \"../../../store/modules/models\"\nimport { DelayModuleItem } from \"./DelayModuleItem\"\nimport { isDelayModule } from \"../../../store/modules/helpers\"\nimport { ModuleList } from \"../ModuleList\"\nimport { Address } from \"../../../components/ethereum/Address\"\nimport { ModulePendingRemoval } from \"./ModulePendingRemovalItem\"\nimport { Badge } from \"../../../components/text/Badge\"\nimport { shortAddress } from \"../../../utils/string\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { RolesV1ModuleItem } from \"./RolesV1ModuleItem\"\nimport { RolesV2ModuleItem } from \"./RolesV2ModuleItem\"\n\ninterface ModuleItemProps extends PanelItemProps {\n remove?: boolean\n instant?: boolean\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n text: {\n lineHeight: 1,\n letterSpacing: \"1px\",\n },\n name: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n badge: {\n marginTop: theme.spacing(1),\n },\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n height: PANEL_ITEM_CONTENT_HEIGHT,\n },\n}))\n\ninterface ModuleItemContentProps extends ModuleItemProps {\n classes: Record\n}\n\nexport const ModuleItemContent = (props: ModuleItemContentProps) => {\n const { module, classes, ...panelItemProps } = props\n const { safe } = useSafeAppsSDK()\n if (isDelayModule(module)) {\n return \n }\n\n if (module.type === ModuleType.ROLES_V1) {\n return (\n \n )\n }\n if (module.type === ModuleType.ROLES_V2) {\n return (\n \n )\n }\n\n const ownerBadge =\n module.owner && module.owner !== safe.safeAddress ? (\n \n External Owner\n \n ) : null\n\n return (\n <>\n {module.name ? (\n \n {module.name}\n \n ) : null}\n \n {ownerBadge}\n \n )\n}\n\nexport const ModuleItem = (props: ModuleItemProps) => {\n const { module, remove = false, instant = false, onClick, ...panelItemProps } = props\n\n const classes = useStyles()\n\n if (remove) {\n return (\n \n )\n }\n\n return (\n \n }\n {...panelItemProps}\n >\n
\n \n
\n\n {module.subModules.length ? : null}\n \n )\n}\n","var _circle, _circle2, _circle3, _path, _path2, _path3, _path4, _path5;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgDaoModulePending = function SvgDaoModulePending(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 37,\n height: 36,\n viewBox: \"0 0 37 36\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 29,\n cy: 4.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 4,\n cy: 17.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 27,\n cy: 31.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path4 || (_path4 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M26.6668 17.5C26.6668 21.1819 23.6821 24.1667 20.0002 24.1667C16.3183 24.1667 13.3335 21.1819 13.3335 17.5C13.3335 13.8181 16.3183 10.8334 20.0002 10.8334C23.6821 10.8334 26.6668 13.8181 26.6668 17.5ZM14.6667 17.5C14.6667 20.4455 17.0545 22.8333 20 22.8333C22.9455 22.8333 25.3333 20.4455 25.3333 17.5C25.3333 14.5545 22.9455 12.1667 20 12.1667C17.0545 12.1667 14.6667 14.5545 14.6667 17.5Z\",\n fill: \"#B2B5B2\"\n })), _path5 || (_path5 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M20.6665 16.8333H22.6665C23.0347 16.8333 23.3332 17.1318 23.3332 17.5C23.3332 17.8681 23.0347 18.1666 22.6665 18.1666H20.6665V20.1666C20.6665 20.5348 20.368 20.8333 19.9998 20.8333C19.6316 20.8333 19.3332 20.5348 19.3332 20.1666V18.1666H17.3332C16.965 18.1666 16.6665 17.8681 16.6665 17.5C16.6665 17.1318 16.965 16.8333 17.3332 16.8333H19.3332V14.8333C19.3332 14.4651 19.6316 14.1666 19.9998 14.1666C20.368 14.1666 20.6665 14.4651 20.6665 14.8333V16.8333Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgDaoModulePending, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/dao-module-pending.3803c565.svg\";\nexport { ForwardRef as ReactComponent };","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgModuleInherit = function SvgModuleInherit(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 30,\n height: 7,\n viewBox: \"0 0 30 7\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1.28906 1.69727C5.32916 3.95696 10.0897 5.26087 15.1864 5.26087C20.283 5.26087 25.0436 3.95696 29.0837 1.69727\",\n strokeWidth: 2\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgModuleInherit, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/module-inherit.3008886e.svg\";\nexport { ForwardRef as ReactComponent };","import { useMemo } from \"react\"\nimport { SafeAppProvider } from \"@gnosis.pm/safe-apps-provider\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { ethers } from \"ethers\"\n\nconst useSafeAppsSDKWithProvider = () => {\n const { sdk, safe } = useSafeAppsSDK()\n const provider = useMemo(\n () => new ethers.providers.Web3Provider(new SafeAppProvider(safe, sdk)),\n [sdk, safe],\n )\n return { sdk, safe, provider }\n}\n\nexport default useSafeAppsSDKWithProvider\n","import React, { useEffect } from \"react\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getCurrentPendingModule,\n getPendingCreateModuleTransactions,\n getPendingModules,\n getSafeThreshold,\n} from \"../../store/modules/selectors\"\nimport {\n fetchModulesList,\n fetchPendingModules,\n setCurrentPendingModule,\n} from \"../../store/modules\"\nimport { ModulePendingItem } from \"./item/ModulePendingItem\"\nimport { LoadingIcon } from \"../../components/icons/LoadingIcon\"\nimport { ReactComponent as AddIcon } from \"../../assets/icons/add-circle-icon.svg\"\nimport { ReactComponent as ModulePendingImg } from \"../../assets/images/dao-module-pending.svg\"\nimport { getModuleContractMetadata } from \"../../utils/modulesValidation\"\nimport { getModuleName } from \"../../store/modules/helpers\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nexport const PendingModuleStates = () => {\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const dispatch = useRootDispatch()\n const currentPending = useRootSelector(getCurrentPendingModule)\n const pendingModuleTransactions = useRootSelector(getPendingModules)\n const pendingCreateModuleTransactions = useRootSelector(\n getPendingCreateModuleTransactions,\n )\n const safeThreshold = useRootSelector(getSafeThreshold)\n const isInstantExecution = safeThreshold === 1\n\n useEffect(() => {\n dispatch(fetchPendingModules(safe))\n }, [dispatch, safe])\n\n useEffect(() => {\n if (isInstantExecution && pendingModuleTransactions.length) {\n const interval = setInterval(() => dispatch(fetchPendingModules(safe)), 3000)\n return () => {\n clearInterval(interval)\n dispatch(\n fetchModulesList({\n provider,\n safeSDK: sdk,\n chainId: safe.chainId,\n safeAddress: safe.safeAddress,\n }),\n )\n }\n }\n }, [\n dispatch,\n isInstantExecution,\n sdk,\n safe,\n pendingModuleTransactions.length,\n provider,\n ])\n\n const image = isInstantExecution ? (\n } />\n ) : (\n \n )\n const linkText = isInstantExecution ? \"Transaction confirming...\" : \"Awaiting approval\"\n\n return (\n <>\n {pendingCreateModuleTransactions.map((pendingModule, index) => {\n const props = {\n key: index,\n instant: isInstantExecution,\n onClick: () => dispatch(setCurrentPendingModule(pendingModule)),\n active: currentPending?.address === pendingModule.address,\n }\n const metadata = getModuleContractMetadata(pendingModule.module)\n const name = getModuleName(metadata?.type)\n return (\n \n )\n })}\n \n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAddIcon = function SvgAddIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 13,\n height: 12,\n viewBox: \"0 0 13 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M7.22344 4.8H10.8234C11.4862 4.8 12.0234 5.33726 12.0234 6C12.0234 6.66274 11.4862 7.2 10.8234 7.2H7.22344V10.8C7.22344 11.4627 6.68618 12 6.02344 12C5.3607 12 4.82344 11.4627 4.82344 10.8V7.2H1.22344C0.560696 7.2 0.0234375 6.66274 0.0234375 6C0.0234375 5.33726 0.560696 4.8 1.22344 4.8H4.82344V1.2C4.82344 0.537258 5.3607 0 6.02344 0C6.68618 0 7.22344 0.537258 7.22344 1.2V4.8Z\",\n fill: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAddIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/add-icon.7ae47d81.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles, Typography } from \"@material-ui/core\"\nimport React, { useEffect } from \"react\"\nimport { Module } from \"../../store/modules/models\"\nimport { fetchModulesList, setCurrentModule } from \"../../store/modules\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getCurrentModule,\n getIsLoadingModules,\n getPendingModules,\n getPendingRemoveModuleTransactions,\n getSafeThreshold,\n} from \"../../store/modules/selectors\"\nimport { ReactComponent as AvatarEmptyIcon } from \"../../assets/icons/avatar-empty.svg\"\nimport { Skeleton } from \"@material-ui/lab\"\nimport { PANEL_ITEM_HEIGHT, PANEL_ITEM_MARGIN, PanelItem } from \"./item/PanelItem\"\nimport { ModuleItem } from \"./item/ModuleItem\"\nimport { resetNewTransaction } from \"../../store/transactionBuilder\"\nimport { PendingModuleStates } from \"./PendingModuleStates\"\nimport { Column } from \"../../components/layout/Column\"\nimport { isPendingModule } from \"../../store/modules/helpers\"\nimport { ReactComponent as ModuleStackIcon } from \"../../assets/icons/module-inherit.svg\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleListProps {\n modules: Module[]\n sub?: boolean\n}\n\nconst useStyles = makeStyles((theme) => ({\n subModules: {\n position: \"relative\",\n },\n line: {\n position: \"absolute\",\n borderColor: \"#6d6b5a\",\n borderStyle: \"solid\",\n borderBottomWidth: 2,\n borderLeftWidth: 2,\n borderTopWidth: 0,\n borderRightWidth: 0,\n borderBottomLeftRadius: 16,\n top: PANEL_ITEM_MARGIN - 6,\n left: -40,\n width: 32,\n },\n moduleStackIcon: {\n position: \"absolute\",\n top: 0,\n left: -54,\n zIndex: 100,\n stroke: \"#6d6b5a\",\n },\n emptyModulesText: {\n maxWidth: 200,\n },\n emptyImage: {\n border: \"1px solid rgba(255,255,255,0.2)\",\n borderRadius: \"50%\",\n padding: theme.spacing(0.5),\n },\n}))\n\nexport const ModuleList = ({ modules, sub = false }: ModuleListProps) => {\n const classes = useStyles()\n const { safe, sdk, provider } = useSafeAppsSDKWithProvider()\n\n const dispatch = useRootDispatch()\n const currentModule = useRootSelector(getCurrentModule)\n const modulesLoading = useRootSelector(getIsLoadingModules)\n const pendingModules = useRootSelector(getPendingModules)\n const safeThreshold = useRootSelector(getSafeThreshold)\n const pendingRemoveTxs = useRootSelector(getPendingRemoveModuleTransactions)\n\n const handleClick = (module: Module) => {\n dispatch(setCurrentModule(module))\n dispatch(resetNewTransaction())\n }\n\n const [intervalId, setIntervalId] = React.useState(null)\n\n useEffect(() => {\n if (intervalId == null) {\n const exec = () => {\n dispatch(\n fetchModulesList({\n provider,\n safeSDK: sdk,\n chainId: safe.chainId,\n safeAddress: safe.safeAddress,\n }),\n )\n }\n\n const intervalId = setInterval(exec, 10000)\n\n setIntervalId(intervalId)\n exec()\n }\n return () => {\n if (intervalId != null) {\n clearInterval(intervalId)\n }\n }\n }, [sdk, dispatch, safe, intervalId, provider])\n\n if (modulesLoading) {\n return (\n }>\n \n \n \n )\n }\n\n if (!modules.length && !pendingModules.length) {\n return (\n }\n >\n \n Modules will appear here once added\n \n \n )\n }\n\n const content = modules.map((module) => {\n const active = module.id === currentModule?.id\n const remove = pendingRemoveTxs.some((tx) => isPendingModule(module, tx))\n return (\n handleClick(module)}\n />\n )\n })\n\n if (sub) {\n const lines = modules.map((_, index) => {\n const previous = index && modules[index - 1]\n const subModulesCount = previous && previous.subModules.length\n const subModulesHeight = subModulesCount * PANEL_ITEM_HEIGHT\n\n const height =\n 1 +\n subModulesHeight +\n PANEL_ITEM_HEIGHT * (index + 1) +\n PANEL_ITEM_MARGIN * index -\n PANEL_ITEM_HEIGHT / 2 +\n 6\n return
\n })\n const arrow = modules.length ? (\n \n ) : null\n return (\n
\n {content}\n {arrow}\n {lines}\n
\n )\n }\n\n return (\n \n \n {content}\n \n )\n}\n","import React from \"react\";\n\nexport const Grow = () => {\n return
;\n};\n","import React from \"react\"\nimport { Button, makeStyles, Typography } from \"@material-ui/core\"\nimport { ModuleList } from \"./ModuleList\"\nimport { Row } from \"../../components/layout/Row\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getCurrentModule, getCurrentPendingModule, getModulesList } from \"../../store/modules/selectors\"\nimport { unsetCurrentModule } from \"../../store/modules\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport { ReactComponent as AddIcon } from \"../../assets/icons/add-icon.svg\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n hashInfo: {\n \"& p\": {\n color: theme.palette.text.primary + \" !important\",\n },\n },\n header: {\n padding: theme.spacing(0, 1, 2, 1),\n boxSizing: \"content-box\",\n minHeight: 40,\n alignItems: \"center\",\n },\n moduleList: {\n marginTop: theme.spacing(3),\n },\n}))\n\nexport const Panel = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const modulesList = useRootSelector(getModulesList)\n const currentModule = useRootSelector(getCurrentModule)\n const currentPending = useRootSelector(getCurrentPendingModule)\n\n const handleAddModule = () => {\n dispatch(unsetCurrentModule())\n }\n\n return (\n
\n \n Modules and Modifiers\n \n {currentModule || currentPending ? (\n }\n >\n Add\n \n ) : null}\n \n\n \n
\n )\n}\n\nexport default Panel\n","import { Button, ButtonProps, makeStyles } from \"@material-ui/core\";\nimport React from \"react\";\nimport classNames from \"classnames\";\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n color: theme.palette.secondary.main,\n },\n queryButton: {\n textTransform: \"none\",\n fontSize: 16,\n \"&.MuiButton-contained.Mui-disabled\": {\n backgroundColor: theme.palette.secondary.main,\n color: theme.palette.common.white,\n },\n \"&.MuiButton-outlinedSecondary.Mui-disabled\": {\n color: theme.palette.common.white,\n borderColor: theme.palette.common.white,\n },\n },\n buttonDisabled: {\n opacity: 0.5,\n },\n outlined: {\n color: theme.palette.common.white,\n padding: theme.spacing(0.75, 2),\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n transition: \"0.2s ease all\",\n \"&::before\": {\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n },\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n },\n },\n}));\n\nexport const ActionButton = ({ classes, className, ...props }: ButtonProps) => {\n const _classes = useStyles();\n return (\n \n );\n};\n","import { Transaction, SerializedTransaction } from \"./models\";\nimport { FunctionFragment, Interface } from \"@ethersproject/abi\";\nimport { Module } from \"../modules/models\";\n\nexport function serializeTransaction(\n moduleTransaction: Transaction\n): SerializedTransaction {\n return {\n ...moduleTransaction,\n func: moduleTransaction.func.format(\"full\"),\n };\n}\n\nexport function deserializeTransaction(\n moduleTransaction: SerializedTransaction\n): Transaction {\n const interf = new Interface([moduleTransaction.func]);\n return {\n ...moduleTransaction,\n func: FunctionFragment.from(interf.fragments[0]),\n };\n}\n\nexport function getRemoveModuleTxId(module: Module) {\n return `remove_${module.address}_${module.parentModule}`;\n}\n","import { RootState } from \"../index\";\nimport { deserializeTransaction } from \"./helpers\";\n\nexport function getAddTransaction(state: RootState) {\n return state.transactionBuilder.addTransaction;\n}\n\nexport function getTransactions(state: RootState) {\n return state.transactionBuilder.transactions.map(deserializeTransaction);\n}\n\nexport function getTransactionBuilderOpen(state: RootState) {\n return state.transactionBuilder.open;\n}\n","import React from \"react\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { HashInfo } from \"../../components/ethereum/HashInfo\"\nimport { ActionButton } from \"../../components/ActionButton\"\nimport { Address } from \"../../components/ethereum/Address\"\nimport { Module } from \"../../store/modules/models\"\nimport { disableModule } from \"services\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getPendingRemoveModuleTransactions } from \"../../store/modules/selectors\"\nimport { addTransaction, openTransactionBuilder } from \"../../store/transactionBuilder\"\nimport {\n getRemoveModuleTxId,\n serializeTransaction,\n} from \"../../store/transactionBuilder/helpers\"\nimport { Transaction } from \"../../store/transactionBuilder/models\"\nimport { SafeAbi } from \"../../services/helpers\"\nimport { ReactComponent as RemoveIcon } from \"../../assets/icons/delete-icon.svg\"\nimport { Interface } from \"@ethersproject/abi\"\nimport { getTransactions } from \"../../store/transactionBuilder/selectors\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleDetailHeaderProps {\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n header: {\n minHeight: 88,\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n padding: theme.spacing(3),\n },\n text: {\n marginLeft: \"16px !important\",\n color: theme.palette.text.primary + \" !important\",\n },\n addressType: {\n fontSize: \".75rem\",\n fontFamily: \"Roboto Mono\",\n },\n spacing: {\n marginLeft: theme.spacing(2),\n },\n removeButton: {},\n}))\n\nexport const ModuleDetailHeader = ({ module }: ModuleDetailHeaderProps) => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const { safe, provider } = useSafeAppsSDKWithProvider()\n const pendingRemoveModuleTransactions = useRootSelector(\n getPendingRemoveModuleTransactions,\n )\n const txBuildersTransaction = useRootSelector(getTransactions)\n\n const isRemoveTxOnQueue = txBuildersTransaction.some(\n (tx) => tx.id === getRemoveModuleTxId(module),\n )\n const isModuleToBeRemoved = pendingRemoveModuleTransactions\n .map((pending) => pending.address)\n .includes(module.address)\n const disabledRemoveButton = isRemoveTxOnQueue || isModuleToBeRemoved\n\n const removeModule = async () => {\n try {\n const { params } = await disableModule(\n provider,\n module.parentModule,\n safe.chainId,\n module.address,\n )\n const safeInterface = new Interface(SafeAbi)\n const disableModuleFunc = safeInterface.getFunction(\"disableModule\")\n const transaction: Transaction = {\n module,\n params,\n id: getRemoveModuleTxId(module),\n func: disableModuleFunc,\n to: module.parentModule,\n }\n dispatch(addTransaction(serializeTransaction(transaction)))\n dispatch(openTransactionBuilder())\n } catch (error) {\n console.warn(\"could not remove module\", error)\n }\n }\n\n return (\n
\n \n \n\n \n }\n >\n Remove\n \n
\n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgPlayIcon = function SvgPlayIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 21,\n height: 20,\n viewBox: \"0 0 21 20\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M15.2111 9.10557L8.44721 5.72361C7.78231 5.39116 7 5.87465 7 6.61803L7 13.382C7 14.1253 7.78231 14.6088 8.44722 14.2764L15.2111 10.8944C15.9482 10.5259 15.9482 9.4741 15.2111 9.10557Z\",\n fill: \"#FFFFFF\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgPlayIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/play-icon.aae3f5f2.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { makeStyles, PaperProps } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport classNames from \"classnames\";\n\ninterface CollapsableProps extends PaperProps {\n open?: boolean;\n content?: React.ReactElement;\n containerClassName?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(2),\n transition: \"0.2s ease all\",\n \"& + &\": {\n marginTop: theme.spacing(2),\n },\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n content: {\n marginTop: theme.spacing(2),\n },\n hide: {\n display: \"none\",\n },\n}));\n\nexport const Collapsable: React.FC = ({\n open = false,\n content,\n children,\n className,\n containerClassName,\n ...props\n}) => {\n const classes = useStyles();\n return (\n \n {children}\n {content ? (\n \n {content}\n
\n ) : null}\n \n );\n};\n","import React, { useRef, useState } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { validateFunctionParams } from \"../../utils/contracts\";\nimport { ParamInputProps } from \"./ParamInput\";\n\ntype ParamValue = { value: any; valid: boolean };\n\ninterface ContractQueryFormProps {\n func: FunctionFragment;\n defaultParams?: any[];\n\n children(props: {\n paramInputProps: ParamInputProps[];\n getParams: () => any[];\n areParamsValid: boolean;\n }): React.ReactElement;\n}\n\nexport const ContractQueryForm = ({\n defaultParams,\n func,\n children,\n}: ContractQueryFormProps) => {\n const params = useRef(\n func.inputs.map((_, index) => ({\n value:\n defaultParams && defaultParams[index] !== undefined\n ? defaultParams[index]\n : \"\",\n valid: true,\n }))\n );\n\n const validate = () => {\n return validateFunctionParams(\n func,\n params.current.map((_param) => _param.value)\n );\n };\n\n const [areParamsValid, setParamsValid] = useState(validate());\n\n const handleParamChange = (index: number, value: any, valid: boolean) => {\n params.current[index] = { value, valid };\n const _areParamsValid = params.current.every((param) => param.valid);\n setParamsValid(_areParamsValid && validate());\n };\n\n const paramInputProps: ParamInputProps[] = func.inputs.map((param, index) => {\n return {\n param: param,\n value: params.current[index].value,\n onChange: (value: any, valid: boolean) => {\n handleParamChange(index, value, valid);\n },\n };\n });\n\n const getParams = () => params.current.map((param) => param.value);\n\n return children({ paramInputProps, getParams, areParamsValid });\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { FunctionOutputs } from \"../../../hooks/useContractQuery\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { formatValue } from \"../../../utils/contracts\";\n\ninterface ContractFunctionResultProps {\n func: FunctionFragment;\n loading?: boolean;\n result?: FunctionOutputs;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n color: theme.palette.common.white,\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n padding: theme.spacing(2),\n },\n item: {\n \"& + &\": {\n marginTop: theme.spacing(1),\n },\n },\n label: {\n color: \"rgba(217, 212, 173, 0.9)\",\n },\n value: {\n overflowWrap: \"break-word\",\n },\n}));\n\nexport const ContractFunctionResult = ({\n func,\n loading = false,\n result,\n}: ContractFunctionResultProps) => {\n const classes = useStyles();\n if (loading) return ;\n if (!result) return null;\n return (\n \n {func.outputs?.map((param, index) => (\n
\n \n {param.name ? `${param.name} (${param.type})` : param.type}:{\" \"}\n \n \n {formatValue(param.baseType, result[index])}\n \n
\n ))}\n
\n );\n};\n","import React from \"react\";\nimport { Address } from \"../../../components/ethereum/Address\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport TimeAgo from \"timeago-react\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { FunctionOutputs } from \"../../../hooks/useContractQuery\";\nimport { CopyToClipboardBtn } from \"@gnosis.pm/safe-react-components\";\nimport { formatValue } from \"../../../utils/contracts\";\nimport classNames from \"classnames\";\n\ninterface ContractFunctionHeaderProps {\n date?: Date;\n func: FunctionFragment;\n loading?: boolean;\n showResult?: boolean;\n result?: FunctionOutputs;\n}\n\nconst useStyles = makeStyles((theme) => ({\n spaceLeft: {\n marginLeft: theme.spacing(1),\n },\n type: {\n fontFamily: \"Roboto Mono\",\n fontSize: \".75rem\",\n },\n queryType: {\n fontSize: \".75rem\",\n },\n}));\n\nexport const ContractFunctionHeader = ({\n date,\n func,\n result,\n showResult,\n loading = false,\n}: ContractFunctionHeaderProps) => {\n const classes = useStyles();\n\n if (loading) {\n return ;\n }\n\n if (showResult && result && result.length && func.outputs) {\n const { baseType, type } = func.outputs[0];\n const value = formatValue(baseType, result[0]);\n\n if (baseType === \"address\") {\n return (\n \n );\n }\n return (\n <>\n \n ({type})\n \n \n {value}\n \n \n \n );\n }\n\n if (date) {\n return (\n \n Queried \n \n );\n }\n\n return Query;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\n\ninterface ContractFunctionErrorProps {\n error?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n fontSize: 12,\n padding: theme.spacing(2),\n marginBottom: theme.spacing(2),\n color: theme.palette.error.main,\n borderRadius: theme.shape.borderRadius,\n borderColor: theme.palette.error.main,\n borderStyle: \"solid\",\n borderWidth: 2,\n wordWrap: \"break-word\",\n },\n}));\n\nexport const ContractFunctionError = ({\n error,\n}: ContractFunctionErrorProps) => {\n const classes = useStyles();\n if (!error) return null;\n return
{error}
;\n};\n","import React, { useState } from \"react\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ZodiacTextField } from \"zodiac-ui-components\"\nimport { TextFieldProps } from \"../input/TextField\"\nimport { formatParamValue } from \"../../utils/contracts\"\nimport { MenuItem } from \"@material-ui/core\"\nimport { BigNumber } from \"ethers\"\n\nexport interface ParamInputProps\n extends Omit {\n param: ParamType\n value?: string | boolean | BigNumber\n label?: string\n\n onChange(value: any, valid: boolean): void\n}\n\nfunction getLabel(param: ParamType) {\n if (param.name) {\n return `${param.name} (${param.type})`\n }\n return `(${param.type})`\n}\n\nfunction getDefaultValue(\n param: ParamType,\n defaultValue: ParamInputProps[\"value\"],\n): string {\n if (defaultValue !== undefined) {\n if (typeof defaultValue === \"object\") return JSON.stringify(defaultValue)\n return defaultValue.toString()\n }\n return param.baseType === \"boolean\" ? \"false\" : \"\"\n}\n\nexport const ParamInput = ({\n param,\n value: defaultValue,\n onChange,\n ...props\n}: ParamInputProps) => {\n if (props.defaultValue != null) {\n throw new Error(\n \"This is a controlled component, `defaultValue` should not be used. Use `value` instead.\",\n )\n }\n const [value, setValue] = useState(getDefaultValue(param, defaultValue))\n const [error, setError] = useState()\n\n const handleChange = (evt: React.ChangeEvent) => {\n const _value = evt.target.value\n setValue(_value)\n\n if (param.baseType === \"boolean\") {\n onChange(_value === \"true\", true)\n return\n }\n\n if (!_value.length) {\n onChange(_value, false)\n setError(undefined)\n return\n }\n\n try {\n const paramValue = formatParamValue(param, _value)\n onChange(paramValue, true)\n setError(undefined)\n } catch (error: any) {\n onChange(_value, false)\n setError(error?.message)\n }\n }\n\n if (param.baseType === \"boolean\") {\n return (\n \n True\n False\n \n )\n }\n\n return (\n \n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgChevronDown = function SvgChevronDown(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 18,\n height: 10,\n viewBox: \"0 0 18 10\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M10.0651 9.58417C9.77258 9.86274 9.38708 10.0013 9.00008 9.99992C8.61458 10.0013 8.22908 9.86274 7.93658 9.58417C7.93058 9.57846 7.87208 9.51846 7.86608 9.51274L0.439578 2.43703C-0.143922 1.88132 -0.143922 0.972744 0.439578 0.41703C1.02308 -0.138684 1.97708 -0.138684 2.56058 0.41703L9.00008 6.55132L15.4411 0.41703C16.0246 -0.138684 16.9786 -0.138684 17.5621 0.41703C18.1456 0.972744 18.1456 1.88132 17.5621 2.43703L10.1461 9.49846C10.1401 9.50417 10.0711 9.57846 10.0651 9.58417Z\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgChevronDown, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/chevron-down.0df60caa.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\nimport { ReactComponent as ChevronDownIcon } from \"../../assets/icons/chevron-down.svg\";\nimport React from \"react\";\n\nconst useStyles = makeStyles((theme) => ({\n arrowIcon: {\n cursor: \"pointer\",\n color: theme.palette.primary.main,\n fill: \"#B2B5B2\",\n width: 18,\n height: 10,\n \"&.rotate\": {\n transform: \"rotate(180deg)\",\n },\n },\n}));\n\ninterface ArrowIconProps extends React.SVGProps {\n up?: boolean;\n}\n\nexport const ArrowIcon = ({\n up = false,\n className,\n ...props\n}: ArrowIconProps) => {\n const classes = useStyles();\n return (\n \n );\n};\n","import React, { useCallback, useEffect, useState } from \"react\"\nimport { FunctionFragment } from \"@ethersproject/abi\"\nimport { Box, makeStyles, Typography } from \"@material-ui/core\"\nimport { Collapsable } from \"../../../components/Collapsable\"\nimport classNames from \"classnames\"\nimport { useContractQuery } from \"../../../hooks/useContractQuery\"\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\"\nimport { ContractFunctionResult } from \"./ContractFunctionResult\"\nimport { ContractFunctionHeader } from \"./ContractFunctionHeader\"\nimport { formatValue, isBasicFunction, isOneResult } from \"../../../utils/contracts\"\nimport { Row } from \"../../../components/layout/Row\"\nimport { ContractFunctionError } from \"./ContractFunctionError\"\nimport { ReactComponent as PlayIcon } from \"../../../assets/icons/play-icon.svg\"\nimport { ActionButton } from \"../../../components/ActionButton\"\nimport { ParamInput } from \"../../../components/ethereum/ParamInput\"\nimport { useRootSelector } from \"../../../store\"\nimport { getReloadCount } from \"../../../store/modules/selectors\"\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\"\nimport { Grow } from \"../../../components/layout/Grow\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ContractFunctionBlockProps {\n address: string\n func: FunctionFragment\n}\n\nconst useStyles = makeStyles((theme) => ({\n clickable: {\n cursor: \"pointer\",\n },\n expandIcon: {\n marginLeft: theme.spacing(2),\n },\n icon: {\n color: theme.palette.common.white,\n },\n queryButton: {\n marginTop: theme.spacing(2),\n },\n title: {\n marginRight: theme.spacing(1),\n },\n}))\n\nexport const ContractFunctionQueryBlock = ({\n address,\n func,\n}: ContractFunctionBlockProps) => {\n const classes = useStyles()\n const reloadCount = useRootSelector(getReloadCount)\n const { safe, provider } = useSafeAppsSDKWithProvider()\n\n const [open, setOpen] = useState(false)\n const [lastQueryDate, setLastQueryDate] = useState()\n\n const { loading, result, fetch, error } = useContractQuery()\n\n const isBasic = isBasicFunction(func)\n const oneResult = isOneResult(func)\n\n const baseType = oneResult && func.outputs ? func.outputs[0].baseType : \"\"\n const resultLength =\n result === undefined || !oneResult ? 0 : formatValue(baseType, result[0]).length\n\n const execQuery = useCallback(\n (params?: any[]) => {\n setLastQueryDate(undefined)\n fetch(provider, safe.chainId, address, [func], func.name, params)\n },\n [address, fetch, func, safe.chainId, provider],\n )\n\n useEffect(() => {\n if (!loading && result) {\n setLastQueryDate(new Date())\n }\n }, [loading, result])\n\n useEffect(() => {\n if (isBasic) {\n execQuery()\n }\n }, [execQuery, isBasic, reloadCount])\n\n const maxResultLength = 60\n const showResultOnHeader = oneResult && resultLength < maxResultLength && !error\n const collapsable = !showResultOnHeader || !isBasic\n\n const content = (\n <>\n \n {!showResultOnHeader ? (\n \n ) : null}\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n <>\n {paramInputProps.map((props, index) => (\n \n \n \n ))}\n {paramInputProps.length ? (\n execQuery(getParams())}\n startIcon={}\n >\n Run Query\n \n ) : null}\n \n )}\n \n \n )\n\n return (\n \n setOpen(!open)}\n >\n {func.name}\n \n \n {collapsable ? : null}\n \n \n )\n}\n","import { useCallback, useState } from \"react\";\nimport { callContract } from \"../services\";\nimport { BigNumber } from \"ethers\";\n\nexport type FunctionOutputs = (string | BigNumber)[];\n\nexport const useContractQuery = () => {\n const [loading, setLoading] = useState(false);\n const [result, setResult] = useState();\n const [error, setError] = useState();\n\n const fetch = useCallback((...params: Parameters) => {\n setLoading(true);\n setResult(undefined);\n callContract(...params)\n .then((response) => {\n setResult(response);\n setError(undefined);\n })\n .catch((error) => {\n setError(error.message);\n setResult(undefined);\n })\n .finally(() => setLoading(false));\n }, []);\n\n return { loading, error, result, fetch };\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Collapsable } from \"../../../components/Collapsable\";\nimport { ContractFunctionHeader } from \"./ContractFunctionHeader\";\nimport { isBasicFunction, isOneResult } from \"../../../utils/contracts\";\nimport { Row } from \"../../../components/layout/Row\";\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\";\nimport { Grow } from \"../../../components/layout/Grow\";\n\ninterface ContractFunctionPreviewBlockProps {\n func: FunctionFragment;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n opacity: 0.5,\n },\n expandIcon: {\n marginLeft: theme.spacing(2),\n },\n icon: {\n color: theme.palette.secondary.main,\n },\n title: {\n marginRight: theme.spacing(1),\n },\n}));\n\nfunction getPlaceholderValue(func: FunctionFragment): string {\n if (!isOneResult(func) || !func.outputs) return \"\";\n const { baseType } = func.outputs[0];\n\n if (baseType.includes(\"int\")) return \"0\";\n if (baseType === \"bool\") return \"true\";\n return \"0x0000000000000000000000000000000000000000\";\n}\n\nexport const ContractFunctionPreviewBlock = ({\n func,\n}: ContractFunctionPreviewBlockProps) => {\n const classes = useStyles();\n\n const isBasic = isBasicFunction(func);\n const oneResult = isOneResult(func);\n\n const shrink = isBasic && oneResult;\n\n return (\n \n \n {func.name}\n \n \n {!shrink ? : null}\n \n \n );\n};\n","import React, { useMemo } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { ContractFunctionQueryBlock } from \"./ContractFunctionQueryBlock\";\nimport { getReadFunction } from \"../../../utils/contracts\";\nimport { ContractFunctionPreviewBlock } from \"./ContractFunctionPreviewBlock\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ntype ModuleListFunctionsProps = {\n address: string;\n abi: ContractInterface;\n preview?: boolean;\n};\n\nexport const ContractReadFunctionsList = ({\n abi,\n address,\n preview,\n}: ModuleListFunctionsProps) => {\n const readFunctions: FunctionFragment[] = useMemo(\n () => getReadFunction(abi),\n [abi]\n );\n\n return (\n <>\n {readFunctions.map((func) => {\n if (preview) {\n return ;\n }\n\n return (\n \n );\n })}\n \n );\n};\n","import React from \"react\"\nimport {\n Grid,\n GridProps,\n InputBase,\n InputLabel,\n makeStyles,\n StandardTextFieldProps,\n TextField as MUITextField,\n Tooltip,\n withStyles,\n} from \"@material-ui/core\"\nimport classNames from \"classnames\"\nimport { colors } from \"zodiac-ui-components\"\nimport HelpOutline from \"@material-ui/icons/HelpOutline\"\n\nconst StyledTextField = withStyles((theme) => ({\n root: {\n \"& label.Mui-focused\": {\n position: \"relative\",\n transform: \"none\",\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n \"& .MuiInputBase-root\": {\n marginTop: 0,\n minHeight: \"37px\",\n },\n \"& .MuiSelect-select:focus\": {\n backgroundColor: \"transparent\",\n },\n },\n}))(MUITextField)\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: \"4px\",\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n icon: {\n fontSize: \"1rem\",\n },\n append: {\n display: \"flex\",\n alignItems: \"center\",\n padding: theme.spacing(1),\n borderWidth: 1,\n borderStyle: \"solid\",\n borderLeftWidth: 0,\n },\n primary: {\n borderColor: theme.palette.primary.light,\n },\n secondary: {\n borderColor: colors.tan[300],\n },\n error: {\n background: \"rgba(244, 67, 54, 0.1)\",\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n },\n}))\n\nexport interface TextFieldProps\n extends Omit {\n label?: string\n append?: React.ReactElement | string\n AppendProps?: GridProps\n variantAppend?: \"primary\" | \"secondary\" | \"error\"\n tooltipMsg?: string\n}\n\nexport const TextField = ({\n InputProps,\n InputLabelProps,\n label,\n append,\n variantAppend,\n AppendProps,\n tooltipMsg,\n ...props\n}: TextFieldProps) => {\n const classes = useStyles()\n\n const handleRoot = () => {\n switch (variantAppend) {\n case \"primary\":\n return classes.primary\n\n case \"secondary\":\n return classes.secondary\n\n case \"error\":\n return classes.error\n }\n }\n\n if (props.select || !append) {\n return (\n \n )\n }\n\n return (\n
\n \n \n \n {label}\n \n \n {tooltipMsg && (\n \n \n \n \n \n )}\n \n \n \n \n \n \n {append}\n \n \n
\n )\n}\n","import { useEffect, useState } from \"react\"\n\nconst useKeyPress = (targetKey: string) => {\n const [keyPressed, setKeyPressed] = useState(false)\n // If pressed key is our target key then set to true\n function downHandler({ key }: { key: string }) {\n if (key === targetKey) {\n setKeyPressed(true)\n }\n }\n // If released key is our target key then set to false\n const upHandler = ({ key }: { key: string }) => {\n if (key === targetKey) {\n setKeyPressed(false)\n }\n }\n\n useEffect(() => {\n window.addEventListener(\"keydown\", downHandler)\n window.addEventListener(\"keyup\", upHandler)\n return () => {\n window.removeEventListener(\"keydown\", downHandler)\n window.removeEventListener(\"keyup\", upHandler)\n }\n // eslint-disable-next-line\n }, [])\n\n return keyPressed\n}\n\nexport default useKeyPress\n","import React, { useEffect, useState } from \"react\"\nimport { Box, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { BigNumber, BigNumberish } from \"ethers\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { TextField } from \"./TextField\"\nimport { colors } from \"zodiac-ui-components\"\nimport useKeyPress from \"hooks/useKeyPress\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport ReportProblemOutlinedIcon from \"@material-ui/icons/ReportProblemOutlined\"\n\nexport const unitConversion = {\n seconds: 1,\n minutes: 60,\n hours: 3600,\n days: 86400,\n months: 2592000, // 30 Days\n}\ntype Unit = keyof typeof unitConversion\n\ninterface TimeSelectProps {\n tooltipMsg?: string\n defaultValue?: BigNumberish\n defaultUnit?: Unit\n value?: string\n valueUnit?: Unit\n label: string\n variant?: \"primary\" | \"secondary\" | \"error\"\n alertType?: \"error\" | \"warning\"\n onChange(time: string, unit: Unit): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n select: {\n padding: 0,\n border: 0,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"120px\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n primary: {\n borderColor: theme.palette.primary.light,\n },\n secondary: {\n borderColor: colors.tan[300],\n },\n error: {\n background: \"rgba(244, 67, 54, 0.1)\",\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n },\n}))\n\nfunction calculateTime(amount: string, unit: Unit): BigNumber {\n return BigNumber.from(amount).mul(unitConversion[unit])\n}\n\nexport const TimeSelect = ({\n onChange,\n defaultUnit = \"hours\",\n defaultValue = \"0\",\n value,\n valueUnit,\n label,\n variant = \"primary\",\n tooltipMsg,\n alertType,\n}: TimeSelectProps) => {\n const classes = useStyles()\n const tabPress = useKeyPress(\"Tab\")\n const [unit, setUnit] = useState(defaultUnit)\n const [amount, setAmount] = useState(\n BigNumber.from(defaultValue).div(unitConversion[unit]).toString(),\n )\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleAmountChange = (_amount: string) => {\n try {\n const newAmount = calculateTime(_amount || \"0\", unit)\n setAmount(_amount)\n onChange(newAmount.toString(), unit)\n } catch (err) {\n console.warn(\"invalid time\")\n }\n }\n\n const handleAdornment = () => {\n if (alertType) {\n switch (alertType) {\n case \"error\":\n return \n\n case \"warning\":\n return \n }\n }\n return null\n }\n\n const handleRoot = () => {\n switch (variant) {\n case \"primary\":\n return classes.primary\n\n case \"secondary\":\n return classes.secondary\n\n case \"error\":\n return classes.error\n }\n }\n\n const handleUnitChange = (newUnit: Unit) => {\n handleClose()\n setUnit(newUnit)\n if (amount) onChange(calculateTime(amount, newUnit).toString(), newUnit)\n }\n\n useEffect(() => {\n if (tabPress && open) {\n handleClose()\n }\n }, [tabPress, open])\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n useEffect(() => {\n if (value && valueUnit) {\n const parsedValue = BigNumber.from(value).div(unitConversion[valueUnit]).toString()\n if (parsedValue !== amount) {\n setAmount(parsedValue)\n }\n if ([\"hours\", \"days\"].includes(unit) && valueUnit !== unit) {\n setUnit(valueUnit)\n }\n }\n }, [value, valueUnit, amount, unit])\n\n return (\n handleAmountChange(evt.target.value),\n startAdornment: handleAdornment(),\n }}\n AppendProps={{\n className: classes.dropdownContainer,\n }}\n append={\n value as string}\n onChange={(evt) => handleUnitChange(evt.target.value as Unit)}\n >\n {Object.keys(unitConversion).map((unit) => (\n \n {unit}\n \n \n \n ))}\n \n }\n />\n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgArrowUpIcon = function SvgArrowUpIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 11,\n height: 13,\n viewBox: \"0 0 11 13\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M8.79066 6.19787L6.50066 3.90787V11.4949C6.50066 12.0449 6.05066 12.4949 5.50066 12.4949C4.94966 12.4949 4.50066 12.0449 4.50066 11.4949V3.90787L2.20966 6.19787C1.82066 6.58687 1.18466 6.58687 0.795656 6.19787C0.406656 5.80887 0.406656 5.17287 0.795656 4.78387L4.79366 0.786873C4.85166 0.726872 4.92566 0.694874 4.99366 0.653873C5.03566 0.628874 5.06966 0.592874 5.11566 0.572873C5.15666 0.554873 5.20266 0.554873 5.24566 0.544873C5.45766 0.487873 5.68166 0.488873 5.88566 0.572873C5.92966 0.591873 5.96266 0.626873 6.00366 0.651873C6.07366 0.692873 6.14666 0.725873 6.20766 0.786873L10.2047 4.78387C10.5937 5.17287 10.5937 5.80887 10.2047 6.19787C9.81566 6.58787 9.17966 6.58787 8.79066 6.19787Z\",\n fill: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgArrowUpIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/arrow-up-icon.7e5a12da.svg\";\nexport { ForwardRef as ReactComponent };","import {\n ParamInput,\n ParamInputProps,\n} from \"../../../components/ethereum/ParamInput\";\nimport React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { TimeSelect } from \"../../../components/input/TimeSelect\";\nimport { BigNumberish } from \"ethers\";\n\ninterface TransactionFieldProps {\n param: ParamInputProps;\n func: FunctionFragment;\n}\n\nexport const TransactionField = ({ param, func }: TransactionFieldProps) => {\n if (func.inputs.length === 1) {\n const [input] = func.inputs;\n const isTimeField = [\"setTxCooldown\", \"setTxExpiration\"].includes(\n func.name\n );\n const isTime = isTimeField && input.type.includes(\"int\");\n if (isTime) return ;\n }\n\n return ;\n};\n\nexport const TransactionTimeField = ({\n label,\n value,\n onChange,\n ...props\n}: ParamInputProps) => {\n const defaultValue = value || \"0\";\n return (\n onChange(time, true)}\n />\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles, MenuItem, Typography } from \"@material-ui/core\";\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\";\nimport { ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\";\nimport { getWriteFunction } from \"../../../utils/contracts\";\nimport classNames from \"classnames\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { ActionButton } from \"../../../components/ActionButton\";\nimport { useRootDispatch, useRootSelector } from \"../../../store\";\nimport { getAddTransaction } from \"../../../store/transactionBuilder/selectors\";\nimport { resetNewTransaction } from \"../../../store/transactionBuilder\";\nimport { getCurrentModule } from \"../../../store/modules/selectors\";\nimport { TransactionField } from \"./TransactionField\";\nimport { ReactComponent as AddIcon } from \"../../../assets/icons/add-icon.svg\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface AddTransactionBlockProps {\n abi: ContractInterface;\n\n onAdd(transaction: Transaction): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n greyText: {\n \"& select\": {\n color: theme.palette.primary.main,\n },\n },\n icon: {\n color: theme.palette.common.white,\n },\n addButton: {\n marginTop: theme.spacing(2),\n },\n header: {\n padding: theme.spacing(1),\n marginBottom: theme.spacing(1.5),\n },\n text: {\n maxWidth: 366,\n },\n content: {\n padding: theme.spacing(1.5),\n },\n field: {\n marginTop: theme.spacing(2.5),\n },\n}));\n\ntype TransactionFieldsProps = {\n func?: FunctionFragment;\n defaultParams?: any[];\n} & Pick;\n\nconst TransactionFields = ({\n func,\n onAdd,\n defaultParams,\n}: TransactionFieldsProps) => {\n const classes = useStyles();\n const module = useRootSelector(getCurrentModule);\n\n if (!func) {\n return (\n }\n >\n Add this transaction\n \n );\n }\n\n const handleAdd = (params: any[]) => {\n if (!module) return;\n onAdd({\n func,\n params,\n module,\n to: module.address,\n id: `${func.name}_${new Date().getTime()}`,\n });\n };\n\n return (\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n <>\n {paramInputProps.map((props, index) => (\n
\n \n
\n ))}\n handleAdd(getParams())}\n disabled={!areParamsValid}\n className={classes.addButton}\n startIcon={}\n >\n Add this transaction\n \n \n )}\n
\n );\n};\n\nconst getSelectedFunction = (\n writeFunctions: FunctionFragment[],\n selectedFunc?: string\n): number => {\n if (selectedFunc) {\n const index = writeFunctions.findIndex(\n (func) => func.format() === selectedFunc\n );\n if (index >= 0) return index;\n }\n return -1;\n};\n\nexport const AddTransactionBlock = ({\n abi,\n onAdd,\n}: AddTransactionBlockProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n const writeFunctions = useMemo(() => getWriteFunction(abi), [abi]);\n const { func: selectedFunc, params: defaultParams } =\n useRootSelector(getAddTransaction);\n\n const [funcIndex, setFuncIndex] = useState(() =>\n getSelectedFunction(writeFunctions, selectedFunc)\n );\n\n useEffect(() => {\n if (selectedFunc)\n setFuncIndex(getSelectedFunction(writeFunctions, selectedFunc));\n }, [selectedFunc, writeFunctions]);\n\n const handleAdd = (transaction: Transaction) => {\n setFuncIndex(-1);\n onAdd(transaction);\n };\n\n const handleFuncChange = (event: React.ChangeEvent) => {\n setFuncIndex(parseInt(event.target.value));\n dispatch(resetNewTransaction());\n };\n\n return (\n <>\n \n \n Add Transaction\n \n \n Add multiple transactions here, and we will bundle them together into\n a single transaction, to save you gas.\n \n \n\n \n \n Select function\n {writeFunctions.map((func, index) => (\n \n {func.name}\n \n ))}\n \n \n \n \n );\n};\n","import React from \"react\";\nimport {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupProps,\n} from \"@material-ui/lab\";\nimport { withStyles } from \"@material-ui/core\";\n\nconst StyledToggleButton = withStyles((theme) => ({\n root: {\n width: \"50%\",\n padding: theme.spacing(1, 2.5),\n \"& span\": {\n fontSize: 16,\n textTransform: \"none\",\n color: theme.palette.text.primary + \" !important\",\n },\n },\n selected: {\n backgroundColor: theme.palette.secondary.main + \" !important\",\n },\n}))(ToggleButton);\n\ninterface ContractOperationToggleButtonsProps extends ToggleButtonGroupProps {\n disabled?: boolean;\n}\n\nexport const ContractOperationToggleButtons = ({\n disabled = false,\n ...props\n}: ContractOperationToggleButtonsProps) => {\n return (\n \n \n Read Contract\n \n \n Write Contract\n \n \n );\n};","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\";\nimport { ContractReadFunctionsList } from \"./ContractReadFunctionsList\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { setOperation } from \"../../../store/modules\";\nimport { useRootDispatch, useRootSelector } from \"../../../store\";\nimport classNames from \"classnames\";\nimport { Operation } from \"../../../store/modules/models\";\nimport { getOperation } from \"../../../store/modules/selectors\";\nimport { AddTransactionBlock } from \"../transaction/AddTransactionBlock\";\nimport { addTransaction } from \"../../../store/transactionBuilder\";\nimport { serializeTransaction } from \"../../../store/transactionBuilder/helpers\";\nimport { ContractOperationToggleButtons } from \"../ContractOperationToggleButtons\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface ContractInteractionsProps {\n address: string;\n abi: ContractInterface;\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(2),\n marginTop: theme.spacing(3),\n background: colors.tan[100],\n },\n hide: {\n display: \"none\",\n },\n}));\n\nexport const ContractInteractions = ({\n address,\n abi,\n}: ContractInteractionsProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n const operation = useRootSelector(getOperation);\n\n const handleOperationChange = (operation?: Operation) => {\n if (operation) dispatch(setOperation(operation));\n };\n\n const handleAddTransaction = (transaction: Transaction) => {\n dispatch(addTransaction(serializeTransaction(transaction)));\n };\n\n return (\n <>\n handleOperationChange(value)}\n />\n\n \n
\n \n
\n
\n \n
\n
\n \n );\n};\n","import React from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { Link } from \"../../components/text/Link\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { getNetworkExplorerInfo } from \"../../utils/explorers\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(2.5),\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n link: {\n fontSize: 16,\n },\n}))\n\nexport const ModuleNoAvailable = () => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const { verifyUrl } = getNetworkExplorerInfo(safe.chainId) || {}\n\n return (\n \n \n No Read or Write functions available\n \n \n We couldn't find an ABI and didn't recognize it as one of the known Zodiac\n contracts.\n \n \n Verify this contract on Etherscan to fix this.\n \n \n )\n}\n","import React, { useEffect, useState } from \"react\"\nimport { ContractInteractions } from \"./contract/ContractInteractions\"\nimport { getModuleData } from \"../../utils/contracts\"\nimport { Module } from \"../../store/modules/models\"\nimport { ModuleNoAvailable } from \"./ModuleNoAvailable\"\nimport { Skeleton } from \"@material-ui/lab\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleInteractionsProps {\n module: Module\n}\n\nexport const ModuleInteractions = ({ module }: ModuleInteractionsProps) => {\n const { safe, sdk, provider } = useSafeAppsSDKWithProvider()\n const [loading, setLoading] = useState(true)\n const [abi, setABI] = useState()\n\n useEffect(() => {\n setLoading(true)\n setABI(undefined)\n getModuleData(provider, sdk, safe.chainId, module.address)\n .then(({ abi }) => setABI(abi))\n .catch((error) => console.warn(\"getModuleABI\", error))\n .finally(() => setLoading(false))\n }, [module, safe, sdk, provider])\n\n if (loading) return \n\n if (!abi) return \n\n return \n}\n","import React from \"react\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { ModuleDetailHeader } from \"./ModuleDetailHeader\"\nimport { ModuleInteractions } from \"./ModuleInteractions\"\nimport { Module } from \"../../store/modules/models\"\n\ninterface ModuleDetailsProps {\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(0, 2, 2, 2),\n },\n}))\n\nexport const ModuleDetails = ({ module }: ModuleDetailsProps) => {\n const classes = useStyles()\n\n return (\n <>\n \n
\n \n
\n \n )\n}\n\nexport default ModuleDetails\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\nconst useStyles = makeStyles((theme) => ({\n tag: {\n display: \"inline-block\",\n borderRadius: 8,\n lineHeight: 1,\n padding: theme.spacing(0.75, 0.5),\n margin: theme.spacing(0, 1, 1, 0),\n backgroundColor: \"rgba(0,20,40,0.5)\",\n color: theme.palette.common.white,\n },\n}));\n\nexport const Tag: React.FC> = ({\n children,\n className,\n ...props\n}) => {\n const classes = useStyles();\n return (\n
\n {children}\n
\n );\n};\n","import React from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport { BadgeIconProps } from \"zodiac-ui-components/lib/components/Icons/BadgeIcon/BadgeIcon\"\nimport classNames from \"classnames\"\nimport { Tag } from \"components/text/Tag\"\n\ninterface ModuleButtonProps extends BadgeIconProps {\n title: string\n description: string\n available: boolean\n deprecated?: boolean\n className?: string\n onClick(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n userSelect: \"none\",\n padding: theme.spacing(2),\n cursor: \"pointer\",\n transition: \"0.2s ease all\",\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n badgeIcon: {\n background: colors.sepia[100],\n marginBottom: theme.spacing(1),\n },\n title: {\n marginBottom: theme.spacing(0.5),\n },\n}))\n\nexport const ModuleButton = ({\n title,\n description,\n icon,\n available,\n deprecated,\n className,\n onClick,\n}: ModuleButtonProps) => {\n const classes = useStyles()\n\n if (!available) return null\n\n return (\n \n \n \n {title}\n \n {deprecated && Deprecated}\n \n {description}\n \n \n )\n}\n","import React from \"react\";\nimport { Tag } from \"../text/Tag\";\n\ninterface TagListProps {\n tags: string[];\n style?: React.CSSProperties;\n className?: string;\n}\n\nexport const TagList = ({ tags, className, style }: TagListProps) => {\n return (\n
\n {tags.map((tag) => (\n \n {tag}\n \n ))}\n
\n );\n};\n","var _rect, _path, _rect2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckboxChecked = function SvgCheckboxChecked(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 32,\n height: 32,\n viewBox: \"0 0 32 32\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _rect || (_rect = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n fill: \"#E0C5AD\",\n fillOpacity: 0.1\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M10 17L14 21L23 11\",\n stroke: \"white\",\n strokeWidth: 2,\n strokeLinejoin: \"round\"\n })), _rect2 || (_rect2 = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n stroke: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckboxChecked, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkbox-checked.6146c37e.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\"\nimport { ButtonProps as MuiButtonProps, Fade, makeStyles, Modal, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, ZodiacPaper } from \"zodiac-ui-components\"\nimport { BadgeIconProps } from \"zodiac-ui-components/lib/components/Icons/BadgeIcon/BadgeIcon\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { Icon } from \"@gnosis.pm/safe-react-components\"\nimport classNames from \"classnames\"\nimport { Link } from \"../../../../components/text/Link\"\nimport { TagList } from \"../../../../components/list/TagList\"\nimport { Row } from \"../../../../components/layout/Row\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\n\ninterface AddModuleModalProps extends BadgeIconProps {\n open: boolean\n title: string\n description?: string\n tags?: string[]\n readMoreLink?: string\n ButtonProps?: MuiButtonProps\n warning?: React.ReactNode\n hideButton?: boolean\n\n onAdd?(): void\n\n onClose?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n outline: \"none\",\n maxWidth: 380,\n margin: theme.spacing(14, 1, 1, 1),\n padding: theme.spacing(2),\n backgroundColor: \"rgba(78, 72, 87, 0.8)\",\n },\n modal: {\n position: \"absolute !important\" as \"absolute\",\n paddingBottom: theme.spacing(2),\n overflow: \"auto\",\n alignItems: \"flex-start\",\n },\n backdrop: {\n backdropFilter: \"blur(4px)\",\n },\n description: {\n marginTop: theme.spacing(1),\n },\n gutterBottom: {\n marginBottom: theme.spacing(3),\n },\n row: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n center: {\n justifyContent: \"center\",\n },\n imageContainer: {\n marginRight: theme.spacing(2),\n minWidth: 68,\n },\n infoContainer: {\n flexGrow: 1,\n },\n readMore: {\n display: \"block\",\n marginTop: theme.spacing(1.5),\n fontSize: 16,\n },\n loader: {\n display: \"block\",\n margin: \"0 auto\",\n },\n warningIcon: {\n marginRight: theme.spacing(1),\n \"& .icon-color\": {\n fill: \"#E0B325 !important\",\n },\n },\n warningText: {\n color: \"#E0B325\",\n },\n}))\n\nexport const AddModuleModal: React.FC = ({\n open,\n title,\n description,\n onAdd,\n tags = [],\n icon,\n readMoreLink,\n onClose,\n children,\n ButtonProps,\n warning,\n hideButton = false,\n}) => {\n const classes = useStyles()\n return (\n \n \n \n
\n \n
\n \n {title}\n \n\n \n\n {description ? (\n \n {description}\n \n ) : null}\n\n {warning ? (\n \n \n \n {warning}\n \n \n ) : null}\n\n {readMoreLink ? (\n \n Read more here\n \n ) : null}\n
\n
\n\n {children ?
{children}
: null}\n\n {hideButton ? null : (\n } onClick={onAdd} {...ButtonProps}>\n Add Module\n \n )}\n
\n
\n \n )\n}\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport { Radio as MUIRadio, RadioProps } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n color: theme.palette.text.secondary,\n \"&:hover\": {\n background: \"none\",\n },\n },\n}));\n\nexport const Radio = ({ ...props }: RadioProps) => {\n const classes = useStyles();\n\n return (\n \n );\n};\n","var _rect, _rect2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckboxUnchecked = function SvgCheckboxUnchecked(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 32,\n height: 32,\n viewBox: \"0 0 32 32\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _rect || (_rect = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n fill: \"#E0C5AD\",\n fillOpacity: 0.1\n })), _rect2 || (_rect2 = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n stroke: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckboxUnchecked, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkbox-unchecked.5c1a7eb5.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport {\n Checkbox as MUICheckbox,\n CheckboxProps,\n makeStyles,\n} from \"@material-ui/core\";\nimport { ReactComponent as CheckMarkCheckedIcon } from \"../../assets/icons/checkbox-checked.svg\";\nimport { ReactComponent as CheckMarkUncheckedIcon } from \"../../assets/icons/checkbox-unchecked.svg\";\n\nconst useStyles = makeStyles(() => ({\n root: {\n padding: 0,\n backgroundColor: \"transparent !important\",\n borderRadius: 0,\n },\n}));\n\nexport const Checkbox = ({ ...props }: CheckboxProps) => {\n const classes = useStyles();\n\n return (\n }\n checkedIcon={}\n classes={{ root: classes.root }}\n {...props}\n />\n );\n};\n","import React, { useState } from \"react\"\nimport { Row } from \"../../../../components/layout/Row\"\nimport { Radio } from \"../../../../components/input/Radio\"\nimport { Checkbox } from \"../../../../components/input/Checkbox\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { Badge } from \"../../../../components/text/Badge\"\nimport { Address } from \"../../../../components/ethereum/Address\"\nimport classNames from \"classnames\"\nimport { formatDuration } from \"../../../../utils/string\"\nimport { Column } from \"../../../../components/layout/Column\"\nimport { Module, ModuleType } from \"../../../../store/modules/models\"\nimport { isDelayModule } from \"../../../../store/modules/helpers\"\n\ninterface AttachModuleFormProps {\n modules: Module[]\n value?: string\n description?: React.ReactNode\n type: ModuleType\n\n onChange(address?: string): void\n}\n\nconst defaultDescription = (\n This will add a timedelay to any transactions created by this module.\n)\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n marginLeft: theme.spacing(1.5),\n },\n item: {\n marginTop: theme.spacing(2),\n },\n text: {\n fontSize: 12,\n },\n delayText: {\n marginBottom: theme.spacing(0.5),\n },\n}))\n\nexport const AttachModuleForm = ({\n modules,\n value,\n description = defaultDescription,\n type,\n onChange,\n}: AttachModuleFormProps) => {\n const classes = useStyles()\n const [checked, setChecked] = useState(false)\n\n const handleCheck = () => {\n if (checked) onChange(undefined)\n setChecked(!checked)\n }\n\n return (\n \n \n
\n Attach to {type.replace(/^\\w/, (c) => c.toUpperCase())} Module\n {description}\n\n {checked\n ? modules.map((module) => (\n \n onChange(module.address)} />\n \n {isDelayModule(module) ? (\n \n {formatDuration(module.expiration)} delay\n \n ) : null}\n \n \n \n ))\n : null}\n
\n
\n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployTellorModule, getTellorOracle } from \"../../../../services\"\nimport { useRootSelector } from \"../../../../store\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { getDelayModules } from \"../../../../store/modules/selectors\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { ModuleType } from \"../../../../store/modules/models\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface TellorModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface TellorModuleParams {\n owner: string\n oracle: string\n cooldown: string\n expiration: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const TellorModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: TellorModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const delayModules = useRootSelector(getDelayModules)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [params, setParams] = useState({\n owner: safe.safeAddress,\n oracle: getTellorOracle(safe.chainId),\n cooldown: \"86400\",\n expiration: \"604800\",\n })\n const [validFields, setValidFields] = useState({\n oracle: !!params.oracle,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: TellorModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddTellorModule = async () => {\n try {\n const args = {\n ...params,\n executor: delayModule || safe.safeAddress,\n }\n const txs = deployTellorModule(provider, safe.safeAddress, safe.chainId, args)\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"owner\", value, valid)}\n />\n \n \n onParamChange(\"oracle\", value, valid)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport {\n deployOptimisticGovernorModule,\n getFinder,\n getCollateral,\n} from \"../../../../services\"\nimport { useRootSelector } from \"../../../../store\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { getDelayModules } from \"../../../../store/modules/selectors\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { ModuleType } from \"../../../../store/modules/models\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport {\n collateralOptions,\n CollateralSelect,\n} from \"../../../../components/input/CollateralSelect\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface OptimisticGovernorModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface OptimisticGovernorModuleParams {\n finder: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n snapshotURL: string\n votingQuorum: string\n votingPeriod: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n errorMessage: {\n color: \"red\",\n },\n}))\n\nexport const OptimisticGovernorModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: OptimisticGovernorModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const delayModules = useRootSelector(getDelayModules)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [isWeth, setIsWeth] = useState(true)\n const [params, setParams] = useState({\n finder: getFinder(safe.chainId),\n owner: safe.safeAddress,\n collateral: getCollateral(safe.chainId, isWeth),\n bond: \"2\",\n rules: \"\",\n identifier: \"0x4153534552545f54525554480000000000000000000000000000000000000000\",\n liveness: \"86400\",\n snapshotURL: \"https://snapshot.org/#/\",\n votingQuorum: \"5\",\n votingPeriod: \"24\",\n })\n const [validFields, setValidFields] = useState({\n finder: !!params.finder,\n bond: !!params.bond,\n snapshotURL: !!params.snapshotURL,\n votingPeriod: !!params.votingPeriod,\n votingQuorum: !!params.votingQuorum,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: OptimisticGovernorModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddOptimisticGovernorModule = async () => {\n try {\n const args = {\n ...params,\n owner: safe.safeAddress,\n executor: delayModule || safe.safeAddress,\n }\n const txs = deployOptimisticGovernorModule(\n provider,\n safe.safeAddress,\n safe.chainId,\n args,\n isWeth,\n )\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n params.rules = `I assert that this transaction proposal is valid according to the following rules: Proposals approved on Snapshot, as verified at ${params.snapshotURL}, are valid as long as there is a minimum quorum of ${params.votingQuorum} and a minimum voting period of ${params.votingPeriod} hours and it does not appear that the Snapshot voting system is being exploited or is otherwise unavailable. The quorum and voting period are minimum requirements for a proposal to be valid. Quorum and voting period values set for a specific proposal in Snapshot should be used if they are more strict than the rules parameter. The explanation included with the on-chain proposal must be the unique IPFS identifier for the specific Snapshot proposal that was approved or a unique identifier for a proposal in an alternative voting system approved by DAO social consensus if Snapshot is being exploited or is otherwise unavailable.`\n\n return (\n \n Parameters\n\n \n \n {\n onParamChange(\"collateral\", value)\n setIsWeth(!isWeth)\n }}\n chainId={safe.chainId}\n />\n \n \n onParamChange(\"bond\", value, valid)}\n />\n \n {Number(params.bond) < 1500 && !isWeth\n ? \"Warning: A minimum bond of 1,500 is recommended for USDC\"\n : Number(params.bond) < 2 && isWeth\n ? \"Warning: A bond of 2 is recommended for WETH\"\n : null}\n \n \n \n onParamChange(\"liveness\", value)}\n />\n \n {Number(params.liveness) < 86400\n ? \"Warning: The minimum recommended liveness period is 24 hours.\"\n : null}\n \n \n \n onParamChange(\"snapshotURL\", value, valid)}\n />\n \n \n onParamChange(\"votingQuorum\", value, valid)}\n />\n \n \n onParamChange(\"votingPeriod\", value, valid)}\n />\n \n \n Rules Parameter:\n {params.rules}\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { deployDelayModule } from \"services\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface DelayModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface DelayModuleParams {\n expiration: string\n cooldown: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const DelayModuleModal = ({ open, onClose, onSubmit }: DelayModuleModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [params, setParams] = useState({\n expiration: \"86400\",\n cooldown: \"86400\",\n })\n\n const onParamChange = (\n field: Field,\n value: DelayModuleParams[Field],\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddDelayModule = async () => {\n try {\n const txs = deployDelayModule(provider, safe.safeAddress, safe.chainId, {\n executor: safe.safeAddress,\n cooldown: params.cooldown,\n expiration: params.expiration,\n })\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { Interface, ParamType } from \"@ethersproject/abi\"\nimport { enableModule } from \"services\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { ReactComponent as AddIcon } from \"../../../../assets/icons/add-icon.svg\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { useRootDispatch } from \"../../../../store\"\nimport { addTransaction } from \"../../../../store/transactionBuilder\"\nimport { SafeAbi } from \"../../../../services/helpers\"\nimport { serializeTransaction } from \"../../../../store/transactionBuilder/helpers\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\n\ninterface AddCustomModuleProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n addButton: {\n marginTop: theme.spacing(2),\n },\n addTransactionButton: {\n marginTop: theme.spacing(1),\n },\n addIcon: {\n stroke: theme.palette.common.white,\n width: 20,\n height: 20,\n },\n}))\n\nexport const CustomModuleModal = ({ onSubmit, open, onClose }: AddCustomModuleProps) => {\n const { sdk, safe } = useSafeAppsSDK()\n const dispatch = useRootDispatch()\n const classes = useStyles()\n\n const [moduleAddress, setModuleAddress] = useState(\"\")\n const [isAddressValid, setAddressValid] = useState(false)\n\n const handleAddressChange = (address: string, isValid: boolean) => {\n setModuleAddress(address)\n setAddressValid(!!address.length && isValid)\n }\n\n const resetState = () => {\n if (onClose) onClose()\n setModuleAddress(\"\")\n setAddressValid(false)\n }\n\n const addModule = async () => {\n const tx = enableModule(safe.safeAddress, moduleAddress)\n\n try {\n await sdk.txs.send({ txs: [tx] })\n resetState()\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.warn(\"error adding custom module\", error)\n }\n }\n\n const addTransactionModule = () => {\n const inter = new Interface(SafeAbi)\n const func = inter.getFunction(\"enableModule\")\n const tx = {\n func,\n to: safe.safeAddress,\n params: [moduleAddress],\n id: \"add_module_\" + new Date().getTime(),\n }\n\n dispatch(addTransaction(serializeTransaction(tx)))\n resetState()\n if (onClose) onClose()\n }\n\n return (\n \n \n\n }\n onClick={addModule}\n >\n Add Module\n \n\n }\n onClick={addTransactionModule}\n variant=\"outlined\"\n >\n Add to Transaction Bundle\n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { AMBModuleParams, deployBridgeModule } from \"../../../../services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface AMBModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ntype AMBModuleParamsInput = Omit\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const AMBModuleModal = ({ open, onClose, onSubmit }: AMBModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n amb: false,\n controller: false,\n chainId: false,\n })\n const [params, setParams] = useState({\n amb: \"\",\n chainId: \"\",\n controller: \"\",\n })\n const isValid = Object.values(errors).every((x) => x)\n\n const onParamChange = (\n field: Field,\n value: AMBModuleParamsInput[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddAMBModule = async () => {\n try {\n const txs = deployBridgeModule(provider, safe.safeAddress, safe.chainId, {\n ...params,\n executor: safe.safeAddress,\n })\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"amb\", value, valid)}\n />\n \n \n onParamChange(\"controller\", value, valid)}\n />\n \n \n onParamChange(\"chainId\", value, valid)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployExitModule, ExitModuleParams } from \"../../../../services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ExitModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ntype ExitModuleParamsInput = Omit\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n textLink: {\n cursor: \"pointer\",\n },\n}))\n\nexport const ExitModuleModal = ({ open, onClose, onSubmit }: ExitModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n tokenContract: false,\n })\n const [params, setParams] = useState({\n tokenContract: \"\",\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: ExitModuleParamsInput[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddExitModule = async () => {\n try {\n const txs = await deployExitModule(provider, safe.safeAddress, safe.chainId, {\n ...params,\n executor: safe.safeAddress,\n })\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"tokenContract\", value, valid)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployRolesV1Modifier, RolesModifierParams } from \"services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n networkAddresses as multisendNetworkAddresses,\n defaultAddress as defaultMultisendAddress,\n} from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/multi_send.json\"\n\ninterface RolesModifierModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RolesV1ModifierModal = ({\n open,\n onClose,\n onSubmit,\n}: RolesModifierModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n target: true,\n multisend: true,\n })\n const [params, setParams] = useState({\n target: safe.safeAddress,\n multisend: defaultMultisend(safe),\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: RolesModifierParams[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRolesModifier = async () => {\n try {\n const txs = deployRolesV1Modifier(provider, safe.safeAddress, safe.chainId, params)\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"target\", value, valid)}\n />\n \n \n onParamChange(\"multisend\", value, valid)}\n />\n \n \n \n )\n}\n\nfunction defaultMultisend(safeInfo: SafeInfo) {\n const address = (multisendNetworkAddresses as Record)[safeInfo.chainId]\n\n return address || defaultMultisendAddress\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployRolesV2Modifier, RolesModifierParams } from \"services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n networkAddresses as multisendNetworkAddresses,\n defaultAddress as defaultMultisendAddress,\n} from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/multi_send.json\"\n\ninterface RolesModifierModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RolesV2ModifierModal = ({\n open,\n onClose,\n onSubmit,\n}: RolesModifierModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n target: true,\n multisend: true,\n })\n const [params, setParams] = useState({\n target: safe.safeAddress,\n multisend: defaultMultisend(safe),\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: RolesModifierParams[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRolesModifier = async () => {\n try {\n const txs = deployRolesV2Modifier(provider, safe.safeAddress, safe.chainId, params)\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"target\", value, valid)}\n />\n \n \n onParamChange(\"multisend\", value, valid)}\n />\n \n \n \n )\n}\n\nfunction defaultMultisend(safeInfo: SafeInfo) {\n const address = (multisendNetworkAddresses as Record)[safeInfo.chainId]\n\n return address || defaultMultisendAddress\n}\n","import React, { useEffect, useState } from \"react\"\nimport { Box, Grid, InputLabel, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { ParamInput } from \"../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { getArbitrator, ARBITRATOR_OPTIONS } from \"../../services\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const arbitratorOptions = {\n NO_ARBITRATOR: \"No arbitration (highest bond wins)\",\n KLEROS: \"Kleros\",\n OTHER: \"Other (custom address)\",\n}\n\n// List of chain IDs where Kleros is available.\nexport const klerosAvailability: number[] = [\n NETWORK.MAINNET,\n NETWORK.GOERLI,\n NETWORK.GNOSIS_CHAIN,\n NETWORK.POLYGON,\n]\n\ntype Option = keyof typeof arbitratorOptions\n\ninterface ArbitratorSelectProps {\n defaultAddress?: string\n defaultOption?: string\n label: string\n chainId: number\n\n onChange(arbitrator: string): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n select: {\n marginBottom: -1,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"100%\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n}))\n\nexport const ArbitratorSelect = ({\n onChange,\n defaultOption = arbitratorOptions.NO_ARBITRATOR,\n defaultAddress = \"\",\n label,\n chainId,\n}: ArbitratorSelectProps) => {\n const classes = useStyles()\n const [option, setOption] = useState(defaultOption)\n const [arbitrator, setArbitrator] = useState(defaultAddress)\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleArbitratorChange = (_arbitrator: string, valid?: boolean) => {\n try {\n if (valid === true) {\n setArbitrator(_arbitrator)\n onChange(_arbitrator)\n }\n } catch (err) {\n console.warn(\"invalid arbitrator option\")\n }\n }\n\n const handleArbitratorOptionChange = (newOption: string) => {\n handleClose()\n const newOptionKey = Object.keys(arbitratorOptions).find(\n (k) => arbitratorOptions[`${k}` as Option] === newOption,\n ) as Option\n setOption(newOption)\n if (newOptionKey === \"OTHER\") {\n setArbitrator(\"\")\n onChange(\"\")\n } else {\n const newArbitrator = getArbitrator(chainId, ARBITRATOR_OPTIONS[newOptionKey])\n setArbitrator(newArbitrator)\n onChange(newArbitrator)\n }\n }\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n return (\n
\n {label}\n \n \n value as string}\n onChange={(evt) => handleArbitratorOptionChange(evt.target.value as string)}\n >\n {Object.keys(arbitratorOptions).map((optionKey) => {\n if (!klerosAvailability.includes(chainId) && optionKey === \"KLEROS\") {\n return null\n }\n return (\n \n {arbitratorOptions[`${optionKey}` as Option]}\n \n \n \n )\n })}\n \n \n \n {option === arbitratorOptions.OTHER && (\n \n \n handleArbitratorChange(value, valid)}\n />\n \n \n )}\n
\n )\n}\n","import {\n deployAndSetUpModule,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { enableModule, getDefaultOracle } from \"services\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { buildTransaction } from \"services/helpers\"\nimport { ethers } from \"ethers\"\n\ninterface RealityModuleParams {\n executor: string\n oracle?: string\n bond: string\n templateId: string\n timeout: string\n cooldown: string\n expiration: string\n arbitrator: string\n}\n\nexport function deployRealityModule(\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RealityModuleParams,\n isERC20?: boolean,\n) {\n const type: KnownContracts = isERC20\n ? KnownContracts.REALITY_ERC20\n : KnownContracts.REALITY_ETH\n const {\n timeout,\n cooldown,\n expiration,\n bond,\n templateId,\n oracle,\n executor,\n arbitrator,\n } = args\n const oracleAddress = oracle || getDefaultOracle(chainId)\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"uint32\",\n \"uint32\",\n \"uint32\",\n \"uint256\",\n \"uint256\",\n \"address\",\n ],\n values: [\n safeAddress,\n safeAddress,\n executor,\n oracleAddress,\n timeout,\n cooldown,\n expiration,\n bond,\n templateId,\n arbitrator,\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n","import React, { useEffect, useState } from \"react\"\nimport { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Grow } from \"../../../../components/layout/Grow\"\nimport { ethers } from \"ethers\"\nimport { useRootSelector } from \"store\"\nimport { getDelayModules } from \"store/modules/selectors\"\nimport { NETWORK, NETWORKS } from \"utils/networks\"\nimport { ARBITRATOR_OPTIONS, getArbitrator, getDefaultOracle } from \"services\"\nimport { getArbitratorBondToken } from \"services/reality-eth\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { ParamInput } from \"components/ethereum/ParamInput\"\nimport { ParamType } from \"ethers/lib/utils\"\nimport { Row } from \"components/layout/Row\"\nimport { TimeSelect } from \"components/input/TimeSelect\"\nimport { ZodiacTextField } from \"zodiac-ui-components\"\nimport { arbitratorOptions, ArbitratorSelect } from \"components/input/ArbitratorSelect\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { ModuleType } from \"store/modules/models\"\nimport { deployRealityModule } from \"./services/moduleDeploymentOld\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nconst SECONDS_IN_DAY = 86400\n\n// TODO: delete this when the new flow is done\n\ninterface RealityModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface RealityModuleParams {\n oracle: string\n templateId: string\n timeout: string\n cooldown: string\n expiration: string\n bond: string\n arbitrator: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RealityModuleOldModal = ({\n open,\n onClose,\n onSubmit,\n}: RealityModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n const delayModules = useRootSelector(getDelayModules)\n const [isERC20, setERC20] = useState(false)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [bondToken, setBondToken] = useState(\n NETWORKS[safe.chainId as NETWORK].nativeAsset,\n )\n const [params, setParams] = useState({\n oracle: getDefaultOracle(safe.chainId),\n templateId: \"\",\n timeout: (SECONDS_IN_DAY * 2).toString(),\n cooldown: (SECONDS_IN_DAY * 2).toString(),\n expiration: (SECONDS_IN_DAY * 7).toString(),\n bond: \"0.1\",\n arbitrator: getArbitrator(safe.chainId, ARBITRATOR_OPTIONS.NO_ARBITRATOR),\n })\n const [validFields, setValidFields] = useState({\n oracle: !!params.oracle,\n templateId: !!params.templateId,\n bond: !!params.bond,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n useEffect(() => {\n if (params.oracle && ethers.utils.isAddress(params.oracle)) {\n getArbitratorBondToken(provider, params.oracle, safe.chainId)\n .then((response) => {\n setBondToken(response.coin)\n setERC20(response.isERC20)\n })\n .catch(() => {\n setBondToken(NETWORKS[safe.chainId as NETWORK].nativeAsset)\n setERC20(false)\n })\n }\n }, [params.oracle, safe.chainId, provider])\n\n const onParamChange = (\n field: Field,\n value: RealityModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddRealityModule = async () => {\n try {\n const minimumBond = ethers.utils.parseUnits(params.bond, bondToken.decimals)\n const args = {\n ...params,\n executor: delayModule || safe.safeAddress,\n bond: minimumBond.toString(),\n }\n const txs = await deployRealityModule(\n provider,\n safe.safeAddress,\n safe.chainId,\n args,\n isERC20,\n )\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const handleBondChange = (event: React.ChangeEvent) => {\n const value = event.target.value || \"0\"\n const leftZero = value.startsWith(\"0\") && value.length > 1\n let bond = leftZero ? value.substr(1) : value\n bond = bond.startsWith(\".\") ? \"0\" + bond : bond\n\n try {\n ethers.utils.parseUnits(bond, bondToken.decimals)\n onParamChange(\"bond\", bond)\n } catch (error) {\n console.warn(\"invalid bond\", value, error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"oracle\", value, valid)}\n />\n \n \n \n TemplateId\n \n \n Get a template here\n \n \n onParamChange(\"templateId\", value, valid)}\n />\n \n \n onParamChange(\"timeout\", value)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n \n \n onParamChange(\"arbitrator\", value)}\n chainId={safe.chainId}\n />\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import { ethers } from \"ethers\"\nimport { enableModule, getDefaultOracle, TxWitMeta } from \"../../../../../services\"\nimport {\n deployAndSetUpModule,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { buildTransaction } from \"services/helpers\"\nimport { Data as OracleTemplateData } from \"../sections/Oracle/components/OracleTemplate\"\nimport DETERMINISTIC_DEPLOYMENT_HELPER_META from \"../../../../../contracts/DeterministicDeploymentHelper.json\"\nexport interface RealityModuleParams {\n executor: string\n oracle?: string\n bond: string\n timeout: string\n cooldown: string\n expiration: string\n arbitrator: string\n}\n\n// TODO: Add support for Reality.ETH oracles that is not known (for instance deployed by the caller)\n// using `deployAndSetUpCustomModule` instead of `deployAndSetUpModule`\nexport async function deployRealityModule(\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n deterministicDeploymentHelperAddress: string,\n chainId: number,\n args: RealityModuleParams,\n template: OracleTemplateData,\n isERC20?: boolean,\n): Promise {\n const oracleType: KnownContracts = isERC20\n ? KnownContracts.REALITY_ERC20\n : KnownContracts.REALITY_ETH\n const { timeout, cooldown, expiration, bond, oracle, executor, arbitrator } = args\n const oracleAddress =\n oracle != null && ethers.utils.isAddress(oracle) ? oracle : getDefaultOracle(chainId)\n if (oracleAddress == null) {\n throw new Error(\n `No oracle address provided and no default oracle available for this chain (chainID: ${chainId})`,\n )\n }\n const saltNonce = Date.now().toString()\n const initData = {\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"uint32\",\n \"uint32\",\n \"uint32\",\n \"uint256\",\n \"uint256\",\n \"address\",\n ],\n values: [\n deterministicDeploymentHelperAddress,\n safeAddress,\n executor,\n oracleAddress,\n timeout,\n cooldown,\n expiration,\n bond,\n 0, // templateId - must use 0 here, will be set up later\n arbitrator,\n ],\n }\n\n const { transaction: daoModuleDeploymentTx, expectedModuleAddress } =\n deployAndSetUpModule(oracleType, initData, provider, chainId, saltNonce)\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [expectedModuleAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n const deterministicSetupHelper = new ethers.Contract(\n deterministicDeploymentHelperAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_META.abi,\n provider,\n )\n\n const populatedTemplateConfigurationTx =\n await deterministicSetupHelper.populateTransaction.createTemplateAndChangeOwner(\n expectedModuleAddress,\n oracleAddress,\n JSON.stringify({\n type: \"bool\",\n title: template.templateQuestion,\n category: \"DAO proposal\",\n lang: \"en\",\n }),\n safeAddress,\n )\n\n if (populatedTemplateConfigurationTx.to == null) {\n throw new Error(\"Missing to address\")\n }\n if (populatedTemplateConfigurationTx.data == null) {\n throw new Error(\"Missing data\")\n }\n\n daoModuleTransactions.push({\n to: populatedTemplateConfigurationTx.to,\n data: populatedTemplateConfigurationTx.data,\n value: \"0\",\n })\n\n return {\n txs: daoModuleTransactions,\n meta: { expectedModuleAddress },\n }\n}\n","import * as IPFS from \"ipfs-core\"\n\nlet node: IPFS.IPFS\nconst textDecoder = new TextDecoder()\n\nconst getNode = async () => {\n if (node == null) {\n node = await IPFS.create()\n }\n return node\n}\nexport const getJsonData = async (path: string) => {\n const node = await getNode()\n\n if (path.startsWith(\"ipns\")) {\n path = await node.resolve(path, { recursive: true })\n }\n\n path = path.replace(\"ipfs://\", \"\")\n\n const chunks: string[] = []\n for await (const chunk of node.cat(path)) {\n chunks.push(textDecoder.decode(chunk))\n }\n const rawContent = chunks.join(\"\")\n return JSON.parse(rawContent)\n}\n\nexport const add = async (content: any) => {\n const node = await getNode()\n const { cid } = await node.add(content)\n return cid\n}\n","import { ethers } from \"ethers\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\n\n/**\n * This only works for domains using a resolver that conforms to the `abiPublicResolver` (like the PublicResolver).\n */\n\nconst ensRegistry = \"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e\" // ENS: Registry with Fallback (singleton same address on different chains)\nconst ensImplementation = \"0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85\" // ENS: Base Registrar Implementation (singleton same address on different chains)\n\nconst abiPublicResolver = [\n \"function setText(bytes32 node, string calldata key, string calldata value) external\",\n \"function text(bytes32 node, string calldata key) external view returns (string memory)\",\n]\n\nconst abiRegistry = [\n \"function owner(bytes32 node) external view returns (address)\",\n \"function resolver(bytes32 node) external view returns (address)\",\n]\n\nconst abiImplementation = [\n \"function ownerOf(uint256 tokenId) public view returns (address owner)\",\n]\n\nexport const setTextRecordTx = async (\n provider: ethers.providers.Provider,\n ensName: string,\n key: string,\n content: string,\n): Promise => {\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const nameHash = ethers.utils.namehash(ensName)\n const ensResolver = await ensRegistryContract.resolver(nameHash)\n const ensResolverContract = new ethers.Contract(\n ensResolver,\n abiPublicResolver,\n provider,\n )\n const populatedTx = await ensResolverContract.populateTransaction.setText(\n nameHash,\n key,\n content,\n )\n if (populatedTx.to == null) {\n throw new Error(\"Missing to address\")\n }\n if (populatedTx.data == null) {\n throw new Error(\"Missing data\")\n }\n\n return {\n to: populatedTx.to,\n data: populatedTx.data,\n value: \"0\",\n }\n}\n\n// the owner of the NFT\nexport const checkIfIsOwner = async (\n provider: ethers.providers.Provider,\n ensName: string,\n address: string,\n) => {\n const BigNumber = ethers.BigNumber\n const name = ensName.split(\".\")[0] // only supports toplevel\n const labelHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(name))\n const tokenId = BigNumber.from(labelHash).toString()\n const ensImplementationContract = new ethers.Contract(\n ensImplementation,\n abiImplementation,\n provider,\n )\n const nftOwner = await ensImplementationContract.ownerOf(tokenId)\n return ethers.utils.getAddress(nftOwner) === ethers.utils.getAddress(address)\n}\n\nexport const getEnsTextRecord = async (\n ensName: string,\n recordId: string,\n provider: ethers.providers.Provider,\n) => {\n const nameHash = ethers.utils.namehash(ensName)\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const ensResolverAddress = await ensRegistryContract.resolver(nameHash)\n const ensResolverContract = new ethers.Contract(ensResolverAddress, abiPublicResolver, provider)\n const record = ensResolverContract.functions.text(nameHash, recordId)\n return record\n}\n\nexport const checkIfIsController = async (\n provider: ethers.providers.Provider,\n ensName: string,\n address: string,\n) => {\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const nameHash = ethers.utils.namehash(ensName)\n const owner = await ensRegistryContract.owner(nameHash)\n\n return ethers.utils.getAddress(address) === ethers.utils.getAddress(owner)\n}\n","import snapshot from \"@snapshot-labs/snapshot.js\"\nimport * as R from \"ramda\"\nimport { NETWORK } from \"utils/networks\"\n\nconst SNAPSHOT_HUB = \"https://hub.snapshot.org\"\nconst SNAPSHOT_HUB_GOERLI = \"https://testnet.hub.snapshot.org\"\nconst SNAPSHOT_SPACE = \"https://snapshot.org\"\nconst SNAPSHOT_SPACE_GOERLI = \"https://testnet.snapshot.org\"\n\n// Returns snapshot space settings, or undefined if no space was found for the ENS name.\nexport const getSnapshotSpaceSettings = async (ensName: string, chainId: number) => {\n await updateSnapshotCache(ensName, chainId) // make sure that the returned snapshot space settings is the newest version\n const res = await fetch(`${getHubUrl(chainId)}/api/spaces/${ensName}`)\n if (res.ok) {\n try {\n return await res.json().then((res) => {\n // Remove flagged, verified, hibernated, and turbo properties from res, as they are not part of the space config, but rater extra info from the server.\n const { flagged, verified, hibernated, turbo, ...filteredRes } = res\n return filteredRes\n })\n } catch (error) {\n return undefined // there is not snapshot space for this ENS\n }\n } else {\n throw res\n }\n}\n\nexport const validateSchema = (spaceSettings: any) =>\n snapshot.utils.validateSchema(snapshot.schemas.space, spaceSettings)\n\nexport const updateSnapshotCache = (ensName: string, chainId: number) =>\n fetch(`${getHubUrl(chainId)}/api/spaces/${ensName}/poke`)\n\nexport const verifyNewSnapshotSettings = (originalSettings: any, newSettings: any) =>\n R.and(\n // check that there are no unintended changes to the new Snapshot Space settings\n R.equals(\n R.omit([\"plugins\", \"safeSnap\"], originalSettings),\n R.omit([\"plugins\", \"safeSnap\"], newSettings),\n ),\n // validate the schema\n // we must be strict here, if not a truthy error value can be returned\n validateSchema(newSettings) === true,\n )\n\nconst getHubUrl = (chainId: number) =>\n chainId === NETWORK.GOERLI ? SNAPSHOT_HUB_GOERLI : SNAPSHOT_HUB\n\nexport const getSnapshotSpaceUrl = (chainId: number, ensName: string) =>\n (chainId === NETWORK.GOERLI ? SNAPSHOT_SPACE_GOERLI : SNAPSHOT_SPACE) + `/#/${ensName}`\n","import { NETWORK } from \"utils/networks\"\nimport { MonitoringSectionData } from \"../sections/Monitoring\"\n\nconst BACKEND_API_URL = process.env.REACT_APP_BACKEND_API_URL\n\nif (BACKEND_API_URL == null) {\n throw new Error(\"BACKEND_API_URL not set\")\n}\n\ninterface MonitoringCredentials {\n apiKey: string\n apiSecret: string\n}\n\ninterface NotificationChannels {\n channel: string\n config: any\n}\ninterface RequestType extends MonitoringCredentials {\n network: string\n realityModuleAddress: string\n oracleAddress: string\n notificationChannels: NotificationChannels[]\n}\n\nexport const setUpMonitoring = async (\n chainId: NETWORK,\n realityModuleAddress: string,\n oracleAddress: string,\n data: MonitoringSectionData,\n) => {\n console.log()\n if ((data.apiKey ?? \"\") === \"\" || (data.secretKey ?? \"\") === \"\") {\n throw new Error(\n \"API keys for monitoring service missing. Monitoring will NOT be set up.\",\n )\n }\n if (\n (data.discordKey ?? \"\") === \"\" &&\n (data.slackKey ?? \"\") === \"\" &&\n data.email.length === 0 &&\n (data.telegram.botToken ?? \"\") === \"\" &&\n (data.telegram.chatId ?? \"\")\n ) {\n throw new Error(\n \"No notification channel(s) specified. Monitoring will NOT be set up.\",\n )\n }\n\n const notificationChannels: NotificationChannels[] = []\n\n if (data.email.length > 0) {\n notificationChannels.push({\n channel: \"email\",\n config: {\n emails: data.email,\n },\n })\n }\n\n if (data.discordKey.length > 0) {\n notificationChannels.push({\n channel: \"discord\",\n config: {\n url: data.discordKey,\n },\n })\n }\n\n if (data.slackKey.length > 0) {\n notificationChannels.push({\n channel: \"slack\",\n config: {\n url: data.slackKey,\n },\n })\n }\n\n if (data.telegram.botToken.length > 0) {\n notificationChannels.push({\n channel: \"telegram\",\n config: data.telegram,\n })\n }\n\n const requestBody: RequestType = {\n apiKey: data.apiKey,\n apiSecret: data.secretKey,\n network: networkToOzDefenderNetworkName(chainId),\n oracleAddress,\n realityModuleAddress,\n notificationChannels,\n }\n\n return fetch(BACKEND_API_URL + \"/monitoring/notification\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(requestBody),\n })\n}\n\nexport const validationCredentials = async (query: MonitoringCredentials) => {\n const { apiKey, apiSecret } = query\n return fetch(\n `${BACKEND_API_URL}/monitoring/validation?apiKey=${apiKey}&apiSecret=${apiSecret}`,\n {\n method: \"GET\",\n mode: \"cors\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n },\n )\n}\n\nconst networkToOzDefenderNetworkName = (network: NETWORK) => {\n switch (network) {\n case NETWORK.MAINNET:\n return \"mainnet\"\n case NETWORK.GOERLI:\n return \"goerli\"\n case NETWORK.OPTIMISM:\n return \"optimism\"\n case NETWORK.BSC:\n return \"bsc\"\n case NETWORK.GNOSIS_CHAIN:\n return \"xdai\"\n case NETWORK.POLYGON:\n return \"matic\"\n case NETWORK.ARBITRUM:\n return \"arbitrum\"\n case NETWORK.AVALANCHE:\n return \"avalanche\"\n default:\n throw new Error(\"Unsupported network\")\n }\n}\n","const BACKEND_API_URL = process.env.REACT_APP_BACKEND_API_URL\n\nif (BACKEND_API_URL == null) {\n throw new Error(\"BACKEND_API_URL not set\")\n}\n\ninterface RequestType {\n snapshotSpaceEnsName: string\n snapshotSpaceSettings: any\n chainId: number\n}\n\ninterface Responds {\n cidV0: string\n}\n\nexport const pinSnapshotSpace: (request: RequestType) => Promise = async (\n request,\n) => {\n const res = await fetch(BACKEND_API_URL + \"/ipfs-pinning/snapshot-settings\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(request),\n })\n return res.json()\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckmarkNofill = function SvgCheckmarkNofill(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 15,\n height: 12,\n viewBox: \"0 0 15 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckmarkNofill, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkmark-nofill.855acc91.svg\";\nexport { ForwardRef as ReactComponent };","import { ethers } from \"ethers\"\nimport { getArbitrator, TxWitMeta as TxsWitMeta } from \"../../../../../services\"\nimport { NETWORK, NETWORKS } from \"../../../../../utils/networks\"\nimport * as ipfs from \"../../../../../services/ipfs\"\nimport * as R from \"ramda\"\nimport { setTextRecordTx } from \"services/ens\"\nimport { SetupData } from \"..\"\nimport SafeAppsSDK, { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport * as snapshot from \"../../../../../services/snapshot\"\nimport { deployRealityModule, RealityModuleParams } from \"./moduleDeployment\"\nimport { setUpMonitoring } from \"./monitoring\"\nimport { pinSnapshotSpace } from \"./snapshot-space-pinning\"\n\nconst MULTI_SEND_CONTRACT = process.env.REACT_APP_MULTI_SEND_CONTRACT\nexport const DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS =\n \"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c\" // needs to be deployed on all networks supported by the Reality Module\n\n/**\n * Sets up the Reality Module.\n *\n * @notice The input variables are not checked for validity here, as this happens in the UI.\n */\nexport const setup = async (\n provider: ethers.providers.JsonRpcProvider,\n safeSdk: SafeAppsSDK,\n safeInfo: SafeInfo,\n executorAddress: string,\n setupData: SetupData,\n statusCallback: (currentStatus: string, error?: Error) => void,\n) => {\n statusCallback(\"Setting up Reality Module deployment transactions\")\n const deploymentRealityModuleTxsMm = await deployRealityModuleTxs(\n provider,\n safeInfo.chainId,\n safeInfo.safeAddress,\n executorAddress,\n setupData,\n ).catch((e) => {\n statusCallback(\"Error while setting up Reality Module deployment transactions\", e)\n })\n\n if (deploymentRealityModuleTxsMm == null) {\n throw new Error(\n \"The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE. Should be handled in the 'statusCallback' function.\",\n )\n }\n\n const realityModuleAddress = deploymentRealityModuleTxsMm.meta?.expectedModuleAddress\n if (realityModuleAddress == null) {\n const error = new Error(\"Unable to calculate the Reality Module future address.\")\n statusCallback(error.message, error)\n }\n\n if (realityModuleAddress == null) {\n throw new Error(\n \"The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.\",\n )\n }\n\n statusCallback(\n \"Setting up transaction for adding the new snapshot space to the ENS record\",\n )\n const addSafeToSnapshotTxsMm = await addSafeSnapToSnapshotSpaceTxs(\n provider,\n setupData.proposal.ensName,\n realityModuleAddress,\n safeInfo.chainId,\n ).catch((e) => {\n statusCallback(\n \"Error when setting up transactions to add SafeSnap to the Snapshot Space\",\n e,\n )\n })\n\n if (deploymentRealityModuleTxsMm == null || addSafeToSnapshotTxsMm == null) {\n throw new Error(\n \"The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE.\",\n )\n }\n\n const txs = [...deploymentRealityModuleTxsMm.txs, ...addSafeToSnapshotTxsMm.txs]\n\n statusCallback(\"Setting up monitoring with OZ Defender\")\n await setUpMonitoring(\n safeInfo.chainId as NETWORK,\n realityModuleAddress,\n setupData.oracle.instanceData.instanceAddress,\n setupData.monitoring,\n ).catch((e) => {\n statusCallback(\"Error when setting up monitoring.\", e)\n })\n\n statusCallback(\"Proposing transactions to the Safe\")\n await safeSdk.txs.send({ txs }).catch((e) => {\n statusCallback(\"Error when proposing transactions to the Safe\", e)\n })\n\n // await pokeSnapshotAPI(setupData.proposal.ensName); // TODO: if the transactions does not happen immediately, we need to poke the snapshot API in some other way later when the transactions is executed to make sure the new space settings is picked up.\n}\n\n/**\n * Generate the transactions required to deploy a Reality Module\n *\n * Can throw if inputs are invalided.\n *\n * @param chainId\n * @param safeAddress\n * @param params Reality Module parameters\n * @returns transaction array\n */\nconst deployRealityModuleTxs = async (\n provider: ethers.providers.JsonRpcProvider,\n chainId: number,\n safeAddress: string,\n executorAddress: string,\n setupData: SetupData,\n): Promise => {\n const bondToken = NETWORKS[chainId as NETWORK].nativeAsset\n const moduleDeploymentParameters: RealityModuleParams = {\n executor: executorAddress,\n bond: ethers.utils\n .parseUnits(setupData.oracle.bondData.bond.toString(), bondToken.decimals)\n .toString(),\n timeout: setupData.oracle.delayData.timeout.toString(),\n cooldown: setupData.oracle.delayData.cooldown.toString(),\n expiration: setupData.oracle.delayData.expiration.toString(),\n arbitrator: getArbitrator(chainId, setupData.oracle.arbitratorData.arbitratorOption),\n oracle: setupData.oracle.instanceData.instanceAddress,\n }\n return await deployRealityModule(\n provider,\n safeAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n chainId,\n moduleDeploymentParameters,\n setupData.oracle.templateData,\n false,\n )\n}\n\nexport const addSafeSnapToSettings = (\n originalSpaceSettings: any,\n chainId: number,\n realityModuleAddress: string,\n) =>\n R.assocPath(\n [\"plugins\", \"safeSnap\"],\n {\n safes: [\n {\n network: chainId,\n realityAddress: realityModuleAddress,\n multisend: MULTI_SEND_CONTRACT,\n },\n ],\n },\n originalSpaceSettings,\n )\n\nexport const addSafeSnapToSnapshotSpaceTxs = async (\n provider: ethers.providers.JsonRpcProvider,\n ensName: string,\n realityModuleAddress: string,\n chainId: number,\n): Promise => {\n // 1. Get the current Space setting file. from IPFS directly or from\n const originalSpaceSettings = await snapshot.getSnapshotSpaceSettings(ensName, chainId)\n\n // 2. Update the Space setting file, by adding the SafeSnap plugin.\n const newSpaceSettings = addSafeSnapToSettings(\n originalSpaceSettings,\n chainId,\n realityModuleAddress,\n )\n // validate the new schema\n if (!snapshot.verifyNewSnapshotSettings(originalSpaceSettings, newSpaceSettings)) {\n throw new Error(\"The new settings file is changed in unexpected ways\")\n }\n\n // 3. Deploy the modified settings file to IPFS.\n const cidV0Locale = (await ipfs.add(JSON.stringify(newSpaceSettings))).toV0().toString()\n // 4. Pin the new file\n let cidV0FromPinning = \"\"\n try {\n const { cidV0 } = await pinSnapshotSpace({\n snapshotSpaceEnsName: ensName,\n snapshotSpaceSettings: newSpaceSettings,\n chainId,\n })\n cidV0FromPinning = cidV0\n } catch (e) {\n throw new Error(\n \"Failed to pin the new snapshot space settings file. Error from backend: \" + e,\n )\n }\n\n if (cidV0FromPinning === \"\" || cidV0FromPinning == null) {\n throw new Error(\n \"Communication with the backend pinning service failed. No CID was returned.\",\n )\n }\n\n if (cidV0Locale != null && cidV0Locale !== cidV0FromPinning) {\n throw new Error(\n `The CID from the locale browser node (${cidV0Locale}) does not correspond the CID from the pinning service (${cidV0FromPinning})`,\n )\n }\n\n // 5. Sett the hash of the new setting file in the ENS snapshot record.\n const setEnsRecordTx = await setTextRecordTx(\n provider,\n ensName,\n \"snapshot\",\n `ipfs://${cidV0Locale}`,\n )\n\n return { txs: [setEnsRecordTx] }\n}\n","import React from \"react\"\nimport {\n Box,\n Grid,\n makeStyles,\n MenuItem,\n Select,\n SelectProps,\n Tooltip,\n Typography,\n} from \"@material-ui/core\"\nimport { colors } from \"zodiac-ui-components\"\nimport HelpOutline from \"@material-ui/icons/HelpOutline\"\nimport * as R from \"ramda\"\n\nconst useStyles = makeStyles(() => ({\n label: {\n marginBottom: 4,\n },\n select: {\n border: `1px solid ${colors.tan[300]}`,\n },\n selectContainer: {\n padding: 2,\n boxSizing: \"border-box\",\n border: `1px solid ${colors.tan[300]}`,\n },\n icon: {\n fontSize: \"1rem\",\n },\n}))\n\ninterface DropdownProps extends SelectProps {\n label?: string\n options: { label: string; value: string | number }[]\n tooltipMsg?: string\n}\n\nexport const Dropdown: React.FC = (props) => {\n const classes = useStyles()\n\n return (\n \n {props.label && (\n \n \n {props.label}\n \n {props.tooltipMsg && (\n \n \n \n \n \n )}\n \n )}\n\n \n \n \n \n )\n}\n","import { Grid, makeStyles, Typography, Tooltip } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React from \"react\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { HelpOutline } from \"@material-ui/icons\"\nimport { InputPartProps } from \"../..\"\n\nexport const getDefaultTemplateQuestion = (ensName: string) =>\n `Did the Snapshot proposal with the id %s in the ${ensName} space pass the execution of the array of Module transactions that have the hash 0x%s and does it meet the requirements of the document referenced in the dao requirements record at ${ensName}? The hash is the keccak of the concatenation of the individual EIP-712 hashes of the Module transactions. If this question was asked before the corresponding Snapshot proposal was resolved, it should ALWAYS be resolved to INVALID!`\n\nconst TEMPLATE_QUESTION_HELP = `Provide a question. This must include two %s placeholders.\nThe first placeholder is for the id of the proposal (e.g., an IPFS hash).\nThe second is the hash of the concatenation of the EIP-712 transaction hashes.`\n\nconst ORACLE_TEMPLATE_OPTIONS = [\n { label: \"Zodiac Reality Module (default)\", value: \"default\" },\n { label: \"Custom\", value: \"custom\" },\n]\n\nconst ORACLE_LANGUAGE = [{ label: \"English\", value: \"english\" }]\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n textFieldSmall: {\n \"& .MuiFormLabel-root\": {\n fontSize: 12,\n },\n },\n select: {\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n },\n paperTemplateContainer: {\n marginTop: 4,\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n templateQuestion: {\n fontFamily: \"Roboto Mono\",\n \"& .MuiInputBase-root\": {\n border: \"none\",\n fontSize: \"0.85rem\",\n },\n },\n input: {\n \"& .MuiInputBase-root\": {\n padding: \"9px 8px\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n button: {\n width: \"100%\",\n padding: \"4px 15px\",\n },\n buttonContainer: {\n marginTop: 8,\n cursor: \"pointer\",\n },\n icon: {\n color: colors.tan[1000],\n fontSize: \"1rem\",\n marginTop: 3,\n },\n text: {\n fontSize: \"0.75rem\",\n },\n tooltipIcon: {\n fontSize: \"1rem\",\n },\n}))\n\nexport type Data = {\n templateType: \"default\" | \"custom\"\n language: \"english\"\n category: \"DAO proposal\"\n templateQuestion: string\n}\n\ninterface OracleTemplateProps extends InputPartProps {\n ensName: string\n}\n\nexport const OracleTemplate: React.FC = ({\n data,\n setData,\n ensName,\n}) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const setTemplateType = (templateType: \"default\" | \"custom\") => {\n if (templateType === \"default\") {\n setData({\n ...data,\n templateQuestion: getDefaultTemplateQuestion(ensName),\n templateType: templateType,\n })\n } else {\n setData({ ...data, templateQuestion: \"\", templateType: templateType })\n }\n }\n\n return (\n \n \n \n \n \n Oracle Template\n \n \n \n \n The oracle template creates an appropriate question based on the data of the\n proposal. We highly recommend using the default Zodiac Reality Module\n template\n \n \n \n \n \n \n \n \n setTemplateType(evt.target.value as \"default\" | \"custom\")\n }\n label=\"Select template:\"\n tooltipMsg=\"The Zodiac Reality Module type has defaults set for connecting the Reality Module to Safesnap. If you need a more specific setup, use the ‘Custom’ type.\"\n />\n \n \n set(\"language\")(target.value as string)}\n />\n \n <>\n \n \n Template question preview:\n\n \n \n \n \n\n \n \n set(\"templateQuestion\")(target.value as string)\n }\n multiline\n minRows={5}\n disabled={get(\"templateType\") === \"default\"}\n placeholder={\n get(\"templateType\") === \"default\"\n ? getDefaultTemplateQuestion(ensName)\n : TEMPLATE_QUESTION_HELP\n }\n />\n \n \n \n \n \n \n )\n}\n\nexport default OracleTemplate\n","import { useState } from \"react\"\nimport { validationCredentials } from \"../service/monitoring\"\n\nexport const useMonitoringValidation = () => {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState()\n\n const execute = async (apiKey: string, apiSecret: string) => {\n setLoading(true)\n setError(undefined)\n try {\n await validationCredentials({\n apiKey,\n apiSecret,\n }).then((res) => {\n setLoading(false)\n if (res.status === 200) {\n return setError(false)\n }\n setError(true)\n })\n } catch {\n setLoading(false)\n }\n }\n\n return { loading, error, execute }\n}\n","import React, { useEffect, useState, useCallback, useMemo } from \"react\"\nimport {\n Box,\n Grid,\n IconButton,\n Link,\n makeStyles,\n Switch,\n Typography,\n withStyles,\n} from \"@material-ui/core\"\nimport debounce from \"lodash.debounce\"\nimport { ethers } from \"ethers\"\nimport { NETWORK, NETWORKS } from \"utils/networks\"\nimport { getDefaultOracle, getKlerosAddress } from \"services\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { TimeSelect } from \"components/input/TimeSelect\"\nimport { colors, ZodiacTextField } from \"zodiac-ui-components\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { deployRealityModule } from \"../RealityModule/service/moduleDeployment\"\nimport {\n addSafeSnapToSnapshotSpaceTxs,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n} from \"../RealityModule/service/setupService\"\nimport {\n Data as TemplateData,\n getDefaultTemplateQuestion,\n} from \"../RealityModule/sections/Oracle/components/OracleTemplate\"\nimport * as snapshot from \"services/snapshot\"\nimport { checkIfIsController, getEnsTextRecord } from \"services/ens\"\nimport { Icon, Loader } from \"@gnosis.pm/safe-react-components\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport WarningOutlinedIcon from \"@material-ui/icons/WarningOutlined\"\nimport { MonitoringSectionData } from \"../RealityModule/sections/Monitoring\"\nimport { setUpMonitoring } from \"../RealityModule/service/monitoring\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport { ReactComponent as CheckmarkIcon } from \"../../../../assets/icons/checkmark-nofill.svg\"\nimport { useMonitoringValidation } from \"../RealityModule/hooks/useMonitoringValidation\"\n\nconst SECONDS_IN_DAY = 86400\n\ninterface RealityModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface RealityModuleParams {\n snapshotEns: string\n timeout: string\n cooldown: string\n expiration: string\n bond: string\n}\nconst useStyles = makeStyles((theme) => ({\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"20px\",\n },\n warningIcon: {\n fill: \"rgba(230, 230, 54, 1)\",\n width: \"20px\",\n },\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n loadingContainer: {\n marginRight: 4,\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 14,\n width: 14,\n border: `1px solid ${colors.tan[300]}`,\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `yellow !important`,\n fill: `yellow !important`,\n opacity: \"100% !important\",\n },\n addSpinner: {\n color: `white !important`,\n fill: `white !important`,\n opacity: \"100% !important\",\n },\n detailsContainer: {\n width: \"95%\",\n },\n messageContainer: {\n width: \"85%\",\n fill: \"rgba(244, 67, 54, 1)\",\n },\n errorMessageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n warningMessageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n color: \"rgba(230, 230, 54, 1)\",\n },\n errorMessage: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n fontWeight: \"bolder\",\n },\n warningMessage: {\n fontSize: 12,\n color: \"rgba(230, 230, 54, 1)\",\n },\n linkStyle: {\n color: \"rgba(190, 190, 120, 1)\",\n },\n flexRow: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n}))\n\nconst CustomSwitch = withStyles({\n switchBase: {\n \"&.Mui-checked\": { color: \"white\" },\n },\n colorSecondary: {\n \"&.Mui-checked + .MuiSwitch-track\": {\n backgroundColor: \"yellow\",\n },\n },\n track: {\n backgroundColor: \"black\",\n },\n})(Switch)\n\nconst PropStatus: React.FC<{\n status: \"error\" | \"warning\" | null\n message: string | null\n link?: string\n}> = ({ status, message, link }) => {\n const classes = useStyles()\n\n return (\n status && (\n \n \n {status === \"error\" && }\n {status === \"warning\" && (\n \n )}\n \n \n \n \n \n {message}\n \n \n {link ? (\n \n \n Details\n \n \n ) : (\n \n )}\n \n \n \n )\n )\n}\n\nexport const KlerosRealityModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: RealityModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n // hack to resolve mainnet ENS\n const mainnetProvider = useMemo(\n () => new ethers.providers.InfuraProvider(1, process.env.REACT_APP_INFURA_ID),\n [],\n )\n const goerliProvider = useMemo(\n () => new ethers.providers.InfuraProvider(5, process.env.REACT_APP_INFURA_ID),\n [],\n )\n\n const bondToken = NETWORKS[safe.chainId as NETWORK].nativeAsset\n const [params, setParams] = useState({\n snapshotEns: \"\",\n timeout: (SECONDS_IN_DAY * 2).toString(),\n cooldown: (SECONDS_IN_DAY * 2).toString(),\n expiration: (SECONDS_IN_DAY * 7).toString(),\n bond: \"0.1\",\n })\n const [loadingEns, setLoadingEns] = useState(false)\n const [loadedEns, setLoadedEns] = useState(false)\n const [validEns, setValidEns] = useState(false)\n const [daorequirements, setDaorequirements] = useState(\"\")\n\n const [isController, setIsController] = useState(false)\n const [isSafesnapInstalled, setIsSafesnapInstalled] = useState(false)\n const validSnapshot =\n !!params.snapshotEns &&\n params.snapshotEns.includes(\".eth\") &&\n !loadingEns &&\n loadedEns &&\n validEns\n\n const [validFields, setValidFields] = useState({\n snapshotEns: validSnapshot,\n bond: !!params.bond,\n })\n\n const [openMonitoring, setOpenMonitoring] = useState(false)\n const [apiKey, setApiKey] = useState(\"\")\n const [apiSecret, setApiSecret] = useState(\"\")\n const [validatedCredentials, setValidatedCredentials] = useState(false)\n\n const [currentEmail, setCurrentEmail] = useState(\"\")\n const [emails, setEmails] = useState([])\n const [discordKey, setDiscordKey] = useState(\"\")\n const [telegramBotToken, setTelegramBotToken] = useState(\"\")\n const [telegramChatId, setTelegramChatId] = useState(\"\")\n\n const [step, setStep] = useState<\"form\" | \"confirm\">(\"form\")\n\n const isValid = Object.values(validFields).every((field) => field)\n const emailIsValid =\n /^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$/.test(currentEmail) && !emails.includes(currentEmail)\n\n const canConfirm =\n isValid &&\n (!openMonitoring ||\n (apiKey !== undefined &&\n apiSecret !== undefined &&\n // we want to force the user to, at least, pass an email address\n // because the other notification systems could break and are hard to validate\n // if that wasn't a concern, you could pass:\n // (emails.length > 0 || discordKey || (telegramBotToken && telegramChatId))))\n emails.length > 0))\n\n const [deploying, setDeploying] = useState(false)\n\n const validateEns = useCallback(async () => {\n // On production, ENS is mainnet. On Goerli, ENS is resolved in goerli.\n const ensProvider = safe.chainId === 5 ? goerliProvider : mainnetProvider\n const address = await ensProvider.resolveName(params.snapshotEns)\n console.log({ address })\n if (address) {\n const snapshotSpace = await snapshot.getSnapshotSpaceSettings(\n params.snapshotEns,\n safe.chainId,\n )\n const daorequirements = await getEnsTextRecord(\n params.snapshotEns,\n \"daorequirements\",\n ensProvider,\n )\n setDaorequirements(daorequirements[0])\n setValidEns(snapshotSpace !== undefined)\n if (snapshotSpace !== undefined) {\n setIsSafesnapInstalled(!!snapshotSpace.plugins?.safeSnap)\n const isController = await checkIfIsController(\n ensProvider,\n params.snapshotEns,\n safe.safeAddress,\n )\n setIsController(isController)\n // We don't check if SafeSnap is installed, because:\n // - either have no control\n // - we have control, and we will create it or overwrite it for the given chain\n console.log({ isController, snapshotSpace })\n console.log({ snapshotSpace })\n }\n } else {\n }\n }, [\n params.snapshotEns,\n safe.chainId,\n safe.safeAddress,\n mainnetProvider,\n goerliProvider,\n ])\n\n const debouncedSnapshotEnsValidation = debounce(() => {\n setValidEns(false)\n setDaorequirements(\"\")\n setIsController(false)\n setIsSafesnapInstalled(false)\n setLoadedEns(false)\n if (params.snapshotEns && params.snapshotEns.includes(\".eth\")) {\n setLoadingEns(true)\n const validateInfo = async () => {\n await validateEns()\n setLoadingEns(false)\n setLoadedEns(true)\n }\n validateInfo()\n }\n }, 300)\n\n // snapshot ens validation\n useEffect(() => {\n debouncedSnapshotEnsValidation()\n // eslint-disable-next-line\n }, [params.snapshotEns])\n\n const {\n loading: loadingCredentials,\n execute: validateCredentials,\n error: invalidCredentials,\n } = useMonitoringValidation()\n\n const debouncedCredentialValidation = debounce(async () => {\n setValidatedCredentials(false)\n await validateCredentials(apiKey, apiSecret)\n setValidatedCredentials(true)\n }, 300)\n\n useEffect(() => {\n if (apiKey && apiSecret) {\n debouncedCredentialValidation()\n }\n\n // eslint-disable-next-line\n }, [apiKey, apiSecret])\n\n // add appropriate default amounts, chain dependant.\n // 1 ETH, 1500 xDAI, 1000 MATIC. Defaults to 1 unit otherwise.\n useEffect(() => {\n if (safe.chainId) {\n const defaultAmount =\n safe.chainId === 1\n ? \"1\"\n : safe.chainId === 100\n ? \"1500\"\n : safe.chainId === 137\n ? \"1000\"\n : \"1\"\n setParams((prevParams) => {\n return { ...prevParams, bond: defaultAmount }\n })\n }\n }, [safe.chainId])\n\n // on change in params, recheck validation\n useEffect(() => {\n setValidFields({\n snapshotEns: validSnapshot,\n bond: !!params.bond,\n })\n }, [params, loadingEns, validSnapshot])\n\n const onParamChange = (\n field: Field,\n value: RealityModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRealityModule = async () => {\n setDeploying(true)\n try {\n const minimumBond = ethers.utils.parseUnits(params.bond, bondToken.decimals)\n const args = {\n ...params,\n oracle: getDefaultOracle(safe.chainId),\n arbitrator: getKlerosAddress(safe.chainId),\n executor: safe.safeAddress,\n bond: minimumBond.toString(),\n }\n\n const templateQuestion = getDefaultTemplateQuestion(args.snapshotEns)\n const templateData: TemplateData = {\n templateType: \"default\",\n language: \"english\",\n category: \"DAO proposal\",\n templateQuestion: templateQuestion,\n }\n const deploymentRealityModuleTxsMm = await deployRealityModule(\n provider,\n safe.safeAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n safe.chainId,\n args,\n templateData,\n )\n\n let txs = [...deploymentRealityModuleTxsMm.txs]\n const realityModuleAddress = deploymentRealityModuleTxsMm.meta\n ?.expectedModuleAddress as string\n // We can only batch the SafeSnap creation when Safe is controller + mainnet\n // Otherwise, just create the module, hope the user got the hint and opened Details\n // to figure out how to set up SafeSnap in the space themselves.\n if (isController && safe.chainId === 1) {\n if (realityModuleAddress == null) {\n throw new Error(\n \"The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.\",\n )\n }\n const { txs: safeSnapTxs } = await addSafeSnapToSnapshotSpaceTxs(\n provider,\n args.snapshotEns,\n realityModuleAddress,\n safe.chainId,\n )\n txs.push(safeSnapTxs[0])\n }\n // If monitoring enabled, try to setup monitoring\n if (openMonitoring) {\n const monitoringData: MonitoringSectionData = {\n // api and secret are required for button to be enabled\n apiKey: apiKey,\n secretKey: apiSecret,\n discordKey: discordKey,\n email: emails,\n slackKey: \"\",\n telegram: { botToken: telegramBotToken, chatId: telegramChatId },\n }\n // we trust the notification parameters for discord and telegram are valid\n // user was forced to pass at least an email address to get here\n await setUpMonitoring(\n safe.chainId,\n realityModuleAddress,\n args.oracle,\n monitoringData,\n )\n }\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n setDeploying(false)\n }\n\n const handleBondChange = (event: React.ChangeEvent) => {\n const value = event.target.value || \"0\"\n const leftZero = value.startsWith(\"0\") && value.length > 1\n let bond = leftZero ? value.substr(1) : value\n bond = bond.startsWith(\".\") ? \"0\" + bond : bond\n\n try {\n ethers.utils.parseUnits(bond, bondToken.decimals)\n onParamChange(\"bond\", bond)\n } catch (error) {\n console.warn(\"invalid bond\", value, error)\n }\n }\n\n return (\n \n {step === \"form\" ? (\n <>\n Parameters\n\n \n \n onParamChange(\"snapshotEns\", e.target.value, true)}\n label=\"Snapshot Name\"\n placeholder=\"gnosis.eth\"\n rightIcon={\n <>\n {loadingEns ? (\n \n \n \n ) : loadedEns && validEns ? (\n \n \n \n ) : null}\n \n }\n />\n {!loadingEns && loadedEns && !validSnapshot && (\n \n )}\n \n \n onParamChange(\"timeout\", value)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n \n \n \n \n Configure Monitoring\n \n \n
\n {\n setOpenMonitoring(!openMonitoring)\n }}\n />\n \n \n {openMonitoring && (\n \n \n \n Setting up an effective monitoring strategy is critical for the security\n of your safe. First, you need to{\" \"}\n \n create an Open Zeppelin account\n \n .\n \n \n \n {\n setApiKey(e.target.value)\n }}\n label=\"API Key\"\n placeholder=\"3pwZzZZZzzZZZzzZZzZZZAAaaAAaaZZzz\"\n rightIcon={\n loadingCredentials ? (\n \n \n \n ) : (\n validatedCredentials &&\n !invalidCredentials && (\n \n \n \n )\n )\n }\n />\n \n\n \n {\n setApiSecret(e.target.value)\n }}\n label=\"API Secret\"\n placeholder=\"2LUwZwwuUuuUUzzZZdDddooodudDDdaaDDdaAAAddDDadDzZZzdDDdcCCdDDaaAA\"\n rightIcon={\n loadingCredentials ? (\n \n \n \n ) : (\n validatedCredentials &&\n !invalidCredentials && (\n \n \n \n )\n )\n }\n />\n \n\n {validatedCredentials && invalidCredentials && (\n \n \n \n )}\n\n {/* Emails section */}\n \n \n Email\n \n  (required)\n \n \n \n Enter as many email addresses as you need\n \n {\n setCurrentEmail(e.target.value)\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && emailIsValid) {\n setEmails([...emails, currentEmail])\n setCurrentEmail(\"\")\n }\n }}\n rightIcon={\n <>\n {emailIsValid ? (\n \n {\n setEmails([...emails, currentEmail])\n setCurrentEmail(\"\")\n }}\n >\n {\" \"}\n \n \n \n ) : null}\n \n }\n />\n {emails.length > 0 ? (\n emails.map((e) => (\n \n \n setEmails(emails.filter((x) => x !== e))}\n >\n \n \n \n \n {e}\n \n \n ))\n ) : (\n \n {emailIsValid\n ? \"Press Enter or click + to add this email\"\n : \"(No emails entered, at least one is required)\"}\n \n )}\n \n\n \n \n Discord Integration\n \n  (optional)\n \n \n \n \n Include the Discord channel's url key\n \n \n Learn more\n \n \n {\n setDiscordKey(e.target.value)\n }}\n placeholder=\"https://discord.com/api/webhooks/.../\"\n />\n \n\n \n \n Telegram Integration\n \n  (optional)\n \n \n \n \n Include the Telegram bot token and Chat ID\n \n \n Learn more\n \n \n \n \n \n {\n setTelegramBotToken(e.target.value)\n }}\n />\n \n \n {\n setTelegramChatId(e.target.value)\n }}\n />\n \n \n \n \n \n )}\n {/* Button Section */}\n }\n onClick={() => {\n setStep(\"confirm\")\n }}\n disabled={!canConfirm}\n style={{ marginTop: \"16px\" }}\n >\n {/* Button Messages */}\n {canConfirm || !openMonitoring\n ? \"Add Module\"\n : loadingCredentials\n ? \"Validating OpenZeppelin Credentials...\"\n : !validatedCredentials || invalidCredentials\n ? \"Missing OpenZeppelin API\"\n : \"Missing Email\"}\n \n \n ) : (\n <>\n It's almost ready! Just a reminder:\n {loadedEns &&\n (validSnapshot ? (\n isController && safe.chainId === 1 ? (\n isSafesnapInstalled ? (\n
\n SafeSnap plugin is already installed, and will be overwritten.\n
\n ) : (\n
The SafeSnap plugin will be automatically installed.
\n )\n ) : (\n // A way to paste the safesnap plugin info is here.\n
\n \n
\n )\n ) : (\n \n ))}\n {loadedEns && daorequirements === \"\" && (\n // Notice on how to setup DAO requirements, which appear on template.\n \n )}\n \n \n }\n onClick={() => setStep(\"form\")}\n >\n Return\n \n \n \n \n ) : (\n \n )\n }\n onClick={() => {\n handleAddRealityModule()\n }}\n >\n Add Module\n \n \n {deploying && openMonitoring && (\n \n
This can take around a minute, please wait...
\n
\n )}\n \n \n )}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Typography, makeStyles } from \"@material-ui/core\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ConnextModuleParams, deployConnextModule, getConnextAddress } from \"services\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\n\ninterface ConnextModuleProps {\n open: boolean\n onClose?(): void\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n addButton: {\n marginTop: theme.spacing(2),\n },\n addTransactionButton: {\n marginTop: theme.spacing(1),\n },\n addIcon: {\n stroke: theme.palette.common.white,\n width: 20,\n height: 20,\n },\n inputParam: {\n marginTop: theme.spacing(2),\n },\n errorMessage: {\n marginTop: theme.spacing(1),\n color: \"red\",\n },\n}))\n\nexport const ConnextModuleModal = ({ onSubmit, open, onClose }: ConnextModuleProps) => {\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n const classes = useStyles()\n\n const [errors, setErrors] = useState>({\n owner: false,\n avatar: false,\n target: false,\n domainId: true,\n sender: true,\n })\n\n const [params, setParams] = useState({\n owner: safe.safeAddress,\n avatar: safe.safeAddress,\n target: safe.safeAddress,\n domainId: 0,\n sender: \"\",\n })\n\n const onParamChange = (\n field: Field,\n value: ConnextModuleParams[Field],\n valid?: boolean,\n ) => {\n setErrors({ ...errors, [field]: !valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddConnextModule = async () => {\n try {\n const args = {\n ...params,\n }\n const txs = deployConnextModule(provider, safe.safeAddress, safe.chainId, args)\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.error(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n onParamChange(\"sender\", value, valid)}\n />\n\n onParamChange(\"domainId\", value, valid)}\n />\n\n \n {!getConnextAddress(safe.chainId) ? \"Not supported network for the Module\" : null}\n \n\n }\n onClick={handleAddConnextModule}\n >\n Add Module\n \n \n )\n}\n","import React from \"react\"\nimport { TellorModuleModal } from \"./TellorModule/TellorModuleModal\"\nimport { OptimisticGovernorModuleModal } from \"./OptimisticGovernorModule/OptimisticGovernorModuleModal\"\nimport { DelayModuleModal } from \"./DelayModule/DelayModuleModal\"\nimport { ModuleType } from \"../../../store/modules/models\"\nimport { CustomModuleModal } from \"./CustomModule/CustomModuleModal\"\nimport { AMBModuleModal } from \"./AMBModuleModal/AMBModuleModal\"\nimport { ExitModuleModal } from \"./ExitModule/ExitModuleModal\"\nimport { RolesV1ModifierModal } from \"./RolesModifier/RolesV1ModifierModal\"\nimport { RolesV2ModifierModal } from \"./RolesModifier/RolesV2ModifierModal\"\nimport { RealityModuleOldModal } from \"./RealityModuleOld/RealityModuleOldModal\"\nimport { KlerosRealityModuleModal } from \"./KlerosRealityModule/KlerosRealityModuleModal\"\nimport { ConnextModuleModal } from \"./ConnextModule/ConnextModuleModal\"\n\n/**\n * All wizards that use a Modal must be added here.\n */\n\ninterface ModuleModalsProps {\n selected?: ModuleType\n\n onClose?(): void\n\n onSubmit?(module: ModuleType): void\n}\n\nexport const ModuleModals = ({ selected, onClose, onSubmit }: ModuleModalsProps) => {\n return (\n <>\n onSubmit && onSubmit(ModuleType.TELLOR)}\n />\n onSubmit && onSubmit(ModuleType.OPTIMISTIC_GOVERNOR)}\n />\n onSubmit && onSubmit(ModuleType.DELAY)}\n />\n onSubmit && onSubmit(ModuleType.BRIDGE)}\n />\n onSubmit && onSubmit(ModuleType.EXIT)}\n />\n onSubmit && onSubmit(ModuleType.ROLES_V1)}\n />\n onSubmit && onSubmit(ModuleType.ROLES_V2)}\n />\n onSubmit && onSubmit(ModuleType.REALITY_ETH)}\n />\n onSubmit && onSubmit(ModuleType.KLEROS_REALITY)}\n />\n onSubmit && onSubmit(ModuleType.CONNEXT)}\n />\n\n onSubmit && onSubmit(ModuleType.UNKNOWN)}\n />\n \n )\n}\n","import React, { useState } from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { ModuleButton } from \"./ModuleButton\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getModulesList } from \"../../store/modules/selectors\"\nimport { ModuleModals } from \"./wizards/ModalWizards\"\nimport { ModuleType } from \"../../store/modules/models\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setOzGovernorModuleScreen,\n setRealityModuleScreen,\n} from \"../../store/modules\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { NETWORK } from \"utils/networks\"\nimport { klerosAvailability } from \"components/input/ArbitratorSelect\"\nimport {\n ContractAddresses as AllContractAddresses,\n KnownContracts,\n SupportedNetworks,\n} from \"@gnosis.pm/zodiac\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(1.5),\n },\n gridContainer: {\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fill, minmax(180px, 1fr))\",\n gap: theme.spacing(2),\n },\n paper: {\n padding: theme.spacing(2.5, 2),\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n introBox: {\n gridColumn: \"1/3\",\n \"@media (max-width:930px)\": {\n gridColumn: \"1/2\",\n },\n },\n firstModule: {\n gridColumn: 1,\n },\n link: {\n color: theme.palette.text.primary,\n },\n}))\n\nexport const AddModulesView = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const { safe } = useSafeAppsSDK()\n const hasModules = useRootSelector((state) => getModulesList(state).length > 0)\n const [module, setModule] = useState()\n\n const handleSubmit = () => {\n dispatch(fetchPendingModules(safe))\n dispatch(setModuleAdded(true))\n }\n\n const ContractAddresses = AllContractAddresses[safe.chainId as SupportedNetworks]\n\n const title = hasModules ? \"Add another mod\" : \"Start by adding a mod\"\n\n return (\n
\n
\n
\n \n \n {title}\n \n \n Built according to an open standard, the Zodiac collection of tools are mods\n that support, expand, and transform how organizations operate. Learn more\n about Zodiac in{\" \"}\n \n this article\n {\" \"}\n and about Gnosis Safe modules more generally in{\" \"}\n \n this article\n \n .\n \n \n
\n\n setModule(ModuleType.BRIDGE)}\n className={classes.firstModule}\n available={!!ContractAddresses[KnownContracts.BRIDGE]}\n />\n\n setModule(ModuleType.DELAY)}\n available={!!ContractAddresses[KnownContracts.DELAY]}\n />\n\n setModule(ModuleType.EXIT)}\n available={!!ContractAddresses[KnownContracts.EXIT_ERC20]}\n />\n\n setModule(ModuleType.ROLES_V2)}\n available={!!ContractAddresses[KnownContracts.ROLES_V2]}\n />\n\n dispatch(setRealityModuleScreen(true))}\n available={[NETWORK.MAINNET, NETWORK.GOERLI].includes(safe.chainId)}\n />\n\n setModule(ModuleType.REALITY_ETH)}\n available={[NETWORK.MAINNET, NETWORK.GOERLI].includes(safe.chainId)}\n />\n\n setModule(ModuleType.KLEROS_REALITY)}\n available={klerosAvailability.includes(safe.chainId)}\n />\n\n setModule(ModuleType.TELLOR)}\n available={!!ContractAddresses[KnownContracts.TELLOR]}\n />\n\n setModule(ModuleType.OPTIMISTIC_GOVERNOR)}\n available // TODO\n />\n\n dispatch(setOzGovernorModuleScreen(true))}\n available={!!ContractAddresses[KnownContracts.OZ_GOVERNOR]}\n />\n\n setModule(ModuleType.CONNEXT)}\n available={!!ContractAddresses[KnownContracts.CONNEXT]}\n />\n\n setModule(ModuleType.ROLES_V1)}\n available={!!ContractAddresses[KnownContracts.ROLES_V1]}\n />\n\n setModule(ModuleType.UNKNOWN)}\n available\n />\n
\n\n setModule(undefined)}\n onSubmit={handleSubmit}\n />\n
\n )\n}\n\nexport default AddModulesView\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { ContractReadFunctionsList } from \"./ContractReadFunctionsList\";\nimport { ContractOperationToggleButtons } from \"../ContractOperationToggleButtons\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface ContractInteractionsPreviewProps {\n address: string;\n abi: ContractInterface;\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(2.5),\n marginTop: theme.spacing(3),\n },\n}));\n\nexport const ContractInteractionsPreview = ({\n address,\n abi,\n}: ContractInteractionsPreviewProps) => {\n const classes = useStyles();\n\n return (\n <>\n \n\n \n \n \n \n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { useRootSelector } from \"../../store\";\nimport {\n getCurrentPendingModule,\n getSafeThreshold,\n} from \"../../store/modules/selectors\";\nimport { ContractInteractionsPreview } from \"./contract/ContractInteractionsPreview\";\nimport { getModuleContractMetadata } from \"../../utils/modulesValidation\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(3),\n },\n paper: {\n padding: theme.spacing(2.5),\n maxWidth: 500,\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n header: {\n display: \"grid\",\n gridTemplateColumns: \"50px auto\",\n gridGap: theme.spacing(2),\n alignItems: \"center\",\n marginBottom: theme.spacing(3),\n },\n addressText: {\n margin: theme.spacing(0, 2, 0, 3),\n fontWeight: \"bold\",\n },\n icon: {\n marginLeft: \"16px\",\n },\n buttons: {\n marginTop: theme.spacing(3),\n opacity: 0.5,\n },\n}));\n\nfunction ModulePendingInstantTx() {\n const currentPendingTx = useRootSelector(getCurrentPendingModule);\n\n if (!currentPendingTx) return null;\n\n const metadata = getModuleContractMetadata(currentPendingTx.module);\n\n if (!metadata || !metadata.abi) return null;\n\n return (\n \n );\n}\n\nexport const ModulePendingTransaction = () => {\n const classes = useStyles();\n const safeThreshold = useRootSelector(getSafeThreshold);\n const isInstantExecution = safeThreshold === 1;\n\n return (\n
\n
\n \n \n
\n\n {!isInstantExecution ? (\n \n \n Waiting on module approval\n \n \n Once this module transaction has been approved by the other signers,\n you will be able to read and write to it.\n \n \n ) : (\n \n )}\n
\n );\n};\n","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React, { useEffect, useState } from \"react\"\nimport { colors, ZodiacTextField } from \"zodiac-ui-components\"\nimport { InputPartProps, ORACLE_MAINNET_OPTIONS, ORACLE_GOERLI_OPTIONS } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n padding: \"9px 8px\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n}))\n\nexport type Data = {\n instanceAddress: string\n instanceType: \"ETH\" | \"GNO\" | \"custom\"\n}\n\nexport const OracleInstance: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const options = safe.chainId === 1 ? ORACLE_MAINNET_OPTIONS : ORACLE_GOERLI_OPTIONS\n const [selectedOracle, setSelectedOracle] = useState(\"\")\n\n useEffect(() => {\n if (data && options.length && selectedOracle === \"\") {\n const item = options.filter((element) =>\n element.label.includes(data.instanceAddress),\n )\n setSelectedOracle(item[0].value)\n }\n }, [data, options, selectedOracle])\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const handleInstance = (instance: string) => {\n if (instance === \"custom\") {\n set(\"instanceType\")(instance)\n return\n }\n const address = instance.substr(instance.indexOf(\"-\") + 1)\n const instanceType = instance.substr(0, instance.indexOf(\"-\"))\n setSelectedOracle(instance)\n set(\"instanceAddress\")(address)\n set(\"instanceType\")(instanceType as string)\n }\n\n return (\n \n \n \n \n \n Oracle Instance\n \n \n \n \n The oracle instance sets the appropriate bond token. It's recommended\n to use the default (ETH) oracle instance unless you have a specific reason\n to use something like a native token which can potentially be more prone to\n price manipulation.\n \n \n \n \n \n {\n handleInstance(target.value as string)\n }}\n />\n \n {get(\"instanceType\") === \"custom\" && (\n \n \n \n set(\"instanceAddress\")(evt.target.value as string)}\n />\n \n \n {/* //TODO: get the bond token name from the contract} */}\n WEENUS\n \n \n \n )}\n \n )\n}\n\nexport default OracleInstance\n","export const DEFAULT_TIMEOUT = 172800 // 2 Days\nexport const MIN_TIMEOUT = 86400 // 1 Day\nexport const WARNING_TIMEOUT = 172800 // 2 Days\nexport const DEFAULT_COOLDOWN = 172800 // 2 Days\nexport const WARNING_COOLDOWN = 172800 // 2 Days\nexport const MIN_COOLDOWN = 0\nexport const DEFAULT_EXPIRATION = 604800 // 7 Days\nexport const WARNING_EXPIRATION = 432000 // 5 Day\nexport const MIN_EXPIRATION = 86400 // 1 Day\n\nexport const TIMEOUT_WARNING_MSG =\n \"We highly recommend that your timeout delay exceeds 48 hours.\"\nexport const TIMEOUT_ERROR_MSG = \"Your timeout delay must exceed 24 hours.\"\nexport const COOLDOWN_WARNING_MSG =\n \"We highly recommend that your cooldown delay exceeds 48 hours.\"\nexport const COOLDOWN_ERROR_MSG = \"Your cooldown delay must exceed 0\"\nexport const EXPIRATION_WARNING_MSG =\n \"We highly recommend that your expiration delay exceeds cooldown + 5 days.\"\nexport const EXPIRATION_ERROR_MSG =\n \"Your expiration delay must exceeds cooldown + 1 days.\"\n\nexport const isValidOracleDelay = (\n type: \"timeout\" | \"cooldown\" | \"expiration\",\n delayValue: string | number,\n dependsDelayValue?: string | number,\n): boolean => {\n const value = parseInt(delayValue as string)\n const depends = parseInt(dependsDelayValue as string)\n switch (type) {\n case \"timeout\":\n if (value < MIN_TIMEOUT) {\n return false\n }\n break\n case \"cooldown\":\n if (value <= MIN_COOLDOWN) {\n return false\n }\n break\n case \"expiration\":\n if (value === 0) {\n return true\n }\n if (dependsDelayValue && value < depends + MIN_EXPIRATION) {\n return false\n }\n break\n }\n return true\n}\n\nexport const warningOracleDelay = (\n type: \"timeout\" | \"cooldown\" | \"expiration\",\n delayValue: string | number,\n): boolean => {\n const value = parseInt(delayValue as string)\n switch (type) {\n case \"timeout\":\n if (value >= MIN_TIMEOUT && value < WARNING_TIMEOUT) {\n return false\n }\n break\n case \"cooldown\":\n if (value >= MIN_COOLDOWN && value < WARNING_COOLDOWN) {\n return false\n }\n break\n case \"expiration\":\n if (value === 0) {\n return false\n }\n if (value >= MIN_EXPIRATION && value < WARNING_EXPIRATION) {\n return false\n }\n break\n }\n return true\n}\n","import React from \"react\"\nimport { Grid, Typography, makeStyles } from \"@material-ui/core\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport ReportProblemOutlinedIcon from \"@material-ui/icons/ReportProblemOutlined\"\nimport { colors } from \"zodiac-ui-components\"\n\nconst useStyles = makeStyles(() => ({\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n },\n warningIcon: {\n fill: colors.tan[800],\n },\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n warningMessage: {\n fontSize: 12,\n color: colors.tan[800],\n },\n}))\n\nexport const OracleAlert: React.FC<{\n type: \"error\" | \"warning\"\n message: string\n}> = ({ type, message }) => {\n const classes = useStyles()\n return (\n \n {type === \"error\" && (\n \n {\" \"}\n \n )}\n\n {type === \"warning\" && (\n \n \n \n )}\n\n \n \n {message}\n \n \n \n )\n}\n","import { Grid } from \"@material-ui/core\"\nimport React, { Fragment, useEffect, useState } from \"react\"\nimport {\n COOLDOWN_ERROR_MSG,\n COOLDOWN_WARNING_MSG,\n EXPIRATION_ERROR_MSG,\n EXPIRATION_WARNING_MSG,\n isValidOracleDelay,\n TIMEOUT_ERROR_MSG,\n TIMEOUT_WARNING_MSG,\n warningOracleDelay,\n} from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { OracleAlert } from \"../OracleAlert\"\n\nexport interface OracleDelayValidationProps {\n type: \"timeout\" | \"cooldown\" | \"expiration\"\n delayValue: string | number\n dependsDelayValue?: string | number\n}\ninterface OracleAlertType {\n type: \"error\" | \"warning\"\n message: string\n}\n\nexport const OracleDelayValidation: React.FC = ({\n type,\n delayValue,\n dependsDelayValue,\n}) => {\n const timeoutError = isValidOracleDelay(\"timeout\", parseInt(delayValue as string))\n const cooldownError = isValidOracleDelay(\"cooldown\", parseInt(delayValue as string))\n const expirationError = isValidOracleDelay(\n \"expiration\",\n parseInt(delayValue as string),\n dependsDelayValue,\n )\n const timeoutWarning = warningOracleDelay(\"timeout\", parseInt(delayValue as string))\n const cooldownWarning = warningOracleDelay(\"cooldown\", parseInt(delayValue as string))\n const expirationWarning = warningOracleDelay(\n \"expiration\",\n parseInt(delayValue as string),\n )\n\n const [timeoutAlert, setTimeoutAlert] = useState(undefined)\n const [cooldownAlert, setCooldownAlert] = useState(\n undefined,\n )\n const [expirationAlert, setExpirationAlert] = useState(\n undefined,\n )\n\n useEffect(() => {\n if (!timeoutError) {\n return setTimeoutAlert({ type: \"error\", message: TIMEOUT_ERROR_MSG })\n }\n if (!timeoutWarning) {\n return setTimeoutAlert({ type: \"warning\", message: TIMEOUT_WARNING_MSG })\n }\n setTimeoutAlert(undefined)\n }, [timeoutError, timeoutWarning])\n\n useEffect(() => {\n if (!cooldownError) {\n return setCooldownAlert({ type: \"error\", message: COOLDOWN_ERROR_MSG })\n }\n if (!cooldownWarning) {\n return setCooldownAlert({ type: \"warning\", message: COOLDOWN_WARNING_MSG })\n }\n setCooldownAlert(undefined)\n }, [cooldownError, cooldownWarning])\n\n useEffect(() => {\n if (!expirationError) {\n return setExpirationAlert({ type: \"error\", message: EXPIRATION_ERROR_MSG })\n }\n if (!expirationWarning) {\n return setExpirationAlert({ type: \"warning\", message: EXPIRATION_WARNING_MSG })\n }\n setExpirationAlert(undefined)\n }, [expirationError, expirationWarning])\n\n return (\n \n {type === \"timeout\" && timeoutAlert && (\n \n \n \n )}\n {type === \"cooldown\" && cooldownAlert && (\n \n \n \n )}\n {type === \"expiration\" && expirationAlert && (\n \n \n \n )}\n \n )\n}\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { TimeSelect, unitConversion } from \"components/input/TimeSelect\"\nimport React from \"react\"\nimport { isValidOracleDelay } from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { InputPartProps } from \"../..\"\nimport { OracleDelayValidation } from \"../OracleDelayValidation\"\n\nconst useStyles = makeStyles(() => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n}))\n\ntype Unit = keyof typeof unitConversion\n\nexport type Data = {\n expiration: number\n expirationUnit: Unit\n cooldown: number\n cooldownUnit: Unit\n timeout: number\n timeoutUnit: Unit\n}\n\nexport const OracleDelay: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n const get = (key: keyof Data) => data[key]\n const timeout = get(\"timeout\")\n const cooldown = get(\"cooldown\")\n const expiration = get(\"expiration\")\n const isValidTimeout = isValidOracleDelay(\"timeout\", timeout)\n const isValidCooldown = isValidOracleDelay(\"cooldown\", cooldown)\n const isValidExpiration = isValidOracleDelay(\"expiration\", expiration, cooldown)\n\n return (\n \n \n \n \n \n Delay Configuration\n \n \n \n \n These Parameters are very important for your DAO's security and should\n be considered carefully. Allowing enough time in these configurations will\n enable the safe to have a final chance to veto or circumvent any potential\n malicious proposals that have snuck through.\n \n \n \n \n \n \n \n {\n setData({ ...data, timeout: value, timeoutUnit: unit })\n }}\n />\n \n \n {\n setData({ ...data, cooldown: value, cooldownUnit: unit })\n }}\n />\n \n \n {\n setData({ ...data, expiration: value, expirationUnit: unit })\n }}\n />\n \n \n \n \n \n \n \n )\n}\nexport default OracleDelay\n","import { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { ZodiacTextField, colors } from \"zodiac-ui-components\"\nimport { InputPartProps } from \"../..\"\nimport { OracleAlert } from \"../OracleAlert\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n error: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n}))\n\nexport const MIN_BOND = 0.1\n\nexport type Data = {\n bond: number\n}\n\nexport const OracleBond: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const bond = get(\"bond\")\n\n return (\n \n \n \n \n \n Bond\n \n \n \n \n Minimum bond required for an answer to be accepted. New answers must be\n submitted with double the previous bond. For more on why a bond is required\n in an escalation-game-based oracle, read more in the{\" \"}\n \n Reality.eth whitepaper.\n \n \n \n \n \n \n set(\"bond\")(e.target.value)}\n />\n \n {bond < MIN_BOND && (\n \n \n \n )}\n \n )\n}\n\nexport default OracleBond\n","import { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React from \"react\"\nimport { ARBITRATOR_OPTIONS } from \"services\"\nimport { InputPartProps } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n}))\n\nexport type Data = {\n arbitratorOption: ARBITRATOR_OPTIONS\n}\n\nexport const OracleArbitration: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n return (\n \n \n \n \n \n Arbitration\n \n \n \n \n An arbitrator is responsible for providing a final answer to a question when there is a dispute, in\n exchange for a fee. In most cases, the bond escalation-game eliminates the need for this. However, if you\n feel it's necessary to include a backup arbitration strategy incase of a dispute, you can select one\n from below. Read more in the{` `}\n \n Reality.eth arbitrators documentation\n \n .\n \n \n \n \n \n set(\"arbitratorOption\")(target.value)}\n />\n \n \n )\n}\n\nexport default OracleArbitration\n","import { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { Link } from \"components/text/Link\"\nimport React, { useEffect, useState } from \"react\"\nimport { ZodiacModal, ZodiacPaper } from \"zodiac-ui-components\"\nimport OracleTemplate, {\n Data as OracleTemplateData,\n getDefaultTemplateQuestion,\n} from \"./components/OracleTemplate\"\nimport OracleInstance, { Data as OracleInstanceData } from \"./components/OracleInstance\"\nimport OracleDelay, { Data as OracleDelayData } from \"./components/OracleDelay\"\nimport OracleBond, { Data as OracleBondData, MIN_BOND } from \"./components/OracleBond\"\nimport OracleArbitration, {\n Data as OracleArbitratorData,\n} from \"./components/OracleArbitration\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { ARBITRATOR_OPTIONS } from \"services\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport { OracleAlert } from \"./components/OracleAlert\"\nimport {\n DEFAULT_COOLDOWN,\n DEFAULT_EXPIRATION,\n DEFAULT_TIMEOUT,\n isValidOracleDelay,\n warningOracleDelay,\n} from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { OracleDelayValidation } from \"./components/OracleDelayValidation\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n icon: {\n fill: \"white\",\n width: \"20px\",\n },\n\n divider: {\n marginTop: 8,\n marginBottom: 8,\n },\n warningModal: {\n maxWidth: 650,\n },\n errorPaperContainer: {\n width: \"100%\",\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n border: 0,\n borderRadius: 4,\n display: \"inline-block\",\n \"& .MuiTypography-root\": {\n fontFamily: \"Roboto Mono\",\n },\n },\n}))\n\nexport const ORACLE_MAINNET_OPTIONS = [\n {\n label: \"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\",\n value: \"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\",\n },\n {\n label: \"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9\",\n value: \"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9\",\n },\n // { label: \"Add Custom Instance\", value: \"custom\" },\n]\n\nexport const ORACLE_GOERLI_OPTIONS = [\n {\n label: \"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\",\n value: \"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\",\n },\n // { label: \"Add Custom Instance\", value: \"custom\" },\n]\n\nexport interface InputPartProps {\n data: any\n setData: (data: any) => void\n}\n\nexport type OracleSectionData = {\n templateData: OracleTemplateData\n instanceData: OracleInstanceData\n delayData: OracleDelayData\n bondData: OracleBondData\n arbitratorData: OracleArbitratorData\n}\n\nexport const OracleSection: React.FC = ({\n handleBack,\n handleNext,\n setupData,\n}) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const options = safe.chainId === 1 ? ORACLE_MAINNET_OPTIONS : ORACLE_GOERLI_OPTIONS\n const [showModal, setShowModal] = useState(false)\n if (setupData?.proposal.ensName == null) {\n throw new Error(\"ENS name is not set\")\n }\n const [templateData, setTemplateData] = useState({\n templateType: \"default\",\n language: \"english\",\n category: \"DAO proposal\",\n templateQuestion: getDefaultTemplateQuestion(setupData?.proposal.ensName),\n })\n\n const [instanceData, setInstanceData] = useState({\n instanceAddress: options[0].value.substr(options[0].value.indexOf(\"-\") + 1),\n instanceType: options[0].value.substr(0, options[0].value.indexOf(\"-\")) as\n | \"ETH\"\n | \"GNO\"\n | \"custom\",\n })\n\n const [delayData, setDelayData] = useState({\n timeout: DEFAULT_TIMEOUT,\n timeoutUnit: \"days\",\n cooldown: DEFAULT_COOLDOWN,\n cooldownUnit: \"days\",\n expiration: DEFAULT_EXPIRATION,\n expirationUnit: \"days\",\n })\n\n const [bondData, setBondData] = useState({\n bond: 0.1,\n })\n\n const { timeout, cooldown, expiration } = delayData\n const { bond } = bondData\n const isValidTimeout = isValidOracleDelay(\"timeout\", timeout)\n const isValidCooldown = isValidOracleDelay(\"cooldown\", cooldown)\n const isValidExpiration = isValidOracleDelay(\"expiration\", expiration, cooldown)\n const isWarningTimeout = warningOracleDelay(\"timeout\", timeout)\n const isWarningCooldown = warningOracleDelay(\"cooldown\", cooldown)\n const isWarningExpiration = warningOracleDelay(\"expiration\", expiration)\n\n const [arbitratorData, setArbitratorData] = useState({\n arbitratorOption: ARBITRATOR_OPTIONS.NO_ARBITRATOR,\n })\n\n const collectData = (): OracleSectionData => ({\n templateData,\n instanceData,\n delayData,\n bondData,\n arbitratorData,\n })\n\n const validateOracle = () => {\n if (\n [isWarningTimeout, isWarningCooldown, isWarningExpiration].includes(false) ||\n bond < MIN_BOND\n ) {\n return setShowModal(true)\n }\n handleNext(collectData())\n }\n\n useEffect(() => {\n if (setupData && setupData.oracle) {\n const { bondData, delayData, instanceData, templateData, arbitratorData } =\n setupData.oracle\n setBondData(bondData)\n setDelayData(delayData)\n setInstanceData(instanceData)\n setTemplateData(templateData)\n setArbitratorData(arbitratorData)\n }\n }, [setupData])\n\n if (setupData?.proposal.ensName == null) {\n throw new Error(\n \"The ENS name is not available, it needs to already be in the setupData, before initiating this step.\",\n )\n }\n\n return (\n \n \n \n \n \n Set up the Oracle\n \n \n \n Now, it's time to set up the oracle for your reality module. The\n oracle ensures the results of proposals are brought accurately on-chain.\n The Reality.eth oracle uses a mechanism known as the{\" \"}\n \n escalation game\n {\" \"}\n to generate correct answers that can be used as inputs for smart\n contracts. The following parameters are very important for your DAO's\n security and should be considered carefully.\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n handleBack(collectData())}\n >\n Back\n \n \n \n \n Next\n \n \n \n \n \n setShowModal(!showModal)}\n children={\n \n \n \n \n \n \n \n Security Risk Detected\n \n \n \n\n \n \n The following security risks have been detected. We highly recommend that\n you resolve them before moving forward, as these can leave to loss of\n funds.\n \n \n\n \n \n \n \n \n {bond < MIN_BOND && (\n \n \n \n )}\n \n \n\n \n \n \n\n \n \n \n \n \n \n setShowModal(false)}\n >\n Resolve (Recommended)\n \n \n \n \n \n }\n />\n \n )\n}\n\nexport default OracleSection\n","import React from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { Link } from \"components/text/Link\"\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n fill: \"white\",\n width: \"20px\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n background: \"rgba(244, 67, 54, 0.1)\",\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n \"&, &:before, &:after\": {\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n },\n },\n addressPaperContainer: {\n width: \"100%\",\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n border: 0,\n borderRadius: 4,\n display: \"inline-block\",\n \"& .MuiTypography-root\": {\n fontFamily: \"Roboto Mono\",\n },\n },\n}))\n\nexport interface ProposalDetailsModalProps {\n title: string\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\"\n address?: string\n}\n\nexport const ProposalDetailsModal: React.FC = ({\n title,\n type,\n address,\n}) => {\n const classes = useStyles()\n\n return (\n \n \n \n \n \n \n \n {title}\n \n \n \n \n \n {type === \"controller\" &&\n \"The safe you are currently using with Zodiac is not the controller of the ENS you've entered. Try one of the following: \"}\n {type === \"owner\" &&\n \"The ENS that you've entered is not owned by a safe. This gives unilateral control to the individual with this address: \"}\n {type === \"safesnap\" &&\n \"The Snapshot space has already installed the Safesnap plugin.\"}\n {type === \"snapshot\" &&\n title.includes(\"Invalid\") &&\n \"The current snapshot settings file is invalid. Check the browser console for validation details. The schema for validating the settings file can be found\"}\n {type === \"snapshot\" && title.includes(\"Invalid\") && (\n <>\n {\" \"}\n \n here.\n \n \n )}\n {type === \"snapshot\" &&\n !title.includes(\"Invalid\") &&\n \"The ENS you've entered is not setup with a Snapshot space. To setup a snapshot space with this ENS, follow the guide\"}\n\n {type === \"snapshot\" && !title.includes(\"Invalid\") && (\n <>\n {\" \"}\n \n here.\n \n \n )}\n \n \n {address && (\n \n \n \n {address}\n \n \n \n )}\n {[\"controller\", \"owner\"].includes(type) && (\n \n \n {type === \"controller\" && \"- Check that your ENS is typed correctly.\"}\n {type === \"owner\" &&\n \"We highly recommend transferring the ENS to a multisig safe before continuing.\"}\n \n \n )}\n\n {type === \"controller\" && (\n \n \n - Update your ENS controller settings via the{\" \"}\n \n ENS.\n \n \n \n )}\n \n )\n}\n\nexport default ProposalDetailsModal\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React, { useState } from \"react\"\n\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport WarningOutlinedIcon from \"@material-ui/icons/WarningOutlined\"\nimport { ZodiacModal } from \"zodiac-ui-components\"\nimport ProposalDetailsModal from \"./ProposalDetailsModal\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n messageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n },\n\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"20px\",\n },\n detailsContainer: {\n width: \"95%\",\n },\n messageContainer: {\n width: \"85%\",\n },\n}))\n\nexport interface ProposalStatusProps {\n status: \"error\" | \"warning\" | null\n message: string | null\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\"\n address?: string\n}\n\nexport const ProposalStatus: React.FC = ({\n status,\n message,\n type,\n address,\n}) => {\n const classes = useStyles()\n const [showModal, setShowModal] = useState(false)\n\n const handleTitle = (): string => {\n switch (type) {\n case \"controller\":\n return \"Safe not controller of ENS\"\n\n case \"owner\":\n return \"Security Risk Detected\"\n\n case \"snapshot\":\n if (message?.includes(\"invalid\")) {\n return \"Invalid Snapshot settings file\"\n }\n return \"Snapshot space not found\"\n\n case \"safesnap\":\n return \"Safesnap plugin is already installed\"\n\n default:\n return \"\"\n }\n }\n\n const title = handleTitle()\n return (\n status && (\n \n \n {status === \"error\" && }\n {status === \"warning\" && }\n \n \n \n \n {message}\n \n \n setShowModal(!showModal)}\n >\n Details\n \n \n \n \n setShowModal(!showModal)}\n children={}\n />\n \n )\n )\n}\n\nexport default ProposalStatus\n","export const handleProposalStatus = (\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\",\n loading: boolean,\n isController: boolean,\n isOwner: boolean,\n hasSnapshot: boolean,\n validSnapshot: boolean,\n isSafesnapInstalled: boolean,\n): \"warning\" | \"error\" | null => {\n if (!loading) {\n if (type === \"snapshot\" && !hasSnapshot) {\n return \"error\"\n }\n if (type === \"snapshot\" && !validSnapshot) {\n return \"error\"\n }\n if (type === \"controller\" && !isController) {\n return \"error\"\n }\n if (type === \"safesnap\" && isSafesnapInstalled) {\n return \"error\"\n }\n if (type === \"owner\" && !isOwner) {\n return \"warning\"\n }\n }\n return null\n}\n\nexport const handleProposalStatusMessage = (\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\",\n isController: boolean,\n isOwner: boolean,\n hasSnapshot: boolean,\n hasValidSnapshot: boolean,\n isSafesnapInstalled: boolean,\n): string | null => {\n if (type === \"snapshot\" && !hasSnapshot) {\n return \"The ENS name should have a Snapshot space created.\"\n }\n if (type === \"snapshot\" && !hasValidSnapshot) {\n return \"Your snapshot settings file is invalid.\"\n }\n if (type === \"controller\" && !isController) {\n return \"The safe must be the controller of the ENS name.\"\n }\n if (type === \"owner\" && !isOwner) {\n return \"The safe is not the owner of the ENS name. We highly recommend transferring the ENS to this safe or enter a different ENS before continuing.\"\n }\n if (type === \"safesnap\" && isSafesnapInstalled) {\n return \"The plugin is already installed on the Snapshot space.\"\n }\n return null\n}\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport {\n Box,\n Button,\n Divider,\n Grid,\n makeStyles,\n // FormControlLabel,\n // Radio,\n // RadioGroup,\n Typography,\n} from \"@material-ui/core\"\n\nimport { Link } from \"components/text/Link\"\nimport React, { useEffect, useState } from \"react\"\n// import useSpace from \"services/snapshot/hooks/useSpace\"\nimport { checkIfIsController, checkIfIsOwner } from \"services/ens\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport ProposalStatus from \"./components/ProposalStatus\"\nimport * as snapshot from \"services/snapshot\"\nimport {\n handleProposalStatus,\n handleProposalStatusMessage,\n} from \"utils/proposalValidation\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { safeAppUrl } from \"utils/url\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n doneIcon: {\n marginRight: 4,\n fill: \"#A8E07E\",\n width: \"16px\",\n },\n errorIcon: {\n marginRight: 4,\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"16px\",\n },\n\n loadingContainer: {\n marginRight: 4,\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 14,\n width: 14,\n border: `1px solid ${colors.tan[300]}`,\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `${colors.tan[300]} !important`,\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n marginRight: 8,\n },\n radio: {\n marginLeft: -2,\n padding: 2,\n \"& ~ .MuiFormControlLabel-label\": {\n fontSize: 12,\n marginLeft: 4,\n },\n \"&$checked\": {\n color: colors.tan[1000],\n },\n },\n checked: {},\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n textFieldSmall: {\n \"& .MuiFormLabel-root\": {\n fontSize: 12,\n },\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n errorContainer: { margin: 8, display: \"flex\", alignItems: \"center\" },\n}))\n\nexport type ProposalSectionData = {\n // proposalType: \"snapshot\" | \"custom\";\n ensName: string\n}\n\nexport const ProposalSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const { safe, provider } = useSafeAppsSDKWithProvider()\n const classes = useStyles()\n // const [proposalType, setProposalType] = useState<\"snapshot\" | \"custom\">(\n // \"snapshot\"\n // );\n const [ensName, setEnsName] = useState(\"\")\n const [ensAddress, setEnsAddress] = useState(\"\")\n const [isOwner, setIsOwner] = useState(false)\n const [isSafesnapInstalled, setIsSafesnapInstalled] = useState(false)\n const [isController, setIsController] = useState(false)\n const [hasSnapshot, setHasSnapshot] = useState(false)\n const [validSnapshot, setValidSnapshot] = useState(false)\n const [loading, setLoading] = useState(false)\n const [ensIsValid, setEnsIsValid] = useState(false)\n\n useEffect(() => {\n if (provider && setupData && setupData.proposal) {\n setEnsName(setupData.proposal.ensName)\n }\n }, [])\n\n useEffect(() => {\n if (ensName) {\n if (ensName.includes(\".eth\")) {\n setEnsIsValid(true)\n setLoading(true)\n const validateInfo = async () => {\n await validEns()\n }\n validateInfo()\n } else {\n setEnsIsValid(false)\n setIsController(false)\n setIsOwner(false)\n }\n }\n }, [ensName])\n\n const validEns = async () => {\n const address = await provider.resolveName(ensName)\n if (address) {\n const snapshotSpace = await snapshot.getSnapshotSpaceSettings(ensName, safe.chainId)\n const snapshotSpaceValidation = snapshot.validateSchema(snapshotSpace)\n const isOwner = await checkIfIsOwner(provider, ensName, safe.safeAddress)\n const isController = await checkIfIsController(provider, ensName, safe.safeAddress)\n const plugins = snapshotSpace?.plugins\n if (plugins) {\n setIsSafesnapInstalled(plugins.safeSnap ? true : false) // comment out for easy testing\n }\n if (snapshotSpaceValidation !== true) {\n console.log(\n \"The current snapshot space is not valid. Valid snapshot space schema. Errors:\",\n )\n console.log(JSON.stringify(snapshot.validateSchema(snapshotSpace), undefined, 2))\n }\n setHasSnapshot(snapshotSpace ? true : false)\n setValidSnapshot(snapshotSpaceValidation === true)\n setIsOwner(isOwner)\n setIsController(isController)\n setEnsAddress(address)\n setLoading(false)\n return\n } else {\n setEnsAddress(\"\")\n setLoading(false)\n setIsOwner(false)\n setIsController(false)\n setHasSnapshot(false)\n setValidSnapshot(false)\n setIsSafesnapInstalled(false)\n return\n }\n }\n\n const collectSectionData = (): ProposalSectionData => ({\n // proposalType,\n ensName,\n })\n\n // const handleChange = (event: React.ChangeEvent) => {\n // setProposalType(\n // (event.target as HTMLInputElement).value as \"snapshot\" | \"custom\"\n // );\n // };\n\n const handleEns = (ens: string) => {\n if (ens === \"\") {\n setIsController(false)\n setIsOwner(false)\n setHasSnapshot(false)\n setValidSnapshot(false)\n setEnsName(\"\")\n } else {\n setEnsName(ens)\n }\n }\n\n return (\n \n \n \n \n \n Configure Proposal Space\n \n \n \n Add your preferred proposal type below to get started. If you're\n unsure, we recommend starting with Snapshot.\n \n \n \n \n Don't have a snapshot space setup yet?{` `}\n \n Get started here.\n \n \n \n \n \n \n \n \n \n \n \n \n Proposal Configuration\n \n \n \n \n {/* Enter your snapshot space ENS domain below to get started. If\n you'd prefer to provide a custom proposal integration,\n select Custom and provide the appropriate URL where the\n proposals can be viewed publicly. */}\n Enter your snapshot space ENS domain below to get started. The Safe must\n be the controller of this ENS domain.\n \n \n {/* For now we're only use snapshot space */}\n {/* \n \n Select your proposal type:\n \n \n \n }\n label=\"Snapshot\"\n />\n \n }\n label=\"Custom\"\n />\n \n */}\n \n handleEns(target.value)}\n label=\"Enter the Snapshot ENS name.\"\n placeholder=\"ex: gnosis.eth\"\n borderStyle=\"double\"\n className={`${classes.textFieldSmall} ${\n ensName.includes(\".eth\") &&\n !loading &&\n (!hasSnapshot || !isController || !isOwner)\n ? classes.inputError\n : classes.input\n }`}\n rightIcon={\n <>\n {loading && (\n \n \n \n )}\n {ensName.includes(\".eth\") &&\n !loading &&\n (!hasSnapshot || !isController || !isOwner) && (\n \n )}\n {ensName.includes(\".eth\") &&\n !loading &&\n hasSnapshot &&\n isController &&\n isOwner && }\n \n }\n />\n
\n
\n\n {ensIsValid && (\n <>\n \n \n \n \n {/* {ensAddress && !isOwner && handleProposalStatus(\"owner\") === \"error\" && (\n \n \n \n )} */}\n \n )}\n
\n
\n
\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Cancel\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n
\n
\n )\n}\n\nexport default ProposalSection\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\";\nimport React from \"react\";\nimport { colors } from \"zodiac-ui-components\";\n\ntype CircleStepProps = {\n label: string;\n number: number;\n onClick: () => void;\n disabled?: boolean;\n};\n\nconst useStyles = makeStyles((theme) => ({\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 25,\n width: 25,\n border: `1px solid ${colors.tan[300]}`,\n background: colors.blue[500],\n },\n label: {\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n}));\n\nexport const CircleStep: React.FC = ({\n label,\n number,\n disabled,\n onClick,\n}) => {\n const classes = useStyles();\n return (\n {\n !disabled && onClick();\n }}>\n \n \n {number}\n \n \n \n {label}\n \n \n );\n};\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors } from \"zodiac-ui-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ClearIcon from \"@material-ui/icons/Clear\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: \"0.9rem\",\n },\n messageError: {\n fontSize: \"0.9rem\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n background: colors.tan[1000],\n },\n loadingContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: `1px solid ${colors.tan[300]}`,\n },\n errorContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n width: \"12px\",\n height: \"12px\",\n color: `#F44336`,\n },\n loading: {\n width: \"12px !important\",\n height: \"12px !important\",\n color: `${colors.tan[300]} !important`,\n },\n doneIcon: {\n fill: \"black\",\n width: \"16px\",\n },\n}))\n\nexport interface StatusLog {\n error: boolean\n msg: string\n}\n\nexport interface SubmittingStatusProps {\n statusLog: StatusLog[]\n}\n\nexport const SubmittingStatus: React.FC = ({ statusLog }) => {\n const classes = useStyles()\n\n return (\n \n {statusLog.map((item, index) => (\n \n \n \n {statusLog.length > index + 1 && !item.error && (\n \n \n \n )}\n {statusLog.length === index + 1 && !item.error && (\n \n \n \n )}\n {statusLog.length === index + 1 && item.error && (\n \n \n \n )}\n \n \n \n {item.msg}\n \n \n \n \n ))}\n \n )\n}\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport { Button, Divider, Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { CircleStep } from \"components/CircleStep\"\nimport React, { useEffect, useState } from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\"\nimport AddIcon from \"@material-ui/icons/Add\"\nimport RemoveIcon from \"@material-ui/icons/Remove\"\nimport { SectionProps, SetupData } from \"views/AddModule/wizards/RealityModule\"\nimport { DelayModule, ModuleType } from \"store/modules/models\"\nimport { AttachModuleForm } from \"views/AddModule/wizards/components/AttachModuleForm\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { OracleSectionData } from \"../Oracle\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport { BigNumber } from \"ethers\"\nimport { unitConversion } from \"components/input/TimeSelect\"\nimport { EXPLORERS_CONFIG } from \"utils/explorers\"\nimport { NETWORK } from \"utils/networks\"\nimport { getSnapshotSpaceUrl } from \"services/snapshot\"\nimport { StatusLog, SubmittingStatus } from \"./components/SubmittingStatus\"\n\ninterface ReviewSectionProps extends SectionProps {\n goToStep: (step: number) => void\n delayModules: DelayModule[]\n setupData: SetupData | undefined\n loading: boolean\n statusLog: StatusLog[]\n}\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n paperTemplateContainer: {\n marginTop: 4,\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n icon: {\n fill: \"white\",\n cursor: \"pointer\",\n },\n collapse: {\n textDecoration: \"underline\",\n cursor: \"pointer\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n textarea: {\n \"& .MuiInputBase-root\": {\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n link: {\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n textDecoration: \"underline\",\n fontWeight: \"bold\",\n },\n label: {\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n fontWeight: \"bold\",\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n },\n}))\n\nconst SECTIONS = [\n {\n label: \"Proposal\",\n number: 1,\n section: 0,\n },\n {\n label: \"Oracle\",\n number: 2,\n section: 1,\n },\n {\n label: \"Monitoring\",\n number: 3,\n section: 2,\n },\n]\n\nexport const ReviewSection: React.FC = ({\n handleBack,\n handleNext,\n goToStep,\n delayModules,\n setupData,\n loading,\n statusLog,\n}) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const [snapshotSpace, setSnapshotSpace] = useState()\n const [collapseSection, setCollapseSection] = useState(false)\n const [oracleData, setOracleData] = useState(undefined)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const monitoring = setupData && setupData.monitoring\n\n useEffect(() => {\n if (setupData && setupData.proposal) {\n setSnapshotSpace(getSnapshotSpaceUrl(safe.chainId, setupData.proposal.ensName))\n }\n if (setupData && setupData.oracle) {\n setOracleData(setupData.oracle)\n }\n }, [setupData])\n\n return (\n \n \n {!collapseSection && (\n <>\n \n \n \n Review\n \n \n \n Here is an overview of your reality module configuration. Please\n review carefully. Once you've confirmed that the details are\n correct, you can submit the transaction which will add the reality\n module to this safe, and automatically integrate the SafeSnap plugin\n with the snapshot space you've include.\n \n \n \n \n\n \n \n \n\n {SECTIONS.map((item) => (\n \n \n goToStep(item.section)}\n />\n \n\n {item.label === \"Proposal\" && (\n \n Snapshot Space:\n \n {snapshotSpace}\n \n \n )}\n\n {item.label === \"Oracle\" && oracleData && setupData && (\n \n \n \n Template question preview:\n \n \n {setupData.oracle.templateData.templateQuestion}\n \n \n \n \n Oracle Address:\n \n {oracleData.instanceData.instanceAddress}\n \n \n \n \n \n Timeout:\n \n {BigNumber.from(oracleData.delayData.timeout)\n .div(unitConversion[oracleData.delayData.timeoutUnit])\n .toString()}{\" \"}\n {oracleData.delayData.timeoutUnit}\n \n \n \n Cooldown:\n \n {BigNumber.from(oracleData.delayData.cooldown)\n .div(unitConversion[oracleData.delayData.cooldownUnit])\n .toString()}{\" \"}\n {oracleData.delayData.cooldownUnit}\n \n \n \n Expiration:\n \n {BigNumber.from(oracleData.delayData.expiration)\n .div(unitConversion[oracleData.delayData.expirationUnit])\n .toString()}{\" \"}\n {oracleData.delayData.expirationUnit}\n \n \n \n Bond:\n \n {oracleData.bondData.bond} ETH\n \n \n \n \n \n Arbitrator:\n \n {oracleData.arbitratorData.arbitratorOption === 0 &&\n \"No arbitration (highest bond wins)\"}\n {oracleData.arbitratorData.arbitratorOption === 1 && \"Kleros\"}\n \n \n {/* \n Oracle Address:\n \n https://reality.eth/proposal/343293804ji32khfgahfa\n \n */}\n \n \n )}\n\n {item.label === \"Monitoring\" && monitoring && (\n \n \n \n API key/secret:\n Valid\n \n {monitoring.email.length > 0 && (\n \n Emails:\n {monitoring.email.map((email, index) => (\n \n - {email}\n \n ))}\n \n )}\n {monitoring.discordKey !== \"\" && (\n \n Discord:\n \n {monitoring.discordKey}\n \n \n )}\n {monitoring.telegram.botToken !== \"\" && (\n \n Telegram:\n \n Bot token: {monitoring.telegram.botToken}\n \n \n Chat ID: {monitoring.telegram.chatId}\n \n \n )}\n {monitoring.slackKey !== \"\" && (\n \n Slack:\n \n {monitoring.slackKey}\n \n \n )}\n \n \n )}\n\n \n \n \n \n ))}\n\n {delayModules.length >= 1 && (\n \n \n \n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n \n \n )}\n \n )}\n\n {statusLog.length > 0 && (\n setCollapseSection(!collapseSection)}>\n \n \n {!collapseSection ? (\n \n ) : (\n \n )}\n \n \n {!collapseSection ? \"Show Less\" : \"Show More\"}\n \n \n \n )}\n\n {statusLog.length > 0 && (\n \n \n \n \n Setting up Module\n \n \n \n \n \n \n \n )}\n\n \n \n \n \n Back\n \n \n \n \n ) : (\n \n )\n }\n disabled={loading}\n onClick={() => {\n setCollapseSection(true)\n handleNext(setupData)\n }}\n >\n Submit\n \n \n \n \n \n \n )\n}\n\nconst executionModuleDescription = (\n \n This will add a time delay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed will\n be 48 hours).\n \n)\n\nexport default ReviewSection\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport Creatable from \"react-select/creatable\"\nimport { Props as MultiSelectProps } from \"react-select\"\n\nexport interface MultiSelectValues {\n label: string\n value: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n paperContainer: {\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n}))\n\nconst customStyles = {\n control: (base: any, state: { isFocused: any }) => ({\n ...base,\n background: \"none\",\n border: \"none\",\n fontFamily: \"Roboto Mono !important\",\n color: \"yellow !important\",\n boxShadow: state.isFocused ? null : null,\n \"&:hover\": {\n border: \"none\",\n },\n }),\n option: (base: any) => ({\n ...base,\n color: \"white\",\n backgroundColor: \"#101010\",\n cursor: \"pointer\",\n }),\n menu: (base: any) => ({\n ...base,\n // override border radius to match the box\n borderRadius: 0,\n backgroundColor: \"#101010\",\n // kill the gap\n marginTop: 0,\n }),\n menuList: (base: any) => ({\n ...base,\n // kill the white space on first and last option\n padding: 0,\n }),\n multiValue: (base: any) => ({\n ...base,\n color: \"white !important\",\n background: colors.tan[300],\n maxWidth: \"calc(28% - 4px)\",\n \"&:hover\": {\n background: colors.tan[300],\n },\n \"& > div\": {\n color: `white !important`,\n },\n \"& > div[role=button]:hover\": {\n cursor: \"pointer\",\n color: \"blue\",\n background: colors.tan[500],\n },\n }),\n}\n\ninterface MultiSelectCustomProps extends MultiSelectProps {\n invalidText?: string\n}\n\nexport const MultiSelect: React.FC = (props) => {\n const classes = useStyles()\n return (\n \n \n \n ({\n ...theme,\n colors: {\n ...theme.colors,\n font: \"#101010\",\n primary25: \"#101010\",\n primary: \"#101010\",\n neutral80: \"white\",\n },\n })}\n />\n \n \n {props.invalidText && (\n \n {props.invalidText}\n \n )}\n \n )\n}\n","import { useRef, useEffect } from \"react\"\n\nconst usePrevious = (value: string) => {\n const ref = useRef()\n useEffect(() => {\n ref.current = value\n }, [value])\n return ref.current\n}\nexport default usePrevious\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors } from \"zodiac-ui-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ClearIcon from \"@material-ui/icons/Clear\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: \"0.9rem\",\n },\n messageError: {\n fontSize: \"0.8rem\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n background: colors.tan[1000],\n },\n loadingContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: `1px solid ${colors.tan[300]}`,\n },\n errorContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n width: \"12px\",\n height: \"12px\",\n color: `#F44336`,\n },\n loading: {\n width: \"12px !important\",\n height: \"12px !important\",\n color: `${colors.tan[300]} !important`,\n },\n doneIcon: {\n fill: \"black\",\n width: \"16px\",\n },\n}))\n\nexport interface MonitoringStatus {\n status: \"loading\" | \"success\" | \"error\" | null\n message: string | null\n}\n\nexport const MonitoringStatus: React.FC = ({ status, message }) => {\n const classes = useStyles()\n return (\n status && (\n \n \n {status === \"success\" && (\n \n \n \n )}\n {status === \"loading\" && (\n \n \n \n )}\n {status === \"error\" && (\n \n \n \n )}\n \n \n \n {message}\n \n \n \n )\n )\n}\n","import { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { MultiSelect, MultiSelectValues } from \"components/MultiSelect\"\nimport { Link } from \"components/text/Link\"\nimport usePrevious from \"hooks/usePrevious\"\nimport React, { ChangeEvent, useEffect, useState } from \"react\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { useMonitoringValidation } from \"../../hooks/useMonitoringValidation\"\nimport { MonitoringStatus } from \"./components/MonitoringStatus\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n inputContainer: {\n width: \"50%\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n textarea: {\n \"& .MuiInputBase-root\": {\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `${colors.tan[300]} !important`,\n },\n}))\n\nexport interface MonitoringSectionData {\n apiKey: string\n secretKey: string\n email: string[]\n discordKey: string\n telegram: { botToken: string; chatId: string }\n slackKey: string\n}\n\nconst INITIAL_DATA: MonitoringSectionData = {\n apiKey: \"\",\n secretKey: \"\",\n email: [],\n discordKey: \"\",\n telegram: {\n botToken: \"\",\n chatId: \"\",\n },\n slackKey: \"\",\n}\n\nexport const MonitoringSection: React.FC = ({\n handleBack,\n handleNext,\n setupData,\n}) => {\n const classes = useStyles()\n const {\n loading,\n execute: validateCredentials,\n error: invalidCredentials,\n } = useMonitoringValidation()\n const monitoring = setupData?.monitoring\n const [monitoringData, setMonitoringData] = useState(\n monitoring ?? INITIAL_DATA,\n )\n const [emailValues, setEmailValues] = useState([])\n const [invalidEmail, setInvalidEmail] = useState(false)\n const [loadValidations, setLoadValidations] = useState(false)\n\n const { apiKey, secretKey, email, discordKey, slackKey, telegram } = monitoringData\n const previousApiKey = usePrevious(apiKey)\n const previousSecretKey = usePrevious(secretKey)\n\n useEffect(() => {\n if (monitoring && monitoring.email.length) {\n const emails: MultiSelectValues[] = []\n monitoring.email.forEach((item: string) =>\n emails.push({ label: item, value: item }),\n )\n setEmailValues(emails)\n }\n }, [monitoring])\n\n useEffect(() => {\n if (!loading && ![apiKey, secretKey].includes(\"\") && !loadValidations) {\n setLoadValidations(true)\n const executeValidations = async () => {\n await validateCredentials(apiKey, secretKey)\n }\n executeValidations()\n }\n }, [apiKey, secretKey, loading, loadValidations, validateCredentials])\n\n useEffect(() => {\n if (\n (previousApiKey !== apiKey || previousSecretKey !== secretKey) &&\n loadValidations\n ) {\n setLoadValidations(false)\n }\n }, [apiKey, secretKey, previousApiKey, previousSecretKey, loadValidations])\n\n const updateForm = (\n event: ChangeEvent,\n fieldName: string,\n ) => {\n event.preventDefault()\n if ([\"chatId\", \"botToken\"].includes(fieldName)) {\n const telegram = { ...monitoringData.telegram }\n const newValues = { ...telegram, [fieldName]: event.target.value }\n setMonitoringData({\n ...monitoringData,\n telegram: newValues,\n })\n return\n }\n setMonitoringData({ ...monitoringData, [fieldName]: event.target.value })\n }\n\n const isValidEmail = (email: string) => {\n return /\\S+@\\S+\\.\\S+/.test(email)\n }\n\n const handleNewEmail = (values: MultiSelectValues[]) => {\n const newestEmail = values[values.length - 1]?.value\n\n if (isValidEmail(newestEmail) || newestEmail == null) {\n setInvalidEmail(false)\n setEmailValues(values)\n setMonitoringData({ ...monitoringData, email: values.map((_) => _.value) })\n } else {\n setInvalidEmail(true)\n }\n }\n\n const handleStatusMessage = (): string | null => {\n if (loading) return \"Validating API credentials...\"\n if (invalidCredentials)\n return \"The API credentials that you have provided are not valid. Please verify that you have the correct information.\"\n if (!invalidCredentials && typeof invalidCredentials === \"boolean\")\n return \"API credentials are valid.\"\n return null\n }\n\n const handleStatus = (): \"loading\" | \"error\" | \"success\" | null => {\n if (loading) return \"loading\"\n if (invalidCredentials) return \"error\"\n if (!invalidCredentials && typeof invalidCredentials === \"boolean\") return \"success\"\n return null\n }\n\n const isInvalidForm = (): boolean => {\n const { botToken, chatId } = telegram\n if (loading || invalidCredentials) {\n return true\n }\n if ((botToken === \"\" && chatId !== \"\") || (botToken !== \"\" && chatId === \"\")) {\n return true\n }\n if (\n botToken === \"\" &&\n chatId === \"\" &&\n discordKey === \"\" &&\n slackKey === \"\" &&\n email.length === 0\n ) {\n return true\n }\n return false\n }\n\n return (\n \n \n \n \n \n Configure Monitoring\n \n \n \n Setting up an effective monitoring strategy is critical for the security\n of your safe. In order to set up the monitoring for this module,\n you'll need to first{\" \"}\n \n create an Open Zeppelin account.\n \n \n \n \n \n\n \n \n \n\n \n \n \n \n API Configuration\n \n \n \n \n Include the API Key and Secret Key from your Open Zeppelin account below.\n Follow the Open Zeppelin guide {\"\"}\n \n here.\n \n \n \n \n updateForm(e, \"apiKey\")}\n className={invalidCredentials ? classes.inputError : classes.input}\n />\n \n \n updateForm(e, \"secretKey\")}\n borderStyle=\"double\"\n className={invalidCredentials ? classes.inputError : classes.input}\n />\n \n \n \n \n \n \n\n \n \n \n \n Email\n \n \n \n Add as many emails as you'd like.\n \n \n handleNewEmail(values as MultiSelectValues[])}\n value={emailValues}\n />\n \n \n \n\n \n \n \n \n Discord\n \n \n \n \n To add a Discord integration, include the Discord channel's url\n including key below. Find out more{\" \"}\n \n here.\n \n \n \n \n updateForm(e, \"discordKey\")}\n />\n \n \n \n\n \n \n \n \n Telegram\n \n \n \n \n To add a Telegram integration, include the telegram bot token and chat ID\n below. Find out more{\" \"}\n \n here.\n \n \n \n \n \n \n updateForm(e, \"botToken\")}\n />\n \n \n updateForm(e, \"chatId\")}\n />\n \n \n \n \n \n\n \n \n \n \n Slack\n \n \n \n \n To add a Slack integration, include the Slack channel's url including\n key below. Find out more{\" \"}\n \n here.\n \n \n \n \n updateForm(e, \"slackKey\")}\n />\n \n \n \n\n \n \n \n\n \n \n \n handleBack(monitoringData)}\n >\n Back\n \n \n \n handleNext(monitoringData)}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default MonitoringSection\n","import React, { useEffect, useState } from \"react\"\nimport { useRootDispatch, useRootSelector } from \"store\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setRealityModuleScreen,\n} from \"../../../../store/modules\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport {\n Button,\n Divider,\n Grid,\n makeStyles,\n Step,\n StepContent,\n StepLabel,\n Stepper,\n Typography,\n} from \"@material-ui/core\"\nimport { TagList } from \"components/list/TagList\"\nimport { Link } from \"components/text/Link\"\nimport OracleSection, { OracleSectionData } from \"./sections/Oracle\"\nimport ProposalSection, { ProposalSectionData } from \"./sections/Proposal\"\nimport ReviewSection from \"./sections/Review\"\nimport classnames from \"classnames\"\nimport MonitoringSection, { MonitoringSectionData } from \"./sections/Monitoring\"\nimport { setup } from \"./service/setupService\"\nimport { getDelayModules, getModulesList } from \"store/modules/selectors\"\nimport { StatusLog } from \"./sections/Review/components/SubmittingStatus\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nexport interface SectionProps {\n handleNext: (\n stepData: ProposalSectionData | OracleSectionData | MonitoringSectionData | any,\n ) => void\n handleBack: (\n stepData: ProposalSectionData | OracleSectionData | MonitoringSectionData | any,\n ) => void\n setupData: SetupData | undefined\n}\n\nexport type SetupData = {\n proposal: ProposalSectionData\n oracle: OracleSectionData\n monitoring: MonitoringSectionData\n review: any\n}\n\nconst REALITY_MODULE_STEPS: (keyof SetupData)[] = [\n \"proposal\",\n \"oracle\",\n \"monitoring\",\n \"review\",\n]\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n tag: {\n background: theme.palette.secondary.main,\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n paperTitle: {\n margin: 0,\n },\n step: {\n \"& text\": {\n fontFamily: \"Roboto Mono\",\n },\n \"& .step-label\": {\n textTransform: \"capitalize\",\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n \"&.clickable\": {\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n },\n },\n stepperRoot: {\n backgroundColor: \"transparent\",\n border: \"none\",\n padding: theme.spacing(0),\n \"& .MuiStepIcon-active\": {\n color: theme.palette.secondary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n \"& .MuiStepIcon-completed\": {\n background: theme.palette.text.primary,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n color: theme.palette.secondary.main,\n },\n \"& .Mui-disabled .MuiStepIcon-root\": {\n color: theme.palette.primary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n },\n}))\n\nexport const RealityModule: React.FC = () => {\n const classes = useStyles()\n const { sdk: safeSdk, safe: safeInfo, provider } = useSafeAppsSDKWithProvider()\n const delayModules = useRootSelector(getDelayModules)\n const dispatch = useRootDispatch()\n const modulesList = useRootSelector(getModulesList)\n const [modules, setModules] = useState(modulesList.length)\n const [statusLog, setStatusLog] = useState([])\n const [activeStep, setActiveStep] = useState(0)\n const [completed, setCompleted] = useState({\n proposal: false,\n oracle: false,\n monitoring: false,\n review: false,\n })\n const [loading, setLoading] = useState(false)\n // we can keep the user input data here. No need to send it anywhere else (no need for Redux here, this is self contained).\n const [setupData, setSetupData] = useState()\n\n const handleOpenSection = (pageToOpen: number, step: keyof SetupData) => {\n if (completed[step]) {\n setActiveStep(pageToOpen)\n }\n }\n\n const navigate = (nextPage: number, step: keyof SetupData, stepCompleted: boolean) => {\n return (stepData: any) => {\n setActiveStep(nextPage)\n setCompleted({ ...completed, [step]: stepCompleted })\n setSetupData({ ...setupData, [step]: stepData } as SetupData)\n }\n }\n\n const handleDone = async (delayModuleExecutor?: string) => {\n const logger: StatusLog[] = []\n setLoading(true)\n if (setupData == null) {\n setLoading(false)\n throw new Error(\"No setup data\")\n }\n const executorAddress =\n delayModuleExecutor !== \"\" || delayModuleExecutor == null\n ? safeInfo.safeAddress\n : delayModuleExecutor\n\n const statusLogger = (currentStatus: string, error?: Error) => {\n if (error != null) {\n if (error.name === \"OpenError\") {\n logger.push({\n error: true,\n msg:\n error.toString() +\n `This error can be caused by add/track blockers. Please disable any blockers (for instance, the Brave Shield) and try again.`,\n })\n } else {\n logger.push({ error: true, msg: error.toString() })\n }\n throw error\n } else {\n logger.push({ error: false, msg: currentStatus })\n }\n setStatusLog(logger)\n }\n\n try {\n await setup(provider, safeSdk, safeInfo, executorAddress, setupData, statusLogger)\n } catch (error) {\n setLoading(false)\n console.error(error)\n }\n dispatch(fetchPendingModules(safeInfo))\n dispatch(setModuleAdded(true))\n }\n\n useEffect(() => {\n if (loading && modulesList.length > modules) {\n setModules(modulesList.length)\n setLoading(false)\n dispatch(setRealityModuleScreen(false))\n }\n }, [dispatch, loading, modules, modulesList])\n\n return (\n
\n \n \n \n \n \n \n \n Reality Module\n \n \n \n \n \n \n Allows Reality.eth questions to execute a transaction when resolved.{\" \"}\n \n Read more here.\n \n \n \n \n \n \n \n \n \n \n \n Add Reality Module\n \n \n \n dispatch(setRealityModuleScreen(false))}\n >\n Cancel\n \n \n \n \n {REALITY_MODULE_STEPS.map((label, index) => (\n \n handleOpenSection(index, label as keyof SetupData)}\n >\n \n {label}\n {\" \"}\n \n \n {label === \"proposal\" && (\n dispatch(setRealityModuleScreen(false))}\n setupData={setupData}\n />\n )}\n {label === \"oracle\" && (\n \n )}\n {label === \"monitoring\" && (\n \n )}\n {label === \"review\" && (\n \n )}\n \n \n ))}\n \n \n \n \n
\n )\n}\n\nexport default RealityModule\n","import { ethers } from \"ethers\"\n\nconst VOTES_ABI = [\n \"function getVotes(address account) external view returns (uint256)\",\n \"function getPastVotes(address account, uint256 blockNumber) external view returns (uint256)\",\n \"function getPastTotalSupply(uint256 blockNumber) external view returns (uint256)\",\n \"function delegates(address account) external view returns (address)\",\n \"function delegate(address delegatee) external\",\n \"function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external\",\n]\n\nconst RANDOM_VALID_ADDRESS = \"0xD028d504316FEc029CFa36bdc3A8f053F6E5a6e4\"\nconst RANDOM_BLOCK_NUMBER = 1234\n\nexport const isVotesCompilable =\n (provider: ethers.providers.JsonRpcProvider) => async (tokenAddress: string) => {\n const tokenContract = new ethers.Contract(tokenAddress, VOTES_ABI, provider)\n\n try {\n await Promise.all([\n tokenContract.getVotes(RANDOM_VALID_ADDRESS),\n tokenContract.getPastVotes(RANDOM_VALID_ADDRESS, RANDOM_BLOCK_NUMBER),\n tokenContract.getPastTotalSupply(RANDOM_BLOCK_NUMBER),\n tokenContract.callStatic.delegates(RANDOM_VALID_ADDRESS),\n ])\n // eslint-disable-next-line\n tokenContract.functions[\"delegateBySig\"].name\n } catch (e) {\n console.log(e)\n return false\n }\n\n return true\n }\n","import React, { ChangeEvent, Fragment, useEffect, useState } from \"react\"\nimport {\n Button,\n Divider,\n FormControlLabel,\n FormHelperText,\n Grid,\n makeStyles,\n Radio,\n RadioGroup,\n Typography,\n} from \"@material-ui/core\"\n\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { ethers } from \"ethers\"\nimport { GovernorWizardProps } from \"../..\"\nimport { isVotesCompilable } from \"../../service/tokenValidation\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n radio: {\n marginLeft: -2,\n padding: 2,\n \"& ~ .MuiFormControlLabel-label\": {\n fontSize: 12,\n marginLeft: 4,\n },\n \"&$checked\": {\n color: colors.tan[1000],\n },\n },\n checked: {},\n errorColor: {\n color: \"rgba(244, 67, 54, 1)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n}))\n\nexport type TokenFields =\n | \"tokenAddress\"\n | \"tokenName\"\n | \"tokenSymbol\"\n | \"initialAmount\"\n | \"tokenConfiguration\"\n\nexport type TokenConfigurationType = \"existingToken\" | \"ERC20\" | \"ERC721\"\n\nexport type TokenSectionData = {\n tokenAddress: string | undefined\n tokenName: string\n tokenSymbol: string\n initialAmount: number\n tokenConfiguration: TokenConfigurationType\n}\n\nexport const TOKEN_INITIAL_VALUES: TokenSectionData = {\n tokenAddress: undefined,\n tokenName: \"\",\n tokenSymbol: \"\",\n initialAmount: 100000,\n tokenConfiguration: \"existingToken\",\n}\n\nexport const TokenSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const classes = useStyles()\n const token = setupData.token\n const [tokenData, setTokenData] = useState(token)\n const [isValidTokenAddress, setIsValidTokenAddress] = useState(false)\n\n const { provider } = useSafeAppsSDKWithProvider()\n const tokenAddressValidator = isVotesCompilable(provider)\n const { tokenAddress, tokenName, tokenSymbol, tokenConfiguration, initialAmount } =\n tokenData\n\n const collectSectionData = (): TokenSectionData => ({\n tokenAddress,\n tokenName,\n tokenSymbol,\n tokenConfiguration,\n initialAmount,\n })\n\n const handleInputClasses = () => {\n if ([tokenAddress].includes(\"\")) {\n return classes.input\n }\n if (![tokenAddress].includes(\"\" || undefined) && !isValidTokenAddress) {\n return classes.inputError\n }\n return classes.input\n }\n\n const handleChange = (event: React.ChangeEvent) => {\n setTokenData({\n ...tokenData,\n tokenConfiguration: (event.target as HTMLInputElement)\n .value as TokenConfigurationType,\n })\n }\n\n const updateFields = (\n event: ChangeEvent,\n fieldName: TokenFields,\n ) => {\n setTokenData({ ...tokenData, [fieldName]: event.target.value })\n }\n\n useEffect(() => {\n if (![tokenAddress].includes(\"\" || undefined)) {\n const validations = async () => {\n if (\n ethers.utils.isAddress(tokenAddress as string) &&\n (await tokenAddressValidator(tokenAddress as string))\n ) {\n setIsValidTokenAddress(true)\n } else {\n setIsValidTokenAddress(false)\n }\n }\n validations()\n }\n }, [tokenAddress, tokenAddressValidator])\n\n const handleValidation = (): boolean => {\n if (tokenConfiguration === \"existingToken\") {\n return !isValidTokenAddress || [tokenAddress].includes(\"\") ? true : false\n }\n if (tokenConfiguration === \"ERC721\" || tokenConfiguration === \"ERC20\") {\n return [tokenName, tokenSymbol].includes(\"\") ? true : false\n }\n return true\n }\n\n const isValid = handleValidation()\n return (\n \n \n \n \n \n Setup Token for Voting\n \n \n \n The following token will enable members to vote on proposals with this\n governor contract. The token must be ERC20Votes compatible.\n \n \n \n \n \n \n Token Configuration\n \n \n \n \n Do you have an existing token in your safe that you'd like to use as the\n token for voting in this contract?\n \n \n \n }\n label=\"Existing Token\"\n />\n \n }\n label=\"Deploy a new ERC20 for voting.\"\n />\n \n }\n label=\"Deploy a new ERC721 for voting.\"\n />\n \n \n\n {tokenConfiguration === \"existingToken\" && (\n \n updateFields(e, \"tokenAddress\")}\n />\n {![tokenAddress].includes(\"\" || undefined) && !isValidTokenAddress && (\n \n Please provide a valid address\n \n )}\n \n )}\n\n {(tokenConfiguration === \"ERC20\" || tokenConfiguration === \"ERC721\") && (\n \n \n \n \n updateFields(e, \"tokenName\")}\n tooltipMsg=\"The same as collection name in OpenSea, e.g. Nouns\"\n />\n \n \n updateFields(e, \"tokenSymbol\")}\n tooltipMsg=\"e.g. LOOT\"\n />\n \n \n \n {/* {tokenConfiguration === \"ERC20\" && (\n \n updateFields(e, \"initialAmount\")}\n tooltipMsg=\"The number of tokens you want to mint when the contract is deployed. These will be sent straight to the safe.\"\n />\n \n )} */}\n \n )}\n\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Cancel\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default TokenSection\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport { Button, Divider, Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { CircleStep } from \"components/CircleStep\"\nimport React from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport { GovernorWizardProps, SetupData } from \"../..\"\nimport { EXPLORERS_CONFIG } from \"utils/explorers\"\nimport { NETWORK } from \"utils/networks\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\n\ninterface OZReviewSectionProps extends GovernorWizardProps {\n goToStep: (step: number) => void\n setupData: SetupData\n loading: boolean\n}\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n icon: {\n fill: \"white\",\n cursor: \"pointer\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n label: {\n fontFamily: \"Roboto Mono, monospace\",\n fontSize: 12,\n fontWeight: \"bold\",\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n },\n value: {\n fontFamily: \"Roboto Mono, monospace\",\n fontWeight: \"bold\",\n color: \"white\",\n },\n underline: {\n textDecoration: \"underline\",\n },\n}))\n\nconst SECTIONS = [\n {\n label: \"Token\",\n number: 1,\n section: 0,\n },\n {\n label: \"Governor\",\n number: 2,\n section: 1,\n },\n]\n\nexport const OZReviewSection: React.FC = ({\n handleBack,\n handleNext,\n goToStep,\n setupData,\n loading,\n}) => {\n const classes = useStyles()\n const token = setupData?.token\n const governor = setupData?.governor\n const { safe } = useSafeAppsSDK()\n\n return (\n \n \n \n \n \n Review\n \n \n \n Please take a final look at your OZ Governor Module details.\n \n \n \n \n\n \n \n \n\n {SECTIONS.map((item) => (\n \n \n goToStep(item.section)}\n />\n \n\n {item.label === \"Token\" && token && (\n <>\n {token.tokenAddress && (\n \n Voting Token:\n \n {token.tokenAddress}\n \n \n )}\n {token.tokenName && (\n \n Token Name:\n {token.tokenName}\n \n )}\n {token.tokenSymbol && (\n \n Token Symbol:\n {token.tokenSymbol}\n \n )}\n {/* {token.tokenConfiguration === \"ERC20\" && token.initialAmount && (\n \n Initial Amount:\n \n {token.initialAmount}\n \n \n )} */}\n \n )}\n {item.label === \"Governor\" && governor && (\n <>\n \n Name:\n {governor.daoName}\n \n \n Voting Delay:\n \n {governor.votingDelayInBlocks} blocks\n \n \n \n Voting Period:\n \n {governor.votingPeriodInBlocks} blocks\n \n \n \n Proposal Threshold:\n \n {governor.proposalThreshold}%\n \n \n \n Quorum (%):\n \n {governor.quorumPercent}%\n \n \n \n )}\n\n \n \n \n \n ))}\n\n \n \n \n \n Back\n \n \n \n \n ) : (\n \n )\n }\n onClick={() => {\n handleNext(setupData)\n }}\n >\n Deploy and Enable Module\n \n \n \n \n \n \n )\n}\n\nexport default OZReviewSection\n","import { deployAndSetUpModule, KnownContracts } from \"@gnosis.pm/zodiac\"\nimport { ethers } from \"ethers\"\nimport { enableModule, TxWitMeta } from \"services\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\n\nconst MULTI_SEND_CONTRACT = process.env.REACT_APP_MULTI_SEND_CONTRACT\nif (MULTI_SEND_CONTRACT == null) {\n throw new Error(\"The MULTI_SEND_CONTRACT environment variable is not set.\")\n}\n\nexport type CreateTokenArgs = {\n name: string\n symbol: string\n kind: \"ERC20\" | \"ERC721\"\n}\n\nconst deployOzGovernorModule = async (\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n tokenAddress: string,\n name: string,\n votingDelayInBlocks: number,\n votingPeriodInBlocks: number,\n proposalThreshold: number,\n quorumPercent: number,\n): Promise => {\n // input validation\n if (safeAddress == null) {\n throw new Error(\"No safe address provided\")\n }\n if (tokenAddress == null) {\n throw new Error(\"No token address provided\")\n }\n if (name == null) {\n throw new Error(\"No name provided\")\n }\n if (votingDelayInBlocks == null) {\n throw new Error(\"No voting delay provided\")\n }\n if (votingPeriodInBlocks == null) {\n throw new Error(\"No voting period provided\")\n }\n if (proposalThreshold == null) {\n throw new Error(\"No proposal threshold provided\")\n }\n if (quorumPercent == null) {\n throw new Error(\"No quorum percent provided\")\n }\n if (quorumPercent > 100 || quorumPercent < 0) {\n throw new Error(\"Quorum percent must be between 0 and 100\")\n }\n\n const initData = {\n values: [\n safeAddress, // owner\n safeAddress, // target\n MULTI_SEND_CONTRACT, // multisend\n tokenAddress, // token\n name, // name\n votingDelayInBlocks.toString(), // votingDelay\n votingPeriodInBlocks.toString(), // votingPeriod\n proposalThreshold.toString(), // proposalThreshold\n quorumPercent.toString(), // quorum\n \"0\", // initialVoteExtension\n ],\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"string\",\n \"uint256\",\n \"uint256\",\n \"uint256\",\n \"uint256\",\n \"uint64\",\n ],\n }\n\n const saltNonce = Date.now().toString()\n const chainId = (await provider.getNetwork()).chainId\n\n const { transaction: deploymentTx, expectedModuleAddress: expectedAddress } =\n deployAndSetUpModule(\n KnownContracts.OZ_GOVERNOR,\n initData,\n provider,\n chainId,\n saltNonce,\n )\n\n return {\n txs: [\n {\n ...deploymentTx,\n value: deploymentTx.value.toString(),\n },\n ], // transactions to be executed by the safe\n meta: { expectedAddress }, // any additional data needed from the setup process\n }\n}\n\nexport const deployVotesTokenTx = async (\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n tokenName: string,\n tokenSymbol: string,\n kind: \"ERC20\" | \"ERC721\",\n): Promise => {\n if (safeAddress == null) {\n throw new Error(\"No safe address provided\")\n }\n if (tokenName == null) {\n throw new Error(\"No token name provided\")\n }\n if (tokenSymbol == null) {\n throw new Error(\"No token symbol provided\")\n }\n if (kind !== \"ERC20\" && kind !== \"ERC721\") {\n throw new Error(\"Invalid token kind\")\n }\n\n const initData = {\n values: [\n safeAddress, // owner\n tokenName, // name\n tokenSymbol, // symbol\n ],\n types: [\"address\", \"string\", \"string\"],\n }\n\n const saltNonce = Date.now().toString()\n const chainId = (await provider.getNetwork()).chainId\n\n const { transaction: deploymentTx, expectedModuleAddress: expectedAddress } =\n deployAndSetUpModule(\n kind === \"ERC20\" ? KnownContracts.ERC20_VOTES : KnownContracts.ERC721_VOTES,\n initData,\n provider,\n chainId,\n saltNonce,\n )\n\n return {\n txs: [\n {\n ...deploymentTx,\n value: deploymentTx.value.toString(),\n },\n ], // transactions to be executed by the safe\n meta: { expectedAddress }, // any additional data needed from the setup process\n }\n}\n\nexport const deployAndEnableOzGovernorModule = async (\n provider: ethers.providers.JsonRpcProvider,\n safeSdk: SafeAppsSDK,\n safeAddress: string,\n name: string,\n votingDelayInBlocks: number,\n votingPeriodInBlocks: number,\n proposalThreshold: number,\n quorumPercent: number,\n tokenAddress?: string,\n createTokenArgs?: CreateTokenArgs,\n) => {\n if (tokenAddress == null && createTokenArgs == null) {\n throw new Error(\"No token address or create token args provided\")\n } else if (tokenAddress != null && createTokenArgs != null) {\n throw new Error(\"Both token address and create token args provided\")\n }\n const txs = []\n if (createTokenArgs != null) {\n const { txs: deployTokenTxs, meta } = await deployVotesTokenTx(\n provider,\n safeAddress,\n createTokenArgs.name,\n createTokenArgs.symbol,\n createTokenArgs.kind,\n )\n txs.push(...deployTokenTxs)\n\n if (meta?.expectedAddress == null) {\n throw new Error(\"No expected address returned from token deployment\")\n }\n tokenAddress = meta.expectedAddress\n }\n\n if (tokenAddress == null) {\n throw new Error(\n \"No token address provided. Should not be possible. Either the token address should be provided or a new token should be deployed.\",\n )\n }\n\n const { txs: deployOzGovernorTxs, meta } = await deployOzGovernorModule(\n provider,\n safeAddress,\n tokenAddress,\n name,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n )\n txs.push(...deployOzGovernorTxs)\n if (meta?.expectedAddress == null) {\n throw new Error(\"The expected value is missing\")\n }\n const enableModuleTx = enableModule(safeAddress, meta.expectedAddress)\n txs.push(enableModuleTx)\n\n return safeSdk.txs.send({ txs: txs }).catch((e) => {\n console.error(e)\n throw new Error(\"Error when proposing transactions to the Safe\")\n })\n}\n","var _circle, _circle2, _circle3, _circle4, _circle5, _circle6;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgGripIcon = function SvgGripIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 9,\n height: 16,\n viewBox: \"0 0 9 16\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 2,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 14,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 8,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle4 || (_circle4 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 2,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle5 || (_circle5 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 14,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle6 || (_circle6 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 8,\n r: 1.5,\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgGripIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/grip-icon.27ae46ee.svg\";\nexport { ForwardRef as ReactComponent };","import React, { ChangeEvent, useState } from \"react\"\nimport { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\n\nimport { colors, ZodiacPaper, ZodiacSlider, ZodiacTextField } from \"zodiac-ui-components\"\nimport { GovernorWizardProps } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n}))\n\nexport type GovernorSectionData = {\n daoName: string\n votingDelayInBlocks: number\n votingPeriodInBlocks: number\n proposalThreshold: number\n quorumPercent: number\n}\n\ntype GovernorFields =\n | \"daoName\"\n | \"votingDelay\"\n | \"votingPeriod\"\n | \"proposalThreshold\"\n | \"quorumPercent\"\n\nexport const GOVERNOR_INITIAL_VALUES: GovernorSectionData = {\n daoName: \"\",\n votingDelayInBlocks: 0,\n votingPeriodInBlocks: 50400,\n proposalThreshold: 0,\n quorumPercent: 4,\n}\n\nexport const GovernorSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const classes = useStyles()\n const governor = setupData.governor\n const [governorData, setGovernorData] = useState(governor)\n\n const updateFields = (\n event: ChangeEvent,\n fieldName: GovernorFields,\n ) => {\n setGovernorData({ ...governorData, [fieldName]: event.target.value })\n }\n\n const collectSectionData = (): GovernorSectionData => governorData\n const {\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n } = governorData\n\n const nextValidations = (): boolean => {\n if (![daoName].includes(\"\") && quorumPercent >= 0 && quorumPercent <= 100) {\n return false\n }\n return true\n }\n return (\n \n \n \n \n \n Setup OZ Governor Contract\n \n \n \n Configure your governor contract. It can always be changed later, so\n don't worry too much about getting it perfect the first time.\n \n \n \n \n \n updateFields(e, \"daoName\")}\n />\n \n\n \n \n \n \n Voting Delay Configurations\n \n \n \n \n Configure a delay modifier to determine the duration required before\n voting (Cooldown), and the amount of time that the proposal will be valid\n (Expiration).\n \n \n \n \n \n \n \n {\n setGovernorData({\n ...governorData,\n votingDelayInBlocks: parseInt(event.target.value),\n })\n }}\n tooltipMsg=\"The time between proposal submission and when voting starts.\"\n />\n \n \n {\n setGovernorData({\n ...governorData,\n votingPeriodInBlocks: parseInt(event.target.value),\n })\n }}\n tooltipMsg=\"The number of blocks between when a proposal's voting period starts and ends.\"\n />\n \n \n \n \n \n \n \n Voting Thresholds\n \n \n \n \n \n updateFields(e, \"proposalThreshold\")}\n />\n \n \n {\n if (typeof value === \"number\" && quorumPercent !== value && value >= 0) {\n setGovernorData({\n ...governorData,\n quorumPercent: value,\n })\n }\n }}\n />\n \n\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Back\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default GovernorSection\n","import React, { useState } from \"react\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport {\n Button,\n Divider,\n Grid,\n makeStyles,\n Step,\n StepContent,\n StepLabel,\n Stepper,\n Typography,\n} from \"@material-ui/core\"\nimport { Link } from \"components/text/Link\"\nimport classnames from \"classnames\"\nimport { useRootDispatch } from \"store\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setOzGovernorModuleScreen,\n} from \"store/modules\"\nimport TokenSection, {\n TokenSectionData,\n TOKEN_INITIAL_VALUES,\n} from \"../OzGovernor/sections/Token\"\nimport OZReviewSection from \"./sections/Review\"\nimport {\n CreateTokenArgs,\n deployAndEnableOzGovernorModule,\n} from \"./service/moduleDeployment\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport GovernorSection, {\n GovernorSectionData,\n GOVERNOR_INITIAL_VALUES,\n} from \"./sections/Governor\"\n\nexport interface GovernorWizardProps {\n handleNext: (stepData: TokenSectionData | GovernorSectionData | any) => void\n handleBack: (stepData: TokenSectionData | GovernorSectionData | any) => void\n setupData: SetupData\n}\n\nexport type SetupData = {\n token: TokenSectionData\n governor: GovernorSectionData\n review: any\n}\n\nexport const OZ_GOVERNOR_MODULE_STEPS: (keyof SetupData)[] = [\n \"token\",\n \"governor\",\n \"review\",\n]\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n paperTitle: {\n margin: 0,\n },\n step: {\n \"& text\": {\n fontFamily: \"Roboto Mono\",\n },\n \"& .step-label\": {\n textTransform: \"capitalize\",\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n \"&.clickable\": {\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n },\n },\n stepperRoot: {\n backgroundColor: \"transparent\",\n border: \"none\",\n padding: theme.spacing(0),\n \"& .MuiStepIcon-active\": {\n color: theme.palette.secondary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n \"& .MuiStepIcon-completed\": {\n background: theme.palette.text.primary,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n color: theme.palette.secondary.main,\n },\n \"& .Mui-disabled .MuiStepIcon-root\": {\n color: theme.palette.primary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n },\n}))\n\nexport const OzGovernorModule: React.FC = () => {\n const classes = useStyles()\n const { sdk: safeSdk, safe: safeInfo, provider } = useSafeAppsSDKWithProvider()\n const dispatch = useRootDispatch()\n const [activeStep, setActiveStep] = useState(0)\n const [loading, setLoading] = useState(false)\n const [completed, setCompleted] = useState({\n token: false,\n governor: false,\n review: false,\n })\n // we can keep the user input data here. No need to send it anywhere else (no need for Redux here, this is self contained).\n const [setupData, setSetupData] = useState({\n token: TOKEN_INITIAL_VALUES,\n governor: GOVERNOR_INITIAL_VALUES,\n review: {},\n })\n\n const handleOpenSection = (pageToOpen: number, step: keyof SetupData) => {\n if (completed[step]) {\n setActiveStep(pageToOpen)\n }\n }\n\n const navigate = (nextPage: number, step: keyof SetupData, stepCompleted: boolean) => {\n return (stepData: any) => {\n setActiveStep(nextPage)\n setCompleted({ ...completed, [step]: stepCompleted })\n setSetupData({ ...setupData, [step]: stepData } as SetupData)\n }\n }\n\n const handleDone = async () => {\n setLoading(true)\n if (setupData == null) {\n setLoading(false)\n throw new Error(\"No setup data\")\n }\n const { tokenAddress, tokenSymbol, tokenConfiguration, tokenName } = setupData.token\n const {\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n } = setupData.governor\n try {\n let createTokenArgs: CreateTokenArgs | undefined = undefined\n\n if (tokenConfiguration === \"ERC20\" || tokenConfiguration === \"ERC721\") {\n createTokenArgs = {\n name: tokenName,\n symbol: tokenSymbol,\n kind: tokenConfiguration as \"ERC20\" | \"ERC721\",\n }\n }\n\n const setup = await deployAndEnableOzGovernorModule(\n provider,\n safeSdk,\n safeInfo.safeAddress,\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n tokenAddress,\n createTokenArgs,\n )\n if (setup.safeTxHash) {\n dispatch(fetchPendingModules(safeInfo))\n dispatch(setModuleAdded(true))\n }\n } catch (error) {\n setLoading(false)\n console.error(error)\n }\n }\n\n return (\n
\n \n \n \n \n \n \n \n Governor Module\n \n \n \n \n \n Enables an Open Zeppelin Governor contract as a module.{\" \"}\n \n Read more here.\n \n \n \n \n \n \n \n \n \n \n \n Add Governor Module\n \n \n \n dispatch(setOzGovernorModuleScreen(false))}\n >\n Cancel\n \n \n \n \n {OZ_GOVERNOR_MODULE_STEPS.map((label, index) => (\n \n handleOpenSection(index, label as keyof SetupData)}\n >\n \n {label}\n {\" \"}\n \n \n {label === \"token\" && (\n dispatch(setOzGovernorModuleScreen(false))}\n setupData={setupData}\n />\n )}\n {label === \"governor\" && (\n \n )}\n {label === \"review\" && (\n \n )}\n \n \n ))}\n \n \n \n \n
\n )\n}\n","import ModuleDetails from \"./views/ModuleDetails\"\nimport React from \"react\"\nimport { useRootSelector } from \"./store\"\nimport { getCurrentModule, getCurrentPendingModule } from \"./store/modules/selectors\"\nimport AddModules from \"./views/AddModule\"\nimport { ModulePendingTransaction } from \"./views/ModuleDetails/ModulePendingTransaction\"\nimport RealityModule from \"views/AddModule/wizards/RealityModule\"\nimport { OzGovernorModule } from \"views/AddModule/wizards/OzGovernor\"\n\n\nexport const Views: React.FC = () => {\n const currentModule = useRootSelector(getCurrentModule)\n const currentPendingModule = useRootSelector(getCurrentPendingModule)\n const loadingModules = useRootSelector((state) => state.modules.loadingModules)\n const showRealityModule = useRootSelector((state) => state.modules.realityModuleScreen)\n const showOzGovernorModule = useRootSelector((state) => state.modules.OzGovernorModuleScreen)\n\n if (currentModule) {\n return \n }\n\n if (currentPendingModule) {\n return \n }\n\n if (showRealityModule) {\n return \n }\n\n if (showOzGovernorModule) {\n return \n }\n\n if (!loadingModules) {\n return \n }\n\n return null\n}\n","import React from \"react\"\nimport { Row } from \"../../components/layout/Row\"\nimport { Badge, makeStyles, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, colors, doubleBorder, ZodiacPaper } from \"zodiac-ui-components\"\nimport classNames from \"classnames\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getTransactions } from \"../../store/transactionBuilder/selectors\"\nimport { openTransactionBuilder } from \"../../store/transactionBuilder\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n marginBottom: theme.spacing(2),\n },\n container: {\n \"&.MuiPaper-root\": {\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n header: {\n \"&.MuiPaper-root\": {\n padding: theme.spacing(0.5, 2, 0.5, 0.5),\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n txBuilder: {\n \"&.MuiPaper-root\": {\n padding: theme.spacing(0.5, 0.5, 0.5, 2),\n cursor: \"pointer\",\n transition: \"0.2s ease all\",\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n },\n img: {\n display: \"block\",\n width: 36,\n height: 36,\n },\n title: {\n marginLeft: theme.spacing(1),\n },\n bagIcon: {\n marginLeft: theme.spacing(2),\n stroke: \"white\",\n },\n badge: {\n color: theme.palette.common.white,\n display: \"flex\",\n position: \"relative\",\n transform: \"none\",\n textAlign: \"center\",\n background: \"none\",\n fontSize: 16,\n },\n badgeRoot: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n height: 36,\n width: 36,\n borderRadius: 60,\n border: `1px solid ${colors.tan[300]}`,\n padding: theme.spacing(0.5),\n },\n txBuilderTitle: {\n marginRight: theme.spacing(3),\n },\n circleIconContainer: {\n padding: theme.spacing(0.5),\n },\n banner: {\n \"&.MuiPaper-root\": {\n flexGrow: 1,\n position: \"relative\",\n borderWidth: 1,\n borderColor: colors.tan[300],\n backgroundColor: colors.tan[100],\n margin: theme.spacing(0, 2),\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n}))\n\nexport const Header = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const transaction = useRootSelector(getTransactions)\n\n const handleOpen = () => dispatch(openTransactionBuilder())\n\n return (\n \n \n \n \n Zodiac\n \n \n \n \n Bundle Transactions\n \n \n \n \n \n )\n}\n\nexport default Header\n","import React from \"react\";\nimport { Box, makeStyles } from \"@material-ui/core\";\nimport { Icon } from \"@gnosis.pm/safe-react-components\";\nimport { ActionButton } from \"../../../components/ActionButton\";\n\nexport interface TransactionBlockHeaderButtonsProps {\n edit?: boolean;\n disabled?: boolean;\n onEdit?(): void;\n onDelete?(): void;\n onSave?(): void;\n onCancel?(): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n color: theme.palette.primary.main,\n width: 20,\n height: 20,\n },\n iconContainer: {\n height: 54,\n cursor: \"pointer\",\n padding: theme.spacing(2, 0.5),\n marginRight: theme.spacing(1),\n },\n button: {\n marginRight: theme.spacing(1.5),\n color: theme.palette.text.secondary,\n },\n label: {\n color: theme.palette.text.primary,\n },\n}));\n\nexport const TransactionBlockHeaderButtons = ({\n edit = false,\n disabled = false,\n onCancel,\n onEdit,\n onSave,\n onDelete,\n}: TransactionBlockHeaderButtonsProps) => {\n const classes = useStyles();\n\n if (edit) {\n return (\n <>\n \n Save Changes\n \n \n Cancel\n \n \n );\n }\n\n return (\n <>\n \n \n \n \n \n \n \n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\n\ninterface DisplayFieldProps {\n label: string;\n value?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n borderRadius: 8,\n },\n label: {\n marginBottom: theme.spacing(0.5),\n },\n field: {\n padding: theme.spacing(1, 0, 1, 1),\n },\n}));\n\nexport const DisplayField = ({ label, value }: DisplayFieldProps) => {\n const classes = useStyles();\n return (\n
\n \n {label}\n \n \n {value}\n \n
\n );\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { Grid } from \"@material-ui/core\";\nimport {\n ParamInput,\n ParamInputProps,\n} from \"../../../components/ethereum/ParamInput\";\nimport { DisplayField } from \"../../../components/input/DisplayField\";\nimport { formatDisplayParamValue } from \"../../../utils/contracts\";\n\nexport type TransactionBlockFieldsProps = Edit extends false\n ? {\n edit: Edit;\n func: FunctionFragment;\n params: any[];\n }\n : {\n edit: Edit;\n paramInputProps: ParamInputProps[];\n };\n\nexport const TransactionBlockFields = (props: TransactionBlockFieldsProps) => {\n const fields = props.edit\n ? props.paramInputProps.map((props, index) => (\n \n \n \n ))\n : props.func.inputs.map((param, index) => (\n \n \n \n ));\n\n return (\n \n {fields}\n \n );\n};\n","import React from \"react\";\nimport { Chip, ChipProps, makeStyles } from \"@material-ui/core\";\nimport { HashInfo } from \"./HashInfo\";\nimport { shortAddress } from \"../../utils/string\";\n\ninterface AddressChipProps extends ChipProps {\n address: string;\n name?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n name: {\n marginRight: theme.spacing(1),\n },\n avatar: {\n \"& img\": {\n width: 20,\n height: 20,\n },\n },\n}));\n\nexport const AddressChip = ({ address, name, ...props }: AddressChipProps) => {\n const classes = useStyles();\n const label = (\n <>\n {name ? {name} : null}\n {shortAddress(address)}\n \n );\n return (\n \n }\n label={label}\n />\n );\n};\n","import React from \"react\";\nimport classNames from \"classnames\";\nimport { Box, Chip, makeStyles } from \"@material-ui/core\";\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\";\nimport { AddressChip } from \"../../../components/ethereum/AddressChip\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { Grow } from \"../../../components/layout/Grow\";\n\nconst useStyles = makeStyles((theme) => ({\n title: {\n padding: theme.spacing(2, 0.5, 2, 0),\n marginRight: theme.spacing(1),\n display: \"flex\",\n alignItems: \"center\",\n flexDirection: \"row\",\n flexGrow: 1,\n },\n clickable: {\n cursor: \"pointer\",\n },\n moduleChip: {\n marginRight: theme.spacing(1),\n fontSize: 14,\n },\n}));\n\nexport interface TransactionBlockHeaderTitleProps {\n edit: boolean;\n open: boolean;\n transaction: Transaction;\n\n onToggle(): void;\n}\n\nexport const TransactionBlockHeaderTitle = ({\n edit,\n open,\n transaction,\n onToggle,\n}: TransactionBlockHeaderTitleProps) => {\n const classes = useStyles();\n return (\n \n {transaction.module ? (\n \n ) : null}\n {transaction.func.name}} />\n \n {!edit ? : null}\n \n );\n};\n","import React from \"react\";\nimport classNames from \"classnames\";\nimport { makeStyles } from \"@material-ui/core\";\nimport {\n DraggableProvided,\n DraggableStateSnapshot,\n Omit,\n} from \"react-beautiful-dnd\";\nimport { Row } from \"../../../components/layout/Row\";\nimport { ReactComponent as GripIcon } from \"../../../assets/icons/grip-icon.svg\";\nimport { Collapsable } from \"../../../components/Collapsable\";\nimport {\n TransactionBlockHeaderButtons,\n TransactionBlockHeaderButtonsProps,\n} from \"./TransactionBlockHeaderButtons\";\nimport {\n TransactionBlockFields,\n TransactionBlockFieldsProps,\n} from \"./TransactionBlockFields\";\nimport {\n TransactionBlockHeaderTitle,\n TransactionBlockHeaderTitleProps,\n} from \"./TransactionBlockHeaderTitle\";\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n marginTop: \"0 !important\",\n padding: 0,\n },\n collapsableContainer: {\n margin: 0,\n padding: theme.spacing(1, 2, 2, 2),\n },\n dragging: {\n borderColor: \"#31AAB7\",\n borderStyle: \"solid\",\n borderWidth: 2,\n },\n noDragging: {\n transform: \"none !important\",\n },\n dropAnimation: {\n transitionDuration: \"0.001s !important\",\n },\n grip: {\n display: \"flex\",\n cursor: \"grab\",\n padding: theme.spacing(2),\n },\n}));\n\ntype TransactionBlockContentProps = {\n open: boolean;\n edit?: Edit;\n drag: {\n provider: DraggableProvided;\n snapshot: DraggableStateSnapshot;\n };\n blockFieldsProps: TransactionBlockFieldsProps;\n headerTitleProps: Omit;\n headerButtonProps: Omit;\n};\n\nexport const TransactionBlockContent = ({\n open,\n edit = false,\n headerButtonProps,\n headerTitleProps,\n blockFieldsProps,\n drag,\n}: TransactionBlockContentProps) => {\n const classes = useStyles();\n\n return (\n }\n >\n \n
\n \n
\n \n \n
\n \n );\n};\n","import React, { useState } from \"react\";\nimport classNames from \"classnames\";\nimport { makeStyles, Paper, withStyles } from \"@material-ui/core\";\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\";\nimport { Draggable } from \"react-beautiful-dnd\";\nimport { TransactionBlockContent } from \"./TransactionBlockContent\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\n\ninterface ContractFunctionBlockProps {\n isOver: boolean;\n isOverBefore: boolean;\n index: number;\n transaction: Transaction;\n\n onUpdate(id: string, params: any[]): void;\n\n onDelete(id: string): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n paddingBottom: theme.spacing(2.5),\n },\n placeholder: {\n position: \"absolute\",\n width: \"100%\",\n borderColor: \"#31AAB7\",\n borderStyle: \"solid\",\n borderWidth: 0,\n borderBottomWidth: theme.spacing(0.5),\n \"&.place-after\": {\n bottom: theme.spacing(1),\n },\n \"&.place-before\": {\n top: theme.spacing(-1),\n },\n },\n}));\n\nconst TransactionBlockPlaceholder = withStyles((theme) => ({\n root: {\n height: 56,\n backgroundColor: theme.palette.primary.light,\n },\n}))(Paper);\n\nexport const TransactionBlock = ({\n index,\n isOver,\n isOverBefore,\n transaction,\n onUpdate,\n onDelete,\n}: ContractFunctionBlockProps) => {\n const classes = useStyles();\n\n const [open, setOpen] = useState(false);\n const [edit, setEdit] = useState(false);\n\n const { id, params, func } = transaction;\n\n const handleStartEditing = () => {\n setOpen(true);\n setEdit(true);\n };\n\n const handleToggleContent = () => {\n if (!edit) setOpen(!open);\n };\n\n const handleCancelEditing = () => {\n setEdit(false);\n };\n const handleDeleteTransaction = () => {\n onDelete(id);\n };\n const handleSaveParams = (newParams: any[]) => {\n onUpdate(id, newParams);\n setEdit(false);\n };\n\n return (\n \n {(provider, snapshot) => (\n
\n {edit ? (\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n handleSaveParams(getParams()),\n }}\n />\n )}\n \n ) : (\n \n )}\n {isOver && (\n \n )}\n {snapshot.isDragging && }\n
\n )}\n
\n );\n};\n","import React, { useCallback, useState } from \"react\";\nimport {\n DragDropContext,\n DragStart,\n DragUpdate,\n Droppable,\n DropResult,\n} from \"react-beautiful-dnd\";\nimport { TransactionBlock } from \"./TransactionBlock\";\nimport { serializeTransaction } from \"../../../store/transactionBuilder/helpers\";\nimport { setTransactions } from \"../../../store/transactionBuilder\";\nimport { useRootDispatch } from \"../../../store\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { makeStyles } from \"@material-ui/core\";\n\ninterface TransactionBuilderListProps {\n transactions: Transaction[];\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n display: \"flex\",\n flexGrow: 1,\n outline: \"none\",\n padding: theme.spacing(1.5),\n marginBottom: theme.spacing(2),\n backgroundColor: \"#0d0b217a\",\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n overflowY: \"auto\",\n },\n}));\n\nexport const TransactionBuilderList = ({\n transactions,\n}: TransactionBuilderListProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n\n const [overIndex, setOverIndex] = useState();\n const [sourceIndex, setSourceIndex] = useState();\n\n const handleDragStart = (result: DragStart) => {\n setSourceIndex(result.source.index);\n };\n\n const handleDragUpdate = (update: DragUpdate) => {\n if (\n update.destination &&\n update.destination.index !== update.source.index\n ) {\n setOverIndex(update.destination.index);\n } else {\n setOverIndex(undefined);\n }\n };\n\n const handleDragEnd = (result: DropResult) => {\n setOverIndex(undefined);\n setSourceIndex(undefined);\n if (result.destination) {\n const sorted = Array.from(transactions).map(serializeTransaction);\n const [removed] = sorted.splice(result.source.index, 1);\n sorted.splice(result.destination.index, 0, removed);\n dispatch(setTransactions(sorted));\n }\n };\n\n const handleTransactionUpdate = useCallback(\n (id, params) => {\n const txs = transactions.map(serializeTransaction).map((transaction) => {\n if (transaction.id !== id) {\n return transaction;\n }\n return { ...transaction, params };\n });\n dispatch(setTransactions(txs));\n },\n [dispatch, transactions]\n );\n\n const handleTransactionDelete = useCallback(\n (id) => {\n const txs = Array.from(transactions).map(serializeTransaction);\n const index = txs.findIndex((tx) => tx.id === id);\n if (index >= 0) {\n txs.splice(index, 1);\n dispatch(setTransactions(txs));\n }\n },\n [dispatch, transactions]\n );\n\n return (\n
\n \n \n {(provider) => (\n \n {transactions.map((transaction, index) => (\n \n ))}\n
\n )}\n \n \n
\n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Column } from \"../../../components/layout/Column\";\nimport { ReactComponent as AvatarEmptyIcon } from \"../../../assets/icons/avatar-empty.svg\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n display: \"flex\",\n flexGrow: 1,\n alignItems: \"center\",\n justifyContent: \"center\",\n outline: \"none\",\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n marginBottom: theme.spacing(2),\n backgroundColor: \"#0d0b217a\",\n },\n content: {\n display: \"grid\",\n gridTemplateColumns: \"40px 1fr\",\n maxWidth: 324,\n },\n title: {\n fontWeight: \"bold\",\n marginBottom: theme.spacing(1),\n lineHeight: 1,\n },\n details: {\n marginLeft: theme.spacing(3),\n },\n}));\n\nexport const TransactionBuilderEmptyList = () => {\n const classes = useStyles();\n return (\n
\n
\n \n \n \n No Transactions Added\n \n \n Add transactions using the Write tab on any mod, and view these\n transactions here before submitting them as a bundle.\n \n \n
\n
\n );\n};\n","import React from \"react\"\nimport { Badge, Fade, makeStyles, Modal, Typography } from \"@material-ui/core\"\nimport { Interface } from \"@ethersproject/abi\"\nimport { ActionButton } from \"../../components/ActionButton\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getTransactionBuilderOpen,\n getTransactions,\n} from \"../../store/transactionBuilder/selectors\"\nimport {\n closeTransactionBuilder,\n resetTransactions,\n} from \"../../store/transactionBuilder\"\nimport { fetchPendingModules } from \"../../store/modules\"\nimport { TransactionBuilderList } from \"./components/TransactionBuilderList\"\nimport { TransactionBuilderEmptyList } from \"./components/TransactionBuilderEmptyList\"\nimport { ReactComponent as ArrowUpIcon } from \"../../assets/icons/arrow-up-icon.svg\"\nimport classNames from \"classnames\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\n\nconst useStyles = makeStyles((theme) => ({\n fullWindow: {\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n outline: \"none\",\n borderRadius: 0,\n },\n header: {\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n marginBottom: theme.spacing(2),\n padding: theme.spacing(0.5, 0.5, 0.5, 1.5),\n },\n content: {\n padding: theme.spacing(1.5, 1.5, 1.5, 1.5),\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n background: \"rgba(78, 72, 87, 0.8)\",\n borderWidth: 1,\n borderColor: \"rgba(255,255,255,0.2)\",\n },\n modal: {\n width: \"70%\",\n minWidth: 400,\n maxWidth: 820,\n\n height: \"calc(100% - 22px) !important\",\n left: \"auto !important\",\n right: \"19px !important\",\n top: \"11px !important\",\n },\n backdrop: {\n backdropFilter: \"blur(4px)\",\n },\n bagIcon: {\n marginLeft: theme.spacing(2),\n stroke: \"white\",\n },\n badge: {\n color: theme.palette.common.white,\n display: \"flex\",\n position: \"relative\",\n transform: \"none\",\n textAlign: \"center\",\n background: \"none\",\n fontSize: 16,\n },\n badgeRoot: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n height: 36,\n width: 36,\n borderRadius: 60,\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: colors.tan[300],\n padding: theme.spacing(0.5),\n },\n circleIconContainer: {\n borderColor: colors.tan[300],\n padding: theme.spacing(0.5),\n },\n}))\n\nexport const TransactionBuilder = () => {\n const classes = useStyles()\n const { sdk, safe } = useSafeAppsSDK()\n const dispatch = useRootDispatch()\n\n const open = useRootSelector(getTransactionBuilderOpen)\n const transactions = useRootSelector(getTransactions)\n\n const handleClose = () => dispatch(closeTransactionBuilder())\n\n const handleSubmitTransaction = async () => {\n try {\n const txs = transactions.map((tx): BaseTransaction => {\n const encoder = new Interface([tx.func])\n return {\n to: tx.to,\n value: \"0\",\n data: encoder.encodeFunctionData(tx.func, tx.params),\n }\n })\n await sdk.txs.send({ txs })\n dispatch(resetTransactions())\n dispatch(\n fetchPendingModules({\n safeAddress: safe.safeAddress,\n chainId: safe.chainId,\n }),\n )\n handleClose()\n } catch (error) {\n console.log(\"handleSubmitTransaction:error\", error)\n }\n }\n\n return (\n \n \n \n \n Bundle Transactions\n \n\n \n \n \n \n\n {transactions.length ? (\n \n ) : (\n \n )}\n }\n onClick={handleSubmitTransaction}\n >\n Submit Transactions\n \n \n \n \n )\n}\n\nexport default TransactionBuilder\n","import React from \"react\"\nimport { AppLayout } from \"./components/layout/AppLayout\"\nimport Panel from \"./views/Panel\"\nimport { Views } from \"./View\"\nimport Header from \"./views/Header\"\nimport { makeStyles } from \"@material-ui/core\"\nimport TransactionBuilder from \"./views/TransactionBuilder\"\nimport zodiacBackground from \"./assets/images/zodiac-bg.svg\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n background: `url(${zodiacBackground})`,\n backgroundSize: \"cover\",\n },\n background: {\n height: \"100vh\",\n padding: theme.spacing(3, 4, 4, 4),\n background:\n \"linear-gradient(108.86deg, rgba(26, 33, 66, 0.85) 6.24%, rgba(12, 19, 8, 0.85) 53.08%, rgba(37, 6, 4, 0.85) 96.54%);\",\n },\n}))\n\nconst App: React.FC = () => {\n const classes = useStyles()\n\n return (\n
\n
\n
\n }>\n \n \n \n
\n
\n )\n}\n\nexport default App\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { ThemeProvider } from \"styled-components\";\nimport {\n CssBaseline,\n ThemeProvider as MUIThemeProvider,\n} from \"@material-ui/core\";\nimport { Loader } from \"@gnosis.pm/safe-react-components\";\nimport SafeProvider from \"@gnosis.pm/safe-apps-react-sdk\";\nimport App from \"./App\";\nimport { Provider } from \"react-redux\";\nimport { REDUX_STORE } from \"./store\";\nimport { Row } from \"./components/layout/Row\";\nimport {\n zodiacMuiTheme,\n gnosisStyledComponentsTheme,\n} from \"zodiac-ui-components\";\n\nconst Main = () => {\n return (\n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n );\n};\n\nReactDOM.render(\n \n
\n ,\n document.getElementById(\"root\")\n);\n","module.exports = __webpack_public_path__ + \"static/media/zodiac-bg.b4d47715.svg\";"],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/main.eb209abb.chunk.js b/static/js/main.eb209abb.chunk.js new file mode 100644 index 0000000..37e3da8 --- /dev/null +++ b/static/js/main.eb209abb.chunk.js @@ -0,0 +1,2 @@ +(this["webpackJsonpzodiac-app"]=this["webpackJsonpzodiac-app"]||[]).push([[0],{1118:function(e,t){},1212:function(e,t){},1214:function(e,t){},1412:function(e,t){},1417:function(e,t){},1435:function(e,t){},1437:function(e,t){},1458:function(e,t){},1495:function(e,t){},1593:function(e,t){},1636:function(e,t){},1656:function(e,t,a){"use strict";a.r(t);var n,r,o,c=a(0),i=a.n(c),l=a(60),s=a.n(l),u=a(472),d=a(1713),f=a(1722),m=a(64),p=a(71),b=a.n(p),g=a(501),h=a(14),E=Object(g.a)((function(e){return{root:{display:"grid",height:"calc(100% - 70px)",gridTemplateColumns:"390px 1fr",gridGap:e.spacing(.5),overflow:"hidden",padding:e.spacing(.5)},leftPanel:{overflowY:"auto"},content:{overflowY:"auto"}}})),v=function(e){var t=e.children,a=e.left,n=E();return i.a.createElement(h.c,{variant:"outlined",className:n.root},i.a.createElement(h.c,{variant:"outlined",className:n.content},a),i.a.createElement(h.c,{variant:"outlined",id:"app-content",className:n.content},t))},y=a(758),O=a(503),x=a(18),w=a(57),j=a(1),C=a.n(j),k=a(25),S=a(212),N=a(12),I=a(34),T=a(69),A=a(226),R=a(298),M=a(29),B=a(537),D="0x0000000000000000000000000000000000000001",L=function(e,t,a,n,r){return{to:t,data:e.encodeFunctionData(a,n),value:r||"0"}},P=a(9);!function(e){e[e.MAINNET=1]="MAINNET",e[e.GOERLI=5]="GOERLI",e[e.OPTIMISM=10]="OPTIMISM",e[e.BSC=56]="BSC",e[e.GNOSIS_CHAIN=100]="GNOSIS_CHAIN",e[e.POLYGON=137]="POLYGON",e[e.ARBITRUM=42161]="ARBITRUM",e[e.AVALANCHE=43114]="AVALANCHE"}(o||(o={}));var F,U={ETH:{symbol:"ETH",decimals:18},XDAI:{symbol:"xDai",decimals:18},MATIC:{symbol:"MATIC",decimals:18},BNB:{symbol:"BNB",decimals:18},AVAX:{symbol:"AVAX",decimals:18}},V=(n={},Object(P.a)(n,o.MAINNET,{chainId:o.MAINNET,name:"mainnet",shortName:"eth",nativeAsset:U.ETH}),Object(P.a)(n,o.GOERLI,{chainId:o.GOERLI,name:"goerli",shortName:"gor",nativeAsset:U.ETH}),Object(P.a)(n,o.OPTIMISM,{chainId:o.OPTIMISM,name:"optimism",shortName:"oeth",nativeAsset:U.ETH}),Object(P.a)(n,o.GNOSIS_CHAIN,{chainId:o.GNOSIS_CHAIN,name:"gnosis_chain",shortName:"gno",nativeAsset:U.XDAI}),Object(P.a)(n,o.BSC,{chainId:o.BSC,name:"binance_smart_chain",shortName:"bnb",nativeAsset:U.BNB}),Object(P.a)(n,o.POLYGON,{chainId:o.POLYGON,name:"polygon",shortName:"matic",nativeAsset:U.MATIC}),Object(P.a)(n,o.ARBITRUM,{chainId:o.ARBITRUM,name:"arbitrum",shortName:"arb1",nativeAsset:U.ETH}),Object(P.a)(n,o.AVALANCHE,{chainId:o.AVALANCHE,name:"avalanche",shortName:"avax",nativeAsset:U.AVAX}),n);r={},Object(P.a)(r,o.MAINNET,U.ETH),Object(P.a)(r,o.GOERLI,U.ETH),Object(P.a)(r,o.OPTIMISM,U.ETH),Object(P.a)(r,o.GNOSIS_CHAIN,U.XDAI),Object(P.a)(r,o.POLYGON,U.MATIC),Object(P.a)(r,o.BSC,U.BNB),Object(P.a)(r,o.ARBITRUM,U.ETH),Object(P.a)(r,o.AVALANCHE,U.AVAX);var H=(F={},Object(P.a)(F,o.MAINNET,{networkExplorerName:"Etherscan",networkExplorerUrl:"https://etherscan.io",networkExplorerApiUrl:"https://api.etherscan.io/api",safeTransactionApi:"https://safe-transaction-mainnet.safe.global/",safeUrl:"https://app.safe.global/eth:",verifyContractUrl:"https://etherscan.io/verifyContract",explorerApiKey:"6RJ8KT4B1S9V7E3CIYECNY7HFW8IPWQ3C4"}),Object(P.a)(F,o.GOERLI,{networkExplorerName:"Etherscan",networkExplorerUrl:"https://goerli.etherscan.io",networkExplorerApiUrl:"https://api-goerli.etherscan.io/api",safeTransactionApi:"https://safe-transaction-goerli.safe.global/",safeUrl:"https://app.safe.global/gor:",verifyContractUrl:"https://goerli.etherscan.io/verifyContract",explorerApiKey:"6RJ8KT4B1S9V7E3CIYECNY7HFW8IPWQ3C4"}),Object(P.a)(F,o.GNOSIS_CHAIN,{networkExplorerName:"GnosisScan",networkExplorerUrl:"https://gnosisscan.io",networkExplorerApiUrl:"https://api.gnosisscan.io/api",safeUrl:"https://app.safe.global/gno:",safeTransactionApi:"https://safe-transaction-gnosis-chain.safe.global/",verifyContractUrl:"https://gnosisscan.io/verifyContract",explorerApiKey:"8ENCUFT4D3XVJS7N9ZFS5Z9XQPNUGRKSN5"}),Object(P.a)(F,o.POLYGON,{networkExplorerName:"Polygonscan",networkExplorerUrl:"https://polygonscan.com",networkExplorerApiUrl:"https://api.polygonscan.com/api",safeUrl:"https://app.safe.global/matic:",safeTransactionApi:"https://safe-transaction-polygon.safe.global/",verifyContractUrl:"https://polygonscan.com/verifyContract",explorerApiKey:"T6WFHXT4HZZ1DISYBINENCSRY38JUW3IU7"}),Object(P.a)(F,o.BSC,{networkExplorerName:"Bscscan",networkExplorerUrl:"https://bscscan.com/",networkExplorerApiUrl:"https://api.bscscan.com/api",safeUrl:"https://app.safe.global/bsc:",safeTransactionApi:"https://safe-transaction-bsc.safe.global/",verifyContractUrl:"https://bscscan.com/verifyContract",explorerApiKey:"AW26UH2PS6I2U6V2537YUBDF5CJVCNDM5E"}),Object(P.a)(F,o.OPTIMISM,{networkExplorerName:"Optimism",networkExplorerUrl:"https://optimistic.etherscan.io/",networkExplorerApiUrl:"https://api-optimistic.etherscan.io/api",safeTransactionApi:"https://safe-transaction-optimism.safe.global/",safeUrl:"https://app.safe.global/oeth:",verifyContractUrl:"https://optimistic.etherscan.io/verifyContract",explorerApiKey:"JXEAJD2QC2Y5GY783GJ3HZ5KP7A4C3F2JH"}),Object(P.a)(F,o.ARBITRUM,{networkExplorerName:"Arbiscan",networkExplorerUrl:"https://arbiscan.io/",networkExplorerApiUrl:"https://api.arbiscan.io/api",safeTransactionApi:"https://safe-transaction-arbitrum.safe.global/",safeUrl:"https://app.safe.global/arb1:",verifyContractUrl:"https://arbiscan.io/verifyContract",explorerApiKey:"KQYPWCBF5Q2S7W8T95K3CVB74BEC6AKCWK"}),Object(P.a)(F,o.AVALANCHE,{networkExplorerName:"Snowtrace",networkExplorerUrl:"https://snowtrace.io/",networkExplorerApiUrl:"https://api.snowtrace.io/api",safeTransactionApi:"https://safe-transaction-avalanche.safe.global/",safeUrl:"https://app.safe.global/avax:",verifyContractUrl:"https://snowtrace.io/verifyContract",explorerApiKey:"4SV7ZU6UA9JJH922KR37J9Q1PPBGVZZF9C"}),F),_=function(e){var t=H[e];if(t)return{name:t.networkExplorerName,url:t.networkExplorerUrl,apiUrl:t.networkExplorerApiUrl,apiKey:t.explorerApiKey,safeTransactionApi:t.safeTransactionApi,safeUrl:t.safeUrl,verifyUrl:t.verifyContractUrl}},G=["function token() view returns (address)"],W=["function name() view returns (string)","function symbol() view returns (string)","function decimals() public view returns (uint8)"],z=["function supportsInterface(bytes4 interfaceID) external view returns (bool)"];function K(){return(K=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,r=new A.b(a,G,t),e.next=4,r.token();case 4:return o=e.sent,c=new A.b(o,W,t),e.next=8,c.symbol();case 8:return e.t0=e.sent,e.next=11,c.decimals();case 11:return e.t1=e.sent,i={symbol:e.t0,decimals:e.t1},e.abrupt("return",{isERC20:!0,coin:i});case 16:return e.prev=16,e.t2=e.catch(0),e.abrupt("return",{isERC20:!1,coin:V[n].nativeAsset});case 19:case"end":return e.stop()}}),e,null,[[0,16]])})))).apply(this,arguments)}var Y,Z=a(482),q=a(1714),X=a(481),Q=a(707),J=a(469),$=["svgRef","title"];function ee(){return(ee=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ae=function(e){var t=e.svgRef,a=e.title,n=te(e,$);return i.a.createElement("svg",ee({width:15,height:12,viewBox:"0 0 15 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Y||(Y=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z",fill:"#001428"})))},ne=i.a.forwardRef((function(e,t){return i.a.createElement(ae,ee({svgRef:t},e))})),re=(a.p,{USDC:"USDC",WETH:"WETH"});var oe,ce=[o.MAINNET,o.POLYGON,o.GOERLI,o.GNOSIS_CHAIN,o.OPTIMISM,o.ARBITRUM,o.AVALANCHE],ie=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:e.spacing(1)},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},select:{marginBottom:-1,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"100%"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1}}})),le=function(e){var t=e.onChange,a=e.defaultOption,n=void 0===a?re.USDC:a,r=e.label,o=e.chainId,l=ie(),s=Object(c.useState)(n),u=Object(x.a)(s,2),d=u[0],f=u[1],m=Object(c.useState)(!1),p=Object(x.a)(m,2),b=p[0],g=p[1],h=function(){return g(!1)},E=function(){return g(!0)},v=i.a.useRef(null),y=function(e){h();var a=Object.keys(re).find((function(t){return re["".concat(t)]===e}));f(e);var n=fe(o,"WETH"===a);t(n)};return Object(c.useEffect)((function(){v.current&&v.current.addEventListener("keyup",(function(e){"Tab"===e.code&&E()}))}),[v]),i.a.createElement("div",null,i.a.createElement(Z.a,{className:l.label},r),i.a.createElement(q.a,{container:!0,className:l.root},i.a.createElement(q.a,{item:!0,xs:12,className:l.dropdownContainer},i.a.createElement(X.a,{disableUnderline:!0,open:b,value:d,ref:v,onOpen:E,onClose:h,className:l.select,MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:l.dropdown,list:l.itemList}},renderValue:function(e){return e},onChange:function(e){return y(e.target.value)}},Object.keys(re).map((function(e){return ce.includes(o)||"WETH"!==e?i.a.createElement(Q.a,{key:e,value:re["".concat(e)],className:l.item},re["".concat(e)],i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"})):null}))))))};function se(e){switch(e){case o.MAINNET:case o.POLYGON:case o.GNOSIS_CHAIN:case o.GOERLI:case o.OPTIMISM:case o.ARBITRUM:return"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0"}return""}function ue(e){switch(e){case o.MAINNET:return"0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c";case o.BSC:return"0xa925646Cae3721731F9a8C886E5D1A7B123151B9";case o.GNOSIS_CHAIN:return"0xE78996A233895bE74a66F451f1019cA9734205cc";case o.POLYGON:return"0x60573B8DcE539aE5bF9aD7932310668997ef0428";case o.GOERLI:return"0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f";case o.OPTIMISM:return"0x0eF940F7f053a2eF5D6578841072488aF0c7d89A";case o.ARBITRUM:return"0x5D18bD4dC5f1AC8e9bD9B666Bd71cB35A327C4A9";case o.AVALANCHE:return"0xD88cd78631Ea0D068cedB0d1357a6eabe59D7502"}return""}function de(e){switch(e){case o.MAINNET:return"0x40f941E48A552bF496B154Af6bf55725f18D77c3";case o.POLYGON:return"0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64";case o.GOERLI:return"0xE60dBa66B85E10E7Fd18a67a6859E241A243950e";case o.GNOSIS_CHAIN:return"0xeF684C38F94F48775959ECf2012D7E864ffb9dd4";case o.OPTIMISM:return"0x278d6b1aA37d09769E519f05FcC5923161A8536D";case o.ARBITRUM:return"0xB0b9f73B424AD8dc58156C2AE0D7A1115D1EcCd1";case o.AVALANCHE:return"0xCFdC4d6FdeC25e339ef07e25C35a482A6bedcfE0"}return""}function fe(e,t){return t?function(e){switch(e){case o.MAINNET:return"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";case o.POLYGON:return"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619";case o.GOERLI:return"0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6";case o.GNOSIS_CHAIN:return"0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1";case o.OPTIMISM:return"0x4200000000000000000000000000000000000006";case o.ARBITRUM:return"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";case o.AVALANCHE:return"0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB"}return""}(e):function(e){switch(e){case o.MAINNET:return"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";case o.POLYGON:return"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";case o.GOERLI:return"0x07865c6E87B9F70255377e024ace6630C1Eaa37F";case o.GNOSIS_CHAIN:return"0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83";case o.OPTIMISM:return"0x7F5c764cBc14f9669B88837ca1490cCa17c31607";case o.ARBITRUM:return"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";case o.AVALANCHE:return"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}return""}(e)}function me(e){switch(e){case o.MAINNET:return"0xf72cfd1b34a91a64f9a98537fe63fbab7530adca";case o.GOERLI:return"0xba08deb3f07a9c55052777fed84a86be8e5ebc1c";case o.GNOSIS_CHAIN:return"0x29f39de98d750eb77b5fafb31b2837f079fce222";case o.POLYGON:return"0x5AFa42b30955f137e10f89dfb5EF1542a186F90e"}return""}function pe(e,t){switch(t){case oe.NO_ARBITRATOR:return ue(e);case oe.KLEROS:return me(e);case oe.OTHER:return""}return""}function be(e){switch(e){case o.MAINNET:return"0x8898B472C54c31894e3B9bb83cEA802a5d0e63C6";case o.POLYGON:return"0x11984dc4465481512eb5b777E44061C158CF2259";case o.GOERLI:return"0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649";case o.GNOSIS_CHAIN:return"0x5bB83e95f63217CDa6aE3D181BA580Ef377D2109";case o.OPTIMISM:return"0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA";case o.ARBITRUM:return"0xEE9deC2712cCE65174B561151701Bf54b99C24C8"}return""}function ge(e,t,a,n){var r=M.d.TELLOR,o=n.owner,c=n.oracle,i=n.cooldown,l=n.expiration,s=n.executor,u=c||se(a),d=Object(M.f)(r,{types:["address","address","address","address","uint32","uint32"],values:[o,t,s,u,i,l]},e,a,Date.now().toString()),f=d.transaction,m=d.expectedModuleAddress,p=[Object(N.a)(Object(N.a)({},f),{},{value:f.value.toString()})];if(s!==t){var b=Object(M.h)(M.d.DELAY,s,e),g=L(b.interface,b.address,"enableModule",[m]);p.push(g)}else{var h=je(t,m);p.push(h)}return p}function he(e,t,a,n){var r=n,o=r.cooldown,c=r.expiration,i=r.executor,l=Object(M.f)(M.d.DELAY,{types:["address","address","address","uint256","uint256"],values:[t,t,i,o,c]},e,a,Date.now().toString()),s=l.transaction,u=je(t,l.expectedModuleAddress);return[Object(N.a)(Object(N.a)({},s),{},{value:s.value.toString()}),u]}function Ee(e,t,a,n){var r=n.executor,o=n.controller,c=n.amb,i=n.chainId,l=Object(M.f)(M.d.BRIDGE,{types:["address","address","address","address","address","bytes32"],values:[t,t,r,c,o,I.ethers.utils.hexZeroPad(T.a.from(i).toHexString(),32)]},e,a,Date.now().toString()),s=l.transaction,u=je(t,l.expectedModuleAddress);return[Object(N.a)(Object(N.a)({},s),{},{value:s.value.toString()}),u]}function ve(e,t,a,n,r,o){var c=o?M.d.CIRCULATING_SUPPLY_ERC721:M.d.CIRCULATING_SUPPLY_ERC20,i=Object(M.g)(c,e,a),l=i.moduleFactory,s=i.moduleMastercopy,u=(new I.ethers.utils.AbiCoder).encode(["address","address","address[]"],[t,n,[t]]),d=s.interface.encodeFunctionData("setUp",[u]),f=Object(M.e)(l,s.address,d,r);return{transaction:{data:l.interface.encodeFunctionData("deployModule",[s.address,d,r]),to:l.address,value:"0"},expectedAddress:f}}function ye(e,t,a,n){return Oe.apply(this,arguments)}function Oe(){return(Oe=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f,m,p,b,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return o=[],c=r.executor,i=r.tokenContract,l=!1,e.prev=3,s=new A.b(i,z,t),e.next=7,s.supportsInterface("0x80ac58cd");case 7:l=e.sent,e.next=13;break;case 10:e.prev=10,e.t0=e.catch(3),console.warn("deployExitModule: error determining token type");case 13:return u=ve(t,a,n,i,Date.now().toString(),l),d=u.transaction,f=u.expectedAddress,o.push(d),m=l?M.d.EXIT_ERC721:M.d.EXIT_ERC20,p=Object(M.f)(m,{types:["address","address","address","address","address"],values:[a,a,c,i,f]},t,n,Date.now().toString()),b=p.transaction,g=p.expectedModuleAddress,o.push(Object(N.a)(Object(N.a)({},b),{},{value:b.value.toString()})),h=je(a,g),o.push(h),e.abrupt("return",o);case 21:case"end":return e.stop()}}),e,null,[[3,10]])})))).apply(this,arguments)}function xe(e,t,a){return we.apply(this,arguments)}function we(){return(we=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new A.b(a,B.a,t),e.next=3,r.getModulesPaginated(D,50);case 3:return o=e.sent,c=Object(x.a)(o,1),i=c[0],e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function je(e,t){return L(new R.b(B.a),e,"enableModule",[t])}function Ce(e,t,a,n){return ke.apply(this,arguments)}function ke(){return(ke=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,xe(t,a,n);case 2:if((o=e.sent).length){e.next=5;break}throw new Error("Safe does not have enabled modules");case 5:return c=D,o.length>1&&(i=o.findIndex((function(e){return e.toLowerCase()===r.toLowerCase()})))>0&&(c=o[i-1]),l=[c,r],e.abrupt("return",Object(N.a)({params:l},L(new R.b(B.a),a,"disableModule",l)));case 9:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(e){e[e.NO_ARBITRATOR=0]="NO_ARBITRATOR",e[e.KLEROS=1]="KLEROS",e[e.OTHER=2]="OTHER"}(oe||(oe={}));var Se=function(e,t,a,n,r){var o,c=arguments.length>5&&void 0!==arguments[5]?arguments[5]:[],i=new A.b(a,n,e);return(o=i.functions)[r].apply(o,Object(w.a)(c))};function Ne(e,t,a){return Ie.apply(this,arguments)}function Ie(){return(Ie=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=_(t)){e.next=3;break}return e.abrupt("return",[]);case 3:return o=new URL("api/v1/safes/".concat(a,"/transactions"),r.safeTransactionApi),Object.entries(n).forEach((function(e){var t=Object(x.a)(e,2),a=t[0],n=t[1];return o.searchParams.set(a,n)})),e.next=7,fetch(o.toString());case 7:return c=e.sent,e.next=10,c.json();case 10:return i=e.sent,e.abrupt("return",i.results);case 12:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Te(e,t){return Ae.apply(this,arguments)}function Ae(){return(Ae=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n=_(t)){e.next=3;break}throw new Error("invalid network");case 3:return r=new URL("api/v1/safes/".concat(a),n.safeTransactionApi),e.next=6,fetch(r.toString());case 6:return o=e.sent,e.next=9,o.json();case 9:return c=e.sent,e.abrupt("return",c);case 11:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Re(e,t,a,n){var r=n.target,o=n.multisend,c=Object(M.f)(M.d.ROLES_V1,{types:["address","address","address"],values:[t,t,r]},e,a,Date.now().toString()),i=c.transaction,l=c.expectedModuleAddress,s=je(t,l),u=Object(M.h)(M.d.ROLES_V1,l,e),d=L(u.interface,u.address,"setMultisend",[o]);return[Object(N.a)(Object(N.a)({},i),{},{value:i.value.toHexString()}),s,d]}function Me(e,t,a,n){var r=n.target,o=n.multisend,c=Object(M.f)(M.d.ROLES_V2,{types:["address","address","address"],values:[t,t,r]},e,a,Date.now().toString()),i=c.transaction,l=c.expectedModuleAddress,s=je(t,l),u=Object(M.h)(M.d.ROLES_V2,l,e),d={to:u.address,data:u.interface.encodeFunctionData("setTransactionUnwrapper",[o,"0x8d80ff0a","0x93B7fCbc63ED8a3a24B59e1C3e6649D50B7427c0"]),value:"0"};return[Object(N.a)(Object(N.a)({},i),{},{value:i.value.toHexString()}),s,d]}function Be(e,t,a,n,r){var o=M.d.OPTIMISTIC_GOVERNOR,c=n.executor,i=n.collateral,l=n.bond,s=n.rules,u=n.identifier,d=n.liveness,f=function(e,t){return t?Number(e)*Math.pow(10,18):Number(e)*Math.pow(10,6)}(l,r).toString(),m=Object(M.f)(o,{types:["address","address","uint256","string","bytes32","uint64"],values:[c,i,f,s,u,d]},e,a,Date.now().toString()),p=m.transaction,b=m.expectedModuleAddress,g=[Object(N.a)(Object(N.a)({},p),{},{value:p.value.toString()})];if(c!==t){var h=Object(M.h)(M.d.DELAY,c,e),E=L(h.interface,h.address,"enableModule",[b]);g.push(E)}else{var v=je(t,b);g.push(v)}return g}function De(e,t,a,n){var r=M.d.CONNEXT,o=n.domainId,c=n.sender,i=n.owner,l=n.avatar,s=n.target,u=be(a),d=Object(M.f)(r,{types:["address","address","address","address","uint32","address"],values:[i,l,s,c,o,u]},e,a,Date.now().toString()),f=d.transaction,m=d.expectedModuleAddress,p=[Object(N.a)(Object(N.a)({},f),{},{value:f.value.toString()})],b=je(t,m);return p.push(b),p}var Le,Pe,Fe,Ue=a(486),Ve=a(96),He=a(300),_e=a(487),Ge=a.n(_e);!function(e){e.TELLOR="tellor",e.OPTIMISTIC_GOVERNOR="optimisticGovernor",e.REALITY_ETH="realityETH",e.REALITY_ERC20="realityERC20",e.DELAY="delay",e.BRIDGE="bridge",e.EXIT="exit",e.ROLES_V1="roles_v1",e.ROLES_V2="roles_v2",e.OZ_GOVERNOR="ozGovernor",e.KLEROS_REALITY="klerosReality",e.CONNEXT="connext",e.UNKNOWN="unknown"}(Fe||(Fe={}));var We,ze=(Le={},Object(P.a)(Le,Fe.TELLOR,"Tellor Module"),Object(P.a)(Le,Fe.OPTIMISTIC_GOVERNOR,"UMA oSnap Module"),Object(P.a)(Le,Fe.REALITY_ERC20,"Reality Module"),Object(P.a)(Le,Fe.REALITY_ETH,"Reality Module"),Object(P.a)(Le,Fe.KLEROS_REALITY,"Kleros Reality Module"),Object(P.a)(Le,Fe.UNKNOWN,"Unknown Module"),Object(P.a)(Le,Fe.BRIDGE,"Bridge Module"),Object(P.a)(Le,Fe.DELAY,"Delay Modifier"),Object(P.a)(Le,Fe.ROLES_V1,"Roles Modifier (v1)"),Object(P.a)(Le,Fe.ROLES_V2,"Roles Modifier (v2)"),Object(P.a)(Le,Fe.EXIT,"Exit Module"),Object(P.a)(Le,Fe.OZ_GOVERNOR,"Governor Module"),Object(P.a)(Le,Fe.CONNEXT,"Connext Module"),Le),Ke=(Pe={},Object(P.a)(Pe,Fe.TELLOR,M.a[M.d.TELLOR]),Object(P.a)(Pe,Fe.OPTIMISTIC_GOVERNOR,M.a[M.d.OPTIMISTIC_GOVERNOR]),Object(P.a)(Pe,Fe.REALITY_ERC20,M.a[M.d.REALITY_ERC20]),Object(P.a)(Pe,Fe.REALITY_ETH,M.a[M.d.REALITY_ETH]),Object(P.a)(Pe,Fe.KLEROS_REALITY,M.a[M.d.REALITY_ETH]),Object(P.a)(Pe,Fe.UNKNOWN,[]),Object(P.a)(Pe,Fe.BRIDGE,M.a[M.d.BRIDGE]),Object(P.a)(Pe,Fe.DELAY,M.a[M.d.DELAY]),Object(P.a)(Pe,Fe.ROLES_V1,M.a[M.d.ROLES_V1]),Object(P.a)(Pe,Fe.ROLES_V2,M.a[M.d.ROLES_V2]),Object(P.a)(Pe,Fe.EXIT,M.a[M.d.EXIT_ERC20]),Object(P.a)(Pe,Fe.OZ_GOVERNOR,M.a[M.d.OZ_GOVERNOR]),Object(P.a)(Pe,Fe.CONNEXT,M.a[M.d.CONNEXT]),Pe);!function(e){e[e.CREATE=0]="CREATE",e[e.REMOVE=1]="REMOVE"}(We||(We={}));var Ye=["function masterCopy() external view returns (address)"];function Ze(e){if(e!==Fe.UNKNOWN)return{type:e,name:ze[e],abi:Ke[e]}}function qe(e){return"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea265627a7a72315820d8a00dc4fe6bf675a9d7416fc2d00bb3433362aa8186b750f76c4027269667ff64736f6c634300050e0032"===e.toLowerCase()}function Xe(e){return 92===e.length&&(e.startsWith("0x363d3d373d3d3d363d73")&&e.endsWith("5af43d82803e903d91602b57fd5bf3"))}function Qe(e){return"0x"+e.substr(22,40)}function Je(e,t,a){return $e.apply(this,arguments)}function $e(){return($e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new A.b(a,Ye,t),e.next=3,r.functions.masterCopy();case 3:return o=e.sent,c=Object(x.a)(o,1),i=c[0],e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var et=a(745),tt=a.n(et);function at(e){return!e.stateMutability||!["view","pure"].includes(e.stateMutability)}function nt(e){return!at(e)}var rt=Ge()((function(e,t){return tt()(function(){var a=Object(k.a)(C.a.mark((function a(n){var r,o,c,i,l,s,u,d,f,m;return C.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:if(r=_(e)){a.next=3;break}throw new Error("Network data not found");case 3:return o=r.apiUrl,c=r.apiKey,i={module:"contract",action:"getsourcecode",address:t},c&&(i.apiKey=c),l=new URLSearchParams(i),a.next=9,fetch("".concat(o,"?").concat(l));case 9:if((s=a.sent).ok){a.next=12;break}throw new Error("Could not fetch contract source code");case 12:return a.next=14,s.json();case 14:if(u=a.sent,d=u.status,f=u.result,"0"!==d){a.next=19;break}throw new Error("Could not fetch contract source code");case 19:return(m=f[0]).ContractName||n(new Error("Contract is not verified")),a.abrupt("return",m);case 22:case"end":return a.stop()}}),a)})));return function(e){return a.apply(this,arguments)}}(),{retries:4,minTimeout:1e3})}),(function(e,t){return"".concat(e,"_").concat(t)}));function ot(e){return!e.inputs.length}function ct(e){var t,a;return 1===(null===(t=e.outputs)||void 0===t?void 0:t.length)&&e.outputs&&"array"!==(null===(a=e.outputs[0])||void 0===a?void 0:a.baseType)}function it(e,t){var a=t;if("array"===e.baseType||"tuple"===e.baseType)try{a=JSON.parse(a)}catch(n){throw new Error("Input must be of type "+e.baseType)}if(!function(e,t){try{return He.b.encode([e],[t]),!0}catch(a){return!1}}(e,a))throw new Error("Input must be of type "+e.type);return a}function lt(e,t){if("array"===e.baseType||"tuple"===e.baseType)try{return JSON.stringify(t)}catch(a){console.warn("formatDisplayParamValue: value is not an object",t,a)}return t.toString()}var st,ut=Ge()(function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f,m;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,a.eth.getCode([r]);case 2:if(!Xe(o=e.sent)){e.next=9;break}return c=Qe(o),e.next=7,ut(t,a,n,c);case 7:return i=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},i),{},{address:r}));case 9:if(!qe(o)){e.next=17;break}return e.next=12,Je(t,r,n);case 12:return l=e.sent,e.next=15,ut(t,a,n,l);case 15:return s=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},s),{},{address:r}));case 17:if((u=wt(n,r))===Fe.UNKNOWN){e.next=20;break}return e.abrupt("return",Object(N.a)({type:u,address:r,implAddress:r,name:Tt(u)},Ze(u)));case 20:return e.prev=20,e.next=23,rt(n,r);case 23:return d=e.sent,f=d.ABI,m=d.ContractName,e.abrupt("return",{address:r,implAddress:r,name:m,abi:f,type:Fe.UNKNOWN});case 29:return e.prev=29,e.t0=e.catch(20),e.abrupt("return",{address:r,implAddress:r,type:Fe.UNKNOWN});case 32:case"end":return e.stop()}}),e,null,[[20,29]])})));return function(t,a,n,r){return e.apply(this,arguments)}}(),(function(e,t,a,n){return"".concat(t,"_").concat(a,"_").concat(n)}));function dt(e,t){return"array"!==e&&"tuple"!==e||(t=JSON.stringify(t)),t.toString()}var ft="0x0000000000000000000000000000000000000001";function mt(e){return e.type===Fe.DELAY}var pt=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u=arguments;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c=u.length>5&&void 0!==u[5]?u[5]:[a],e.next=3,ut(t,n,r,a);case 3:if((i=e.sent).type!==Fe.DELAY){e.next=8;break}return e.next=7,bt(t,a,n,r,o);case 7:return e.abrupt("return",e.sent);case 8:return e.next=10,ht(t,a,i.abi,n,r,c);case 10:return l=e.sent,e.next=13,vt(t,a,i.abi,r);case 13:return s=e.sent,e.abrupt("return",{owner:s,subModules:l,id:a,name:i.name,type:i.type,address:a,parentModule:o});case 15:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}();function bt(e,t,a,n,r){return gt.apply(this,arguments)}function gt(){return(gt=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d,f,m,p,b,g,h,E,v,y;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(M.h)(M.d.DELAY,a,t);case 2:return c=e.sent,i=c.interface.fragments.map((function(e){return e})),e.prev=4,l=new Ue.Contract(c.address,i),s=new Ue.Provider,e.next=9,s.init(t);case 9:return u=l.txCooldown(),d=l.txExpiration(),f=l.getModulesPaginated(ft,50),e.next=14,s.all([u,d,f]);case 14:if(m=e.sent,p=Object(x.a)(m,3),b=p[0],g=p[1],h=Object(x.a)(p[2],1),!(E=h[0])){e.next=26;break}return(v=E.map(function(){var e=Object(k.a)(C.a.mark((function e(c,i){var l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,pt(t,c,n,r,o);case 2:return l=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},l),{},{id:"".concat(a,"_").concat(c,"_").concat(i),parentModule:a}));case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}())).reverse(),e.next=25,Promise.all(v);case 25:E=e.sent;case 26:return e.next=28,vt(t,a,i,r);case 28:return y=e.sent,e.abrupt("return",{owner:y,address:a,parentModule:o,id:a,name:"Delay Module",type:Fe.DELAY,subModules:E||[],expiration:g.toString(),cooldown:b.toString()});case 32:return e.prev=32,e.t0=e.catch(4),console.warn("Error fetching delay module",e.t0),e.abrupt("return",{address:a,parentModule:o,id:a,name:"Delay Module",type:Fe.UNKNOWN,subModules:[]});case 36:case"end":return e.stop()}}),e,null,[[4,32]])})))).apply(this,arguments)}function ht(e,t,a,n,r){return Et.apply(this,arguments)}function Et(){return(Et=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d,f=arguments;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(c=f.length>5&&void 0!==f[5]?f[5]:[],e.prev=1,n){e.next=4;break}return e.abrupt("return",[]);case 4:return(i=new A.b(a,n,t)).interface.getFunction("getModulesPaginated(address,uint256)"),e.next=8,i.getModulesPaginated(ft,50);case 8:return l=e.sent,s=Object(x.a)(l,1),u=s[0],d=[].concat(Object(w.a)(c),Object(w.a)(u)),e.next=14,Promise.all(u.filter((function(e){return!c.includes(e)})).map(function(){var e=Object(k.a)(C.a.mark((function e(n,c){var i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,pt(t,n,r,o,a,d);case 2:return i=e.sent,e.abrupt("return",Object(N.a)(Object(N.a)({},i),{},{id:"".concat(a,"_").concat(n,"_").concat(c),parentModule:a}));case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()));case 14:return e.abrupt("return",e.sent);case 17:return e.prev=17,e.t0=e.catch(1),e.abrupt("return",[]);case 20:case"end":return e.stop()}}),e,null,[[1,17]])})))).apply(this,arguments)}function vt(e,t,a,n){return yt.apply(this,arguments)}function yt(){return(yt=Object(k.a)(C.a.mark((function e(t,a,n,r){var o;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(e.prev=0,n){e.next=3;break}return e.abrupt("return",void 0);case 3:return(o=new A.b(a,n,t)).interface.getFunction("owner()"),e.next=7,o.owner();case 7:return e.abrupt("return",e.sent);case 10:return e.prev=10,e.t0=e.catch(0),e.abrupt("return",void 0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}function Ot(e){return e.dataDecoded&&"multiSend"===e.dataDecoded.method?e.dataDecoded.parameters[0].valueDecoded:[e]}var xt=(st={},Object(P.a)(st,M.d.TELLOR,Fe.TELLOR),Object(P.a)(st,M.d.OPTIMISTIC_GOVERNOR,Fe.OPTIMISTIC_GOVERNOR),Object(P.a)(st,M.d.REALITY_ETH,Fe.REALITY_ETH),Object(P.a)(st,M.d.REALITY_ERC20,Fe.REALITY_ERC20),Object(P.a)(st,M.d.DELAY,Fe.DELAY),Object(P.a)(st,M.d.BRIDGE,Fe.BRIDGE),Object(P.a)(st,M.d.EXIT_ERC20,Fe.EXIT),Object(P.a)(st,M.d.ROLES,Fe.ROLES_V1),Object(P.a)(st,M.d.ROLES_V1,Fe.ROLES_V1),Object(P.a)(st,M.d.ROLES_V2,Fe.ROLES_V2),Object(P.a)(st,M.d.OZ_GOVERNOR,Fe.OZ_GOVERNOR),st);function wt(e,t){var a=M.c[e];if(!a)return Fe.UNKNOWN;var n=Object.entries(a).find((function(e){var a=Object(x.a)(e,2)[1];return Object.values(a).some((function(e){return e.toLowerCase()===t.toLowerCase()}))}));return n&&xt[n[0]]||Fe.UNKNOWN}function jt(e,t){var a,n=(null===(a=M.b[t])||void 0===a?void 0:a.factory)||"";return wt(t,Ot(e).map((function(e){if(e.to.toLowerCase()===n.toLowerCase()){if(!e.dataDecoded)try{return(r=e.data,new I.ethers.utils.Interface(Ct).decodeFunctionData("deployModule",r))[0]}catch(o){return void console.warn("failed to decode proxy factory transaction: ",e.data)}if("deployModule"===e.dataDecoded.method){var t,a=null===(t=e.dataDecoded.parameters)||void 0===t?void 0:t.find((function(e){return"masterCopy"===e.name}));if(a)return a.value}}var r})).find((function(e){return e}))||"")}var Ct=["function deployModule(address masterCopy, bytes initializer, uint256 saltNonce) returns (address proxy)"];function kt(e){return e.dataDecoded&&"enableModule"===e.dataDecoded.method}function St(e){return e.dataDecoded&&"disableModule"===e.dataDecoded.method}function Nt(e,t){return t.flatMap(Ot).filter(St).map((function(t){var a=t.dataDecoded.parameters.find((function(e){return"module"===e.name})),n=a&&a.value?a.value:"",r=e.find((function(e){return e.address===n}));return{address:n,executor:t.to,operation:We.REMOVE,module:r?r.type:Fe.UNKNOWN}}))}function It(e,t){var a=function(e,t){return e.map((function(e){var a,n=Ot(e).reverse().find(kt);if(n){var r=jt(e,t),o=null===(a=n.dataDecoded.parameters)||void 0===a?void 0:a.find((function(e){return"module"===e.name})),c=null===o||void 0===o?void 0:o.value;if(r&&c)return{address:c,type:r}}})).reduce((function(e,t){return t?Object(N.a)(Object(N.a)({},e),{},Object(P.a)({},t.address,t.type)):e}),{})}(e,t);return e.flatMap(Ot).filter((function(e){return kt(e)})).map((function(e){var t=e.dataDecoded.parameters[0].value||"",n=a[t]||Fe.UNKNOWN;return{address:t,executor:e.to,module:n,operation:We.CREATE}}))}function Tt(e){return ze[e||Fe.UNKNOWN]}function At(e){return e.modules.current}function Rt(e){return e.modules.list}function Mt(e){return e.modules.reloadCount}function Bt(e){return e.modules.loadingModules}function Dt(e){return Rt(e).filter(mt)}function Lt(e){return e.modules.operation}function Pt(e){return e.modules.pendingModules}function Ft(e){return Pt(e).filter((function(e){return e.operation===We.CREATE}))}function Ut(e){return Pt(e).filter((function(e){return e.operation===We.REMOVE}))}function Vt(e){return e.modules.safeThreshold}function Ht(e){return e.modules.currentPendingModule}var _t,Gt,Wt={operation:"read",reloadCount:0,safeThreshold:1,loadingModules:!0,list:[],current:void 0,pendingModules:[],moduleAdded:!1,realityModuleScreen:!1,OzGovernorModuleScreen:!1},zt=Object(S.b)("modules/fetchModulesList",function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.provider,r=t.safeSDK,o=t.safeAddress,c=t.chainId,e.next=3,n.ready;case 3:return e.next=5,xe(n,o,c);case 5:return i=e.sent,(l=i.map(function(){var e=Object(k.a)(C.a.mark((function e(t){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,pt(n,t,r,c,o);case 3:return e.abrupt("return",e.sent);case 6:throw e.prev=6,e.t0=e.catch(0),new Error("Error sanitizing module ".concat(t,": ").concat(e.t0));case 9:case"end":return e.stop()}}),e,null,[[0,6]])})));return function(t){return e.apply(this,arguments)}}())).reverse(),e.prev=8,e.next=11,Promise.all(l);case 11:return s=e.sent,e.abrupt("return",s.filter((function(e){return void 0!==e})));case 15:throw e.prev=15,e.t0=e.catch(8),console.error("Cant fetch modules",e.t0),e.t0;case 19:case"end":return e.stop()}}),e,null,[[8,15]])})));return function(t,a){return e.apply(this,arguments)}}()),Kt=Object(S.b)("modules/fetchPendingModules",function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n,r,o,c,i,l,s,u,d,f,m;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.safeAddress,r=t.chainId,o=t.retry,c=void 0===o||o,e.next=3,Te(r,n);case 3:return i=e.sent,e.next=6,Ne(r,n,{nonce__gte:i.nonce.toString()});case 6:return l=e.sent,s=a.getState(),u=Rt(s),d=It(l,r),f=Nt(u,l),m=[].concat(Object(w.a)(d),Object(w.a)(f)),c&&setTimeout((function(){a.dispatch(Kt({safeAddress:n,chainId:r,retry:!1}))}),4e3),e.abrupt("return",{safeInfo:i,pendingModules:m});case 14:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()),Yt=Object(S.c)({name:"modules",initialState:Wt,reducers:{increaseReloadCount:function(e){e.reloadCount+=1},setCurrentModule:function(e,t){e.current=t.payload,e.operation="read",e.currentPendingModule=void 0},unsetCurrentModule:function(e){e.current=void 0,e.currentPendingModule=void 0},setOperation:function(e,t){e.operation=t.payload},setCurrentPendingModule:function(e,t){e.currentPendingModule=t.payload,e.current=void 0},setModuleAdded:function(e,t){e.moduleAdded=t.payload},setRealityModuleScreen:function(e,t){e.realityModuleScreen=t.payload},setOzGovernorModuleScreen:function(e,t){e.OzGovernorModuleScreen=t.payload}},extraReducers:function(e){e.addCase(zt.rejected,(function(e){e.loadingModules=!1})),e.addCase(zt.fulfilled,(function(e,t){e.loadingModules=!1,e.list=t.payload;var a=e.current;a&&(t.payload.some((function(e){return e.address===a.address}))||(e.current=void 0))})),e.addCase(Kt.fulfilled,(function(e,t){var a=t.payload,n=a.safeInfo,r=a.pendingModules;e.safeThreshold=n.threshold,e.pendingModules=r}))}}),Zt=Yt.actions,qt=(Zt.increaseReloadCount,Zt.setCurrentModule),Xt=Zt.unsetCurrentModule,Qt=Zt.setOperation,Jt=Zt.setCurrentPendingModule,$t=Zt.setModuleAdded,ea=Zt.setRealityModuleScreen,ta=Zt.setOzGovernorModuleScreen,aa=a(195),na=Object(S.c)({name:"transactionBuilder",initialState:{open:!1,addTransaction:{},transactions:[]},reducers:{openTransactionBuilder:function(e){e.open=!0},closeTransactionBuilder:function(e){e.open=!1},setTransactions:function(e,t){e.transactions=t.payload},addTransaction:function(e,t){e.transactions.push(t.payload)},resetTransactions:function(e){e.transactions=[]},setNewTransaction:function(e,t){e.addTransaction=t.payload},resetNewTransaction:function(e){e.addTransaction={}}}}),ra=na.actions,oa=ra.openTransactionBuilder,ca=ra.closeTransactionBuilder,ia=ra.setNewTransaction,la=ra.resetNewTransaction,sa=ra.resetTransactions,ua=ra.addTransaction,da=ra.setTransactions,fa=function(e){return function(t){return function(a){if(a.type===zt.fulfilled.type){var n=Ht(e.getState()),r=t(a);if(n){var o=function e(t){var a=t.flatMap((function(t){return e(t.subModules)}));return[].concat(Object(w.a)(t),Object(w.a)(a))}(Rt(e.getState())).find((function(e){return e.address===n.address}));o&&e.dispatch(qt(o))}return r}if(a.type===Kt.fulfilled.type){var c=e.getState(),i=t(a);if(c.modules.moduleAdded){var l=Ft(c),s=Ft(e.getState());(!l.length&&s.length||l.length&&s.length&&s[0].address!==l[0].address)&&(e.dispatch(Jt(s[0])),e.dispatch($t(!1)))}return i}return t(a)}}},ma=function(e){return function(t){return function(a){return a.type===qt.type&&e.dispatch(ca()),t(a)}}},pa=Object(S.a)({reducer:{modules:Yt.reducer,transactionBuilder:na.reducer},middleware:function(e){return e().concat(fa,ma)}}),ba=function(){return Object(aa.c)()},ga=aa.d,ha=["svgRef","title"];function Ea(){return(Ea=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ya=function(e){var t=e.svgRef,a=e.title,n=va(e,ha);return i.a.createElement("svg",Ea({width:40,height:40,viewBox:"0 0 40 40",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,_t||(_t=i.a.createElement("path",{d:"M39 20H34M20 39V34M1 20H6M20 1V6",stroke:"#B2B5B2",strokeWidth:2,strokeLinecap:"round"})),Gt||(Gt=i.a.createElement("path",{d:"M33.435 33.435L29.8995 29.8995M6.56497 33.435L10.1005 29.8995M6.56497 6.56497L10.1005 10.1005M33.435 6.56497L29.8995 10.1005",stroke:"#B2B5B2",strokeWidth:2,strokeLinecap:"round"})))},Oa=i.a.forwardRef((function(e,t){return i.a.createElement(ya,Ea({svgRef:t},e))})),xa=(a.p,a(1716)),wa=a(43),ja=a.n(wa),Ca=a(67),ka=["className"],Sa=Object(g.a)((function(){return{root:{display:"flex",flexDirection:"column"}}})),Na=function(e){var t=e.className,a=Object(Ca.a)(e,ka),n=Sa();return i.a.createElement("div",Object.assign({className:ja()(n.root,t)},a))},Ia=Object(g.a)((function(e){return{root:{padding:8,transition:"0.2s ease all",cursor:"pointer","&:hover":{background:"rgba(217, 212, 173, 0.15)"}},active:{borderColor:e.palette.common.white,background:"none",cursor:"initial","&::before":{borderColor:e.palette.common.white},"&:hover":{background:"none"}},spacing:{"& + &, &.sub":{marginTop:12}},moduleItem:{display:"grid",gridTemplateColumns:"48px 1fr",gridGap:e.spacing(2),backgroundColor:"transparent","&.sub":{zIndex:2}},content:{width:"100%",justifyContent:"center"},image:{paddingTop:2}}})),Ta=function(e){var t=e.active,a=e.sub,n=e.image,r=void 0===n?null:n,o=e.children,c=e.onClick,l=Ia();return i.a.createElement(h.c,{borderStyle:"double",className:ja()(l.root,l.spacing,Object(P.a)({sub:a},l.active,t))},i.a.createElement("div",{onClick:t?void 0:c,className:ja()(l.moduleItem,{active:t,sub:a})},i.a.createElement("div",{className:l.image},r),i.a.createElement(Na,{className:l.content},o)))},Aa=Object(g.a)((function(e){return{hashInfo:{display:"inline-flex !important",width:50,height:50,padding:e.spacing(.5),borderStyle:"solid",borderWidth:1,borderRadius:"50%",borderColor:"rgba(255, 255, 255, 0.2)",background:"rgba(224, 197, 173, 0.1)","& p":{fontSize:12,color:e.palette.text.primary+" !important"},"& .jLVlPg":{margin:0},"& .jLVlPg > p":{fontWeight:"bold",fontSize:14}}}})),Ra=function(e){var t=Aa();return i.a.createElement(m.EthHashInfo,Object.assign({className:t.hashInfo},e))},Ma=a(1715),Ba=a(41),Da=["className"],La=Object(g.a)((function(){return{root:{display:"flex",flexDirection:"row"}}})),Pa=function(e){var t=e.className,a=Object(Ca.a)(e,Da),n=La();return i.a.createElement("div",Object.assign({className:ja()(n.root,t)},a))},Fa=["secondary","children","className"],Ua=Object(g.a)((function(e){return{badge:{display:"inline-block",padding:e.spacing(.25,.5),lineHeight:1,whiteSpace:"nowrap",borderWidth:1,borderStyle:"solid",borderColor:"rgba(255, 255, 255, 0.2)"},primary:{backgroundColor:"rgba(224, 197, 173, 0.1)"},secondary:{backgroundColor:Object(Ba.a)(e.palette.primary.light,.4)}}})),Va=function(e){var t=e.secondary,a=e.children,n=e.className,r=Object(Ca.a)(e,Fa),o=Ua();return t?i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement("div",Object.assign({className:ja()(o.badge,o.primary,n)},r),a),i.a.createElement("div",Object.assign({className:ja()(o.badge,o.secondary,n)},r),t)):i.a.createElement("div",Object.assign({className:ja()(o.badge,o.primary,n)},r),a)},Ha=function(e){var t=e.address,a=e.className,n=function(e,t){var a=_(e);if(a){var n=t.length>42?"tx":"address";return function(){return{url:"".concat(a.url,"/").concat(n,"/").concat(t),alt:a.name}}}}(Object(p.useSafeAppsSDK)().safe.chainId,t);return n?i.a.createElement(m.ExplorerButton,{explorerUrl:n,className:a}):null};function _a(e){return e.substr(0,6)+"..."+e.substr(-4)}function Ga(e){if(e<60)return 1===e?"1 second":"".concat(e," second");if(e<3600){var t=Math.floor(e/60);return 1===t?"1 minute":"".concat(t," minute")}if(e<172800){var a=Math.floor(e/3600);return 1===a?"1 hour":"".concat(a," hour")}var n=Math.floor(e/86400);return"".concat(n," day")}var Wa,za=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.5),justifyContent:"start",alignItems:"center",minWidth:0,"& > *":{gridRow:1}},gutterBottom:{marginBottom:e.spacing(1)},showOnHover:{"& .btn":{visibility:"hidden"},"&:hover .btn":{visibility:"initial"}}}})),Ka=function(e){var t,a=e.address,n=e.short,r=void 0!==n&&n,o=e.hideCopyBtn,c=void 0!==o&&o,l=e.hideExplorerBtn,s=void 0!==l&&l,u=e.showOnHover,d=void 0!==u&&u,f=e.gutterBottom,p=void 0!==f&&f,b=e.classes,g=(b=void 0===b?{}:b).icon,h=b.container,E=e.TypographyProps,v=za();return i.a.createElement("div",{className:ja()(v.root,h,(t={},Object(P.a)(t,v.showOnHover,d),Object(P.a)(t,v.gutterBottom,p),t))},i.a.createElement(y.a,Object.assign({noWrap:!0},E),r?_a(a):a),c?null:i.a.createElement(m.CopyToClipboardBtn,{textToCopy:a,className:ja()(g,"btn")}),s?null:i.a.createElement(Ha,{address:a,className:ja()(g,"btn")}))},Ya=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer"}}})),Za=function(e){var t=e.module,a=Ya(),n=ba();return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(Va,null,Ga(t.cooldown)," delay"),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(e){e.stopPropagation(),n(qt(t)),n(Qt("write")),n(ia({func:"setTxCooldown(uint256)",params:[t.cooldown]}))}},"Change Delay")))},qa=a(23),Xa=Object(qa.a)((function(e){return{root:{color:e.palette.text.primary,textDecoration:"underline",transition:"opacity 0.25s ease-in-out","&:hover":{opacity:.6}}}}))(Ma.a),Qa=["image","linkText","title"],Ja=Object(g.a)((function(e){return{title:{marginBottom:e.spacing(.5),textTransform:"uppercase"},image:{width:50,height:50,display:"inline-flex !important",padding:e.spacing(.5),alignItems:"center",justifyContent:"center",borderStyle:"solid",borderWidth:1,borderRadius:"50%",borderColor:"rgba(255, 255, 255, 0.2)",background:"rgba(224, 197, 173, 0.1)"}}})),$a=function(e){var t=e.image,a=void 0===t?null:t,n=e.linkText,r=e.title,o=Object(Ca.a)(e,Qa),c=Ja(),l=Object(p.useSafeAppsSDK)().safe,s=_(l.chainId),u=s?"".concat(s.safeUrl).concat(l.safeAddress,"/transactions"):"";return i.a.createElement(Ta,Object.assign({image:i.a.createElement("div",{className:c.image},a)},o),i.a.createElement(y.a,{variant:"body2",className:c.title},r),i.a.createElement("div",null,i.a.createElement(Xa,{target:"_parent",href:u},n)))},en=["svgRef","title"];function tn(){return(tn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var nn,rn,on,cn=function(e){var t=e.svgRef,a=e.title,n=an(e,en);return i.a.createElement("svg",tn({width:34,height:34,viewBox:"0 0 34 34",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Wa||(Wa=i.a.createElement("path",{d:"M2 17C2 16.4477 1.55228 16 1 16C0.447715 16 0 16.4477 0 17H2ZM10.6248 1.2361C10.1129 1.44332 9.86584 2.02632 10.0731 2.53825C10.2803 3.05018 10.8633 3.2972 11.3752 3.08997L10.6248 1.2361ZM32 17C32 25.2843 25.2843 32 17 32V34C26.3888 34 34 26.3888 34 17H32ZM17 32C8.71573 32 2 25.2843 2 17H0C0 26.3888 7.61116 34 17 34V32ZM17 2C25.2843 2 32 8.71573 32 17H34C34 7.61116 26.3888 0 17 0V2ZM11.3752 3.08997C13.1109 2.38739 15.009 2 17 2V0C14.7474 0 12.5948 0.438641 10.6248 1.2361L11.3752 3.08997Z",fill:"#FFFFFF"})))},ln=i.a.forwardRef((function(e,t){return i.a.createElement(cn,tn({svgRef:t},e))})),sn=(a.p,Object(g.a)((function(e){return{root:{position:"relative",width:34,height:34},floating:{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center"},icon:{},rotate:{animationName:"$rotate",animationDuration:"2000ms",animationTimingFunction:"linear",animationIterationCount:"infinite"},"@keyframes rotate":{"0%":{transform:"rotate(0deg)"},"100%":{transform:"rotate(360deg)"}}}}))),un=function(e){var t=e.icon,a=sn();return i.a.createElement("div",{className:a.root},i.a.createElement("div",{className:a.floating},i.a.createElement(ln,{className:a.rotate})),i.a.createElement("div",{className:a.floating},t))},dn=["svgRef","title"];function fn(){return(fn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var pn,bn,gn,hn,En,vn,yn,On,xn,wn=function(e){var t=e.svgRef,a=e.title,n=mn(e,dn);return i.a.createElement("svg",fn({width:16,height:16,viewBox:"0 0 16 16",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,nn||(nn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M6.66667 12.0064C7.03533 12.0064 7.33333 11.7084 7.33333 11.3398V7.33976C7.33333 6.9711 7.03533 6.6731 6.66667 6.6731C6.298 6.6731 6 6.9711 6 7.33976V11.3398C6 11.7084 6.298 12.0064 6.66667 12.0064Z",fill:"#B2B5B2"})),rn||(rn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M9.33415 12.0064C9.70281 12.0064 10.0008 11.7084 10.0008 11.3398V7.33976C10.0008 6.9711 9.70281 6.6731 9.33415 6.6731C8.96548 6.6731 8.66748 6.9711 8.66748 7.33976V11.3398C8.66748 11.7084 8.96548 12.0064 9.33415 12.0064Z",fill:"#B2B5B2"})),on||(on=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.0085 13.034C10.9998 13.2033 10.8365 13.336 10.6771 13.3346H5.31245C5.15912 13.3173 5.00512 13.204 4.99645 13.0293L4.56445 5.33329H11.4225L11.0085 13.034ZM6.66439 3.07729C6.66439 2.85463 6.85306 2.66663 7.07572 2.66663H8.92105C9.14772 2.66663 9.33239 2.85129 9.33239 3.07729V3.99996H6.66439V3.07729ZM13.3328 3.99992H12.1742C12.1702 3.99992 12.1662 3.99659 12.1615 3.99659C12.1535 3.99592 12.1468 3.99992 12.1382 3.99992H10.6655V3.07725C10.6655 2.11592 9.88351 1.33325 8.92085 1.33325H7.07551C6.11351 1.33325 5.33085 2.11592 5.33085 3.07725V3.99992H2.66618C2.29818 3.99992 1.99951 4.29792 1.99951 4.66659C1.99951 5.03525 2.29818 5.33325 2.66618 5.33325H3.22951L3.66484 13.0979C3.70685 13.9713 4.43885 14.6686 5.29151 14.6686C5.30351 14.6686 5.31551 14.6679 5.32751 14.6679H10.6608H10.6988C11.5655 14.6679 12.2982 13.9719 12.3402 13.1026L12.7575 5.33325H13.3328C13.7015 5.33325 13.9995 5.03525 13.9995 4.66659C13.9995 4.29792 13.7015 3.99992 13.3328 3.99992Z",fill:"#B2B5B2"})))},jn=i.a.forwardRef((function(e,t){return i.a.createElement(wn,fn({svgRef:t},e))})),Cn=(a.p,["svgRef","title"]);function kn(){return(kn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Nn=function(e){var t=e.svgRef,a=e.title,n=Sn(e,Cn);return i.a.createElement("svg",kn({width:37,height:36,viewBox:"0 0 37 36",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,pn||(pn=i.a.createElement("circle",{cx:29,cy:4.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),bn||(bn=i.a.createElement("circle",{cx:4,cy:17.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),gn||(gn=i.a.createElement("circle",{cx:27,cy:31.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),hn||(hn=i.a.createElement("path",{d:"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833",stroke:"#FFFFFF",strokeWidth:2,strokeLinecap:"round"})),En||(En=i.a.createElement("path",{d:"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),vn||(vn=i.a.createElement("path",{d:"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),yn||(yn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M18.6667 22.0064C19.0353 22.0064 19.3333 21.7084 19.3333 21.3398V17.3398C19.3333 16.9711 19.0353 16.6731 18.6667 16.6731C18.298 16.6731 18 16.9711 18 17.3398V21.3398C18 21.7084 18.298 22.0064 18.6667 22.0064Z",fill:"#B2B5B2"})),On||(On=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M21.3341 22.0064C21.7028 22.0064 22.0008 21.7084 22.0008 21.3398V17.3398C22.0008 16.9711 21.7028 16.6731 21.3341 16.6731C20.9655 16.6731 20.6675 16.9711 20.6675 17.3398V21.3398C20.6675 21.7084 20.9655 22.0064 21.3341 22.0064Z",fill:"#B2B5B2"})),xn||(xn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M23.0085 23.0338C22.9998 23.2032 22.8365 23.3358 22.6771 23.3345H17.3125C17.1591 23.3172 17.0051 23.2038 16.9965 23.0292L16.5645 15.3332H23.4225L23.0085 23.0338ZM18.6644 13.0772C18.6644 12.8545 18.8531 12.6665 19.0757 12.6665H20.9211C21.1477 12.6665 21.3324 12.8512 21.3324 13.0772V13.9998H18.6644V13.0772ZM25.3328 13.9998H24.1742C24.1702 13.9998 24.1662 13.9965 24.1615 13.9965C24.1535 13.9958 24.1468 13.9998 24.1382 13.9998H22.6655V13.0771C22.6655 12.1158 21.8835 11.3331 20.9208 11.3331H19.0755C18.1135 11.3331 17.3308 12.1158 17.3308 13.0771V13.9998H14.6662C14.2982 13.9998 13.9995 14.2978 13.9995 14.6665C13.9995 15.0351 14.2982 15.3331 14.6662 15.3331H15.2295L15.6648 23.0978C15.7068 23.9711 16.4388 24.6685 17.2915 24.6685C17.3035 24.6685 17.3155 24.6678 17.3275 24.6678H22.6608H22.6988C23.5655 24.6678 24.2982 23.9718 24.3402 23.1025L24.7575 15.3331H25.3328C25.7015 15.3331 25.9995 15.0351 25.9995 14.6665C25.9995 14.2978 25.7015 13.9998 25.3328 13.9998Z",fill:"#B2B5B2"})))},In=i.a.forwardRef((function(e,t){return i.a.createElement(Nn,kn({svgRef:t},e))})),Tn=(a.p,["instant","module"]),An=function(e){var t=e.instant,a=e.module,n=Object(Ca.a)(e,Tn);return t?i.a.createElement($a,Object.assign({title:a.name||"",linkText:"Transaction confirming...",image:i.a.createElement(un,{icon:i.a.createElement(jn,null)})},n)):i.a.createElement($a,Object.assign({title:a.name||"",linkText:"Awaiting removal approval",image:i.a.createElement(In,null)},n))};function Rn(e,t){var a=Mn(e),n="/app/".concat(a,":").concat(e.safeAddress,"/apps"),r=new URLSearchParams({appUrl:t});return new URL("".concat("https://gnosis-safe.io").concat(n,"?").concat(r)).href}function Mn(e){return V[e.chainId].shortName}var Bn,Dn,Ln=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer",textUnderlineOffset:"2px","&:hover":{opacity:.5}}}})),Pn=function(e){var t=e.module,a=Ln(),n=Object(p.useSafeAppsSDK)().safe;return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Pa,{style:{justifyContent:"space-between"}},i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(){window.location.href=function(e,t){var a=Mn(e);return new URL("".concat("https://roles-v1.gnosisguild.org","/#/").concat(a,":").concat(t)).href}(n,t.address)},underline:"always"},"Edit Roles")))},Fn=Object(g.a)((function(e){return{root:{display:"grid",gridGap:e.spacing(.25),"& > *":{gridColumn:1}},text:{lineHeight:1,letterSpacing:1},moduleName:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},link:{marginLeft:e.spacing(1),lineHeight:1,cursor:"pointer",textUnderlineOffset:"2px","&:hover":{opacity:.5}}}})),Un=function(e){var t=e.module,a=Fn(),n=Object(p.useSafeAppsSDK)().safe;return i.a.createElement("div",{className:a.root},i.a.createElement(y.a,{variant:"body2",className:a.moduleName},t.name),i.a.createElement(Pa,{style:{justifyContent:"space-between"}},i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),i.a.createElement(Ma.a,{color:"textPrimary",noWrap:!0,className:a.link,onClick:function(){window.location.href=function(e,t){var a=Mn(e);return new URL("".concat("https://roles.gnosisguild.org","/").concat(a,":").concat(t)).href}(n,t.address)},underline:"always"},"View Roles")))},Vn=["module","classes"],Hn=["module","remove","instant","onClick"],_n=Object(g.a)((function(e){return{text:{lineHeight:1,letterSpacing:"1px"},name:{textTransform:"uppercase"},address:{fontFamily:"Roboto Mono"},badge:{marginTop:e.spacing(1)},content:{display:"flex",flexDirection:"column",justifyContent:"center",height:56}}})),Gn=function(e){var t=e.module,a=e.classes,n=Object(Ca.a)(e,Vn),r=Object(p.useSafeAppsSDK)().safe;if(mt(t))return i.a.createElement(Za,Object.assign({module:t},n));if(t.type===Fe.ROLES_V1)return i.a.createElement(Pn,Object.assign({module:t,chainId:r.chainId},n));if(t.type===Fe.ROLES_V2)return i.a.createElement(Un,Object.assign({module:t,chainId:r.chainId},n));var o=t.owner&&t.owner!==r.safeAddress?i.a.createElement(Va,{secondary:_a(t.owner),className:a.badge},"External Owner"):null;return i.a.createElement(i.a.Fragment,null,t.name?i.a.createElement(y.a,{variant:"body2",className:a.name},t.name):null,i.a.createElement(Ka,{short:!0,showOnHover:!0,address:t.address,TypographyProps:{variant:"body2",className:a.address}}),o)},Wn=function(e){var t=e.module,a=e.remove,n=void 0!==a&&a,r=e.instant,o=void 0!==r&&r,c=e.onClick,l=Object(Ca.a)(e,Hn),s=_n();return n?i.a.createElement(An,Object.assign({module:t,instant:o,onClick:c},l)):i.a.createElement(Ta,Object.assign({image:i.a.createElement(Ra,{showAvatar:!0,avatarSize:"lg",showHash:!1,hash:t.address})},l),i.a.createElement("div",{onClick:c,className:s.content},i.a.createElement(Gn,Object.assign({classes:s},e))),t.subModules.length?i.a.createElement(yr,{sub:!0,modules:t.subModules}):null)},zn=["svgRef","title"];function Kn(){return(Kn=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Zn,qn,Xn,Qn,Jn,$n,er,tr,ar=function(e){var t=e.svgRef,a=e.title,n=Yn(e,zn);return i.a.createElement("svg",Kn({width:16,height:17,viewBox:"0 0 16 17",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Bn||(Bn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M14.6668 8.49992C14.6668 12.1818 11.6821 15.1666 8.00016 15.1666C4.31826 15.1666 1.3335 12.1818 1.3335 8.49992C1.3335 4.81802 4.31826 1.83325 8.00016 1.83325C11.6821 1.83325 14.6668 4.81802 14.6668 8.49992ZM2.66667 8.49988C2.66667 11.4454 5.05448 13.8332 8 13.8332C10.9455 13.8332 13.3333 11.4454 13.3333 8.49988C13.3333 5.55436 10.9455 3.16654 8 3.16654C5.05448 3.16654 2.66667 5.55436 2.66667 8.49988Z",fill:"#B2B5B2"})),Dn||(Dn=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.6665 7.83341H10.6665C11.0347 7.83341 11.3332 8.13189 11.3332 8.50008C11.3332 8.86827 11.0347 9.16675 10.6665 9.16675H8.6665V11.1667C8.6665 11.5349 8.36803 11.8334 7.99984 11.8334C7.63165 11.8334 7.33317 11.5349 7.33317 11.1667V9.16675H5.33317C4.96498 9.16675 4.6665 8.86827 4.6665 8.50008C4.6665 8.13189 4.96498 7.83341 5.33317 7.83341H7.33317V5.83341C7.33317 5.46522 7.63165 5.16675 7.99984 5.16675C8.36803 5.16675 8.6665 5.46522 8.6665 5.83341V7.83341Z",fill:"#B2B5B2"})))},nr=i.a.forwardRef((function(e,t){return i.a.createElement(ar,Kn({svgRef:t},e))})),rr=(a.p,["svgRef","title"]);function or(){return(or=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var ir,lr=function(e){var t=e.svgRef,a=e.title,n=cr(e,rr);return i.a.createElement("svg",or({width:37,height:36,viewBox:"0 0 37 36",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Zn||(Zn=i.a.createElement("circle",{cx:29,cy:4.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),qn||(qn=i.a.createElement("circle",{cx:4,cy:17.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),Xn||(Xn=i.a.createElement("circle",{cx:27,cy:31.5,r:3,stroke:"#B2B5B2",strokeWidth:2})),Qn||(Qn=i.a.createElement("path",{d:"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833",stroke:"#FFFFFF",strokeWidth:2,strokeLinecap:"round"})),Jn||(Jn=i.a.createElement("path",{d:"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),$n||($n=i.a.createElement("path",{d:"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461",stroke:"#B2B5B2",strokeOpacity:.3,strokeWidth:2,strokeLinecap:"round"})),er||(er=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M26.6668 17.5C26.6668 21.1819 23.6821 24.1667 20.0002 24.1667C16.3183 24.1667 13.3335 21.1819 13.3335 17.5C13.3335 13.8181 16.3183 10.8334 20.0002 10.8334C23.6821 10.8334 26.6668 13.8181 26.6668 17.5ZM14.6667 17.5C14.6667 20.4455 17.0545 22.8333 20 22.8333C22.9455 22.8333 25.3333 20.4455 25.3333 17.5C25.3333 14.5545 22.9455 12.1667 20 12.1667C17.0545 12.1667 14.6667 14.5545 14.6667 17.5Z",fill:"#B2B5B2"})),tr||(tr=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M20.6665 16.8333H22.6665C23.0347 16.8333 23.3332 17.1318 23.3332 17.5C23.3332 17.8681 23.0347 18.1666 22.6665 18.1666H20.6665V20.1666C20.6665 20.5348 20.368 20.8333 19.9998 20.8333C19.6316 20.8333 19.3332 20.5348 19.3332 20.1666V18.1666H17.3332C16.965 18.1666 16.6665 17.8681 16.6665 17.5C16.6665 17.1318 16.965 16.8333 17.3332 16.8333H19.3332V14.8333C19.3332 14.4651 19.6316 14.1666 19.9998 14.1666C20.368 14.1666 20.6665 14.4651 20.6665 14.8333V16.8333Z",fill:"#B2B5B2"})))},sr=i.a.forwardRef((function(e,t){return i.a.createElement(lr,or({svgRef:t},e))})),ur=(a.p,a(746)),dr=function(){var e=Object(p.useSafeAppsSDK)(),t=e.sdk,a=e.safe,n=Object(c.useMemo)((function(){return new I.ethers.providers.Web3Provider(new ur.SafeAppProvider(a,t))}),[t,a]);return{sdk:t,safe:a,provider:n}},fr=function(){var e=dr(),t=e.sdk,a=e.safe,n=e.provider,r=ba(),o=ga(Ht),l=ga(Pt),s=ga(Ft),u=1===ga(Vt);Object(c.useEffect)((function(){r(Kt(a))}),[r,a]),Object(c.useEffect)((function(){if(u&&l.length){var e=setInterval((function(){return r(Kt(a))}),3e3);return function(){clearInterval(e),r(zt({provider:n,safeSDK:t,chainId:a.chainId,safeAddress:a.safeAddress}))}}}),[r,u,t,a,l.length,n]);var d=u?i.a.createElement(un,{icon:i.a.createElement(nr,null)}):i.a.createElement(sr,{style:{marginLeft:-4}}),f=u?"Transaction confirming...":"Awaiting approval";return i.a.createElement(i.a.Fragment,null,s.map((function(e,t){var a={key:t,instant:u,onClick:function(){return r(Jt(e))},active:(null===o||void 0===o?void 0:o.address)===e.address},n=Ze(e.module),c=Tt(null===n||void 0===n?void 0:n.type);return i.a.createElement($a,Object.assign({title:c,linkText:f,image:d},a))})))},mr=["svgRef","title"];function pr(){return(pr=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var gr,hr=function(e){var t=e.svgRef,a=e.title,n=br(e,mr);return i.a.createElement("svg",pr({width:30,height:7,viewBox:"0 0 30 7",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,ir||(ir=i.a.createElement("path",{d:"M1.28906 1.69727C5.32916 3.95696 10.0897 5.26087 15.1864 5.26087C20.283 5.26087 25.0436 3.95696 29.0837 1.69727",strokeWidth:2})))},Er=i.a.forwardRef((function(e,t){return i.a.createElement(hr,pr({svgRef:t},e))})),vr=(a.p,Object(g.a)((function(e){return{subModules:{position:"relative"},line:{position:"absolute",borderColor:"#6d6b5a",borderStyle:"solid",borderBottomWidth:2,borderLeftWidth:2,borderTopWidth:0,borderRightWidth:0,borderBottomLeftRadius:16,top:6,left:-40,width:32},moduleStackIcon:{position:"absolute",top:0,left:-54,zIndex:100,stroke:"#6d6b5a"},emptyModulesText:{maxWidth:200},emptyImage:{border:"1px solid rgba(255,255,255,0.2)",borderRadius:"50%",padding:e.spacing(.5)}}}))),yr=function(e){var t=e.modules,a=e.sub,n=void 0!==a&&a,r=vr(),o=dr(),l=o.safe,s=o.sdk,u=o.provider,d=ba(),f=ga(At),m=ga(Bt),p=ga(Pt),b=ga(Vt),g=ga(Ut),h=i.a.useState(null),E=Object(x.a)(h,2),v=E[0],O=E[1];if(Object(c.useEffect)((function(){if(null==v){var e=function(){d(zt({provider:u,safeSDK:s,chainId:l.chainId,safeAddress:l.safeAddress}))},t=setInterval(e,1e4);O(t),e()}return function(){null!=v&&clearInterval(v)}}),[s,d,l,v,u]),m)return i.a.createElement(Ta,{image:i.a.createElement(xa.a,{variant:"circle",width:50,height:50})},i.a.createElement(xa.a,{width:160,height:20}),i.a.createElement(xa.a,{width:100,height:20}));if(!t.length&&!p.length)return i.a.createElement(Ta,{image:i.a.createElement(Oa,{className:r.emptyImage,height:50,width:50})},i.a.createElement(y.a,{className:r.emptyModulesText},"Modules will appear here once added"));var w=t.map((function(e){var t=e.id===(null===f||void 0===f?void 0:f.id),a=g.some((function(t){return function(e,t){return t.address===e.address&&t.executor===e.parentModule}(e,t)}));return i.a.createElement(Wn,{key:e.address,remove:a,instant:1===b,module:e,active:t,sub:n,onClick:function(){return function(e){d(qt(e)),d(la())}(e)}})}));if(n){var j=t.map((function(e,a){var n=a&&t[a-1],o=1+74*(n&&n.subModules.length)+74*(a+1)+12*a-37+6;return i.a.createElement("div",{key:a,className:r.line,style:{height:o}})})),C=t.length?i.a.createElement(Er,{className:r.moduleStackIcon}):null;return i.a.createElement("div",{className:r.subModules},w,C,j)}return i.a.createElement(Na,null,i.a.createElement(fr,null),w)},Or=function(){return i.a.createElement("div",{style:{flexGrow:1}})},xr=["svgRef","title"];function wr(){return(wr=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Cr=function(e){var t=e.svgRef,a=e.title,n=jr(e,xr);return i.a.createElement("svg",wr({width:13,height:12,viewBox:"0 0 13 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,gr||(gr=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M7.22344 4.8H10.8234C11.4862 4.8 12.0234 5.33726 12.0234 6C12.0234 6.66274 11.4862 7.2 10.8234 7.2H7.22344V10.8C7.22344 11.4627 6.68618 12 6.02344 12C5.3607 12 4.82344 11.4627 4.82344 10.8V7.2H1.22344C0.560696 7.2 0.0234375 6.66274 0.0234375 6C0.0234375 5.33726 0.560696 4.8 1.22344 4.8H4.82344V1.2C4.82344 0.537258 5.3607 0 6.02344 0C6.68618 0 7.22344 0.537258 7.22344 1.2V4.8Z",fill:"white"})))},kr=i.a.forwardRef((function(e,t){return i.a.createElement(Cr,wr({svgRef:t},e))})),Sr=(a.p,Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},hashInfo:{"& p":{color:e.palette.text.primary+" !important"}},header:{padding:e.spacing(0,1,2,1),boxSizing:"content-box",minHeight:40,alignItems:"center"},moduleList:{marginTop:e.spacing(3)}}}))),Nr=function(){var e=Sr(),t=ba(),a=ga(Rt),n=ga(At),r=ga(Ht);return i.a.createElement("div",{className:e.root},i.a.createElement(Pa,{className:e.header},i.a.createElement(y.a,{variant:"h5"},"Modules and Modifiers"),i.a.createElement(Or,null),n||r?i.a.createElement(O.a,{size:"small",disableRipple:!0,color:"secondary",variant:"contained",onClick:function(){t(Xt())},startIcon:i.a.createElement(kr,null)},"Add"):null),i.a.createElement(yr,{modules:a}))},Ir=["classes","className"],Tr=Object(g.a)((function(e){return{icon:{color:e.palette.secondary.main},queryButton:{textTransform:"none",fontSize:16,"&.MuiButton-contained.Mui-disabled":{backgroundColor:e.palette.secondary.main,color:e.palette.common.white},"&.MuiButton-outlinedSecondary.Mui-disabled":{color:e.palette.common.white,borderColor:e.palette.common.white}},buttonDisabled:{opacity:.5},outlined:{color:e.palette.common.white,padding:e.spacing(.75,2),borderColor:"rgba(217, 212, 173, 0.3)",transition:"0.2s ease all","&::before":{borderColor:"rgba(217, 212, 173, 0.3)"},"&:hover":{background:"rgba(217, 212, 173, 0.15)",borderColor:"rgba(217, 212, 173, 0.3)"}}}})),Ar=function(e){var t=e.classes,a=e.className,n=Object(Ca.a)(e,Ir),r=Tr();return i.a.createElement(O.a,Object.assign({color:"secondary",variant:"contained",classes:Object(N.a)({disabled:r.buttonDisabled,outlined:r.outlined},t),disableRipple:!0,className:ja()(r.queryButton,a)},n))};function Rr(e){return Object(N.a)(Object(N.a)({},e),{},{func:e.func.format("full")})}function Mr(e){var t=new R.b([e.func]);return Object(N.a)(Object(N.a)({},e),{},{func:Ve.f.from(t.fragments[0])})}function Br(e){return"remove_".concat(e.address,"_").concat(e.parentModule)}function Dr(e){return e.transactionBuilder.addTransaction}function Lr(e){return e.transactionBuilder.transactions.map(Mr)}function Pr(e){return e.transactionBuilder.open}var Fr,Ur=Object(g.a)((function(e){return{header:{minHeight:88,display:"flex",flexDirection:"row",alignItems:"center",padding:e.spacing(3)},text:{marginLeft:"16px !important",color:e.palette.text.primary+" !important"},addressType:{fontSize:".75rem",fontFamily:"Roboto Mono"},spacing:{marginLeft:e.spacing(2)},removeButton:{}}})),Vr=function(e){var t=e.module,a=Ur(),n=ba(),r=dr(),o=r.safe,c=r.provider,l=ga(Ut),s=ga(Lr).some((function(e){return e.id===Br(t)})),u=l.map((function(e){return e.address})).includes(t.address),d=s||u,f=function(){var e=Object(k.a)(C.a.mark((function e(){var a,r,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,Ce(c,t.parentModule,o.chainId,t.address);case 3:a=e.sent,r=a.params,i=new R.b(B.a),l=i.getFunction("disableModule"),s={module:t,params:r,id:Br(t),func:l,to:t.parentModule},n(ua(Rr(s))),n(oa()),e.next=15;break;case 12:e.prev=12,e.t0=e.catch(0),console.warn("could not remove module",e.t0);case 15:case"end":return e.stop()}}),e,null,[[0,12]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement("div",{className:a.header},i.a.createElement(Ra,{showAvatar:!0,showHash:!1,avatarSize:"lg",hash:t.address}),i.a.createElement(Ka,{short:!0,address:t.address,classes:{container:a.spacing,icon:a.spacing},TypographyProps:{classes:{root:a.addressType}}}),i.a.createElement(Or,null),i.a.createElement(Ar,{disableElevation:!0,className:a.removeButton,variant:"outlined",onClick:f,disabled:d,startIcon:i.a.createElement(jn,null)},"Remove"))},Hr=["open","content","children","className","containerClassName"],_r=Object(g.a)((function(e){return{root:{padding:e.spacing(2),transition:"0.2s ease all","& + &":{marginTop:e.spacing(2)},"&:hover":{background:"rgba(217, 212, 173, 0.15)"}},content:{marginTop:e.spacing(2)},hide:{display:"none"}}})),Gr=function(e){var t=e.open,a=void 0!==t&&t,n=e.content,r=e.children,o=e.className,c=e.containerClassName,l=Object(Ca.a)(e,Hr),s=_r();return i.a.createElement(h.c,Object.assign({},l,{borderStyle:"double",className:ja()(s.root,o)}),r,n?i.a.createElement("div",{className:ja()(s.content,c,Object(P.a)({},s.hide,!a))},n):null)},Wr=function(e){var t=e.defaultParams,a=e.func,n=e.children,r=Object(c.useRef)(a.inputs.map((function(e,a){return{value:t&&void 0!==t[a]?t[a]:"",valid:!0}}))),o=function(){return function(e,t){try{return He.b.encode(e.inputs,t),!0}catch(a){return!1}}(a,r.current.map((function(e){return e.value})))},i=Object(c.useState)(o()),l=Object(x.a)(i,2),s=l[0],u=l[1];return n({paramInputProps:a.inputs.map((function(e,t){return{param:e,value:r.current[t].value,onChange:function(e,a){!function(e,t,a){r.current[e]={value:t,valid:a};var n=r.current.every((function(e){return e.valid}));u(n&&o())}(t,e,a)}}})),getParams:function(){return r.current.map((function(e){return e.value}))},areParamsValid:s})},zr=Object(g.a)((function(e){return{root:{color:e.palette.common.white,fontFamily:"Roboto Mono",fontSize:12,padding:e.spacing(2)},item:{"& + &":{marginTop:e.spacing(1)}},label:{color:"rgba(217, 212, 173, 0.9)"},value:{overflowWrap:"break-word"}}})),Kr=function(e){var t,a=e.func,n=e.loading,r=void 0!==n&&n,o=e.result,c=zr();return r?i.a.createElement(xa.a,{variant:"rect",height:50}):o?i.a.createElement(h.c,{className:c.root},null===(t=a.outputs)||void 0===t?void 0:t.map((function(e,t){return i.a.createElement("div",{key:t,className:c.item},i.a.createElement("span",{className:c.label},e.name?"".concat(e.name," (").concat(e.type,")"):e.type,":"," "),i.a.createElement("span",{className:c.value},dt(e.baseType,o[t])))}))):null},Yr=a(756),Zr=Object(g.a)((function(e){return{spaceLeft:{marginLeft:e.spacing(1)},type:{fontFamily:"Roboto Mono",fontSize:".75rem"},queryType:{fontSize:".75rem"}}})),qr=function(e){var t=e.date,a=e.func,n=e.result,r=e.showResult,o=e.loading,c=void 0!==o&&o,l=Zr();if(c)return i.a.createElement(xa.a,{variant:"text",width:300});if(r&&n&&n.length&&a.outputs){var s=a.outputs[0],u=s.baseType,d=s.type,f=dt(u,n[0]);return"address"===u?i.a.createElement(Ka,{address:f,TypographyProps:{classes:{root:l.type}}}):i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"subtitle1",className:l.type},"(",d,")"),i.a.createElement(y.a,{noWrap:!0,className:ja()(l.spaceLeft,l.type)},f),i.a.createElement(m.CopyToClipboardBtn,{textToCopy:f,className:l.spaceLeft}))}return t?i.a.createElement(y.a,{className:l.queryType},"Queried ",i.a.createElement(Yr.a,{datetime:t})):i.a.createElement(y.a,{className:l.queryType},"Query")},Xr=Object(g.a)((function(e){return{root:{fontSize:12,padding:e.spacing(2),marginBottom:e.spacing(2),color:e.palette.error.main,borderRadius:e.shape.borderRadius,borderColor:e.palette.error.main,borderStyle:"solid",borderWidth:2,wordWrap:"break-word"}}})),Qr=function(e){var t=e.error,a=Xr();return t?i.a.createElement("div",{className:a.root},t):null},Jr=["svgRef","title"];function $r(){return($r=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var to=function(e){var t=e.svgRef,a=e.title,n=eo(e,Jr);return i.a.createElement("svg",$r({width:21,height:20,viewBox:"0 0 21 20",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Fr||(Fr=i.a.createElement("path",{d:"M15.2111 9.10557L8.44721 5.72361C7.78231 5.39116 7 5.87465 7 6.61803L7 13.382C7 14.1253 7.78231 14.6088 8.44722 14.2764L15.2111 10.8944C15.9482 10.5259 15.9482 9.4741 15.2111 9.10557Z",fill:"#FFFFFF"})))},ao=i.a.forwardRef((function(e,t){return i.a.createElement(to,$r({svgRef:t},e))})),no=(a.p,["param","value","onChange"]);function ro(e){return e.name?"".concat(e.name," (").concat(e.type,")"):"(".concat(e.type,")")}var oo,co=function(e){var t=e.param,a=e.value,n=e.onChange,r=Object(Ca.a)(e,no);if(null!=r.defaultValue)throw new Error("This is a controlled component, `defaultValue` should not be used. Use `value` instead.");var o=Object(c.useState)(function(e,t){return void 0!==t?"object"===typeof t?JSON.stringify(t):t.toString():"boolean"===e.baseType?"false":""}(t,a)),l=Object(x.a)(o,2),s=l[0],u=l[1],d=Object(c.useState)(),f=Object(x.a)(d,2),m=f[0],p=f[1],b=function(e){var a=e.target.value;if(u(a),"boolean"!==t.baseType){if(!a.length)return n(a,!1),void p(void 0);try{var r=it(t,a);n(r,!0),p(void 0)}catch(m){n(a,!1),p(null===m||void 0===m?void 0:m.message)}}else n("true"===a,!0)};return"boolean"===t.baseType?i.a.createElement(h.e,Object.assign({select:!0,color:"secondary",label:ro(t),value:s,onChange:b},r),i.a.createElement(Q.a,{value:"true"},"True"),i.a.createElement(Q.a,{value:"false"},"False")):i.a.createElement(h.e,Object.assign({color:"secondary",label:ro(t),value:s,onChange:b,error:!!m,helperText:m},r))},io=["svgRef","title"];function lo(){return(lo=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var uo=function(e){var t=e.svgRef,a=e.title,n=so(e,io);return i.a.createElement("svg",lo({width:18,height:10,viewBox:"0 0 18 10",ref:t},n),a?i.a.createElement("title",null,a):null,oo||(oo=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0651 9.58417C9.77258 9.86274 9.38708 10.0013 9.00008 9.99992C8.61458 10.0013 8.22908 9.86274 7.93658 9.58417C7.93058 9.57846 7.87208 9.51846 7.86608 9.51274L0.439578 2.43703C-0.143922 1.88132 -0.143922 0.972744 0.439578 0.41703C1.02308 -0.138684 1.97708 -0.138684 2.56058 0.41703L9.00008 6.55132L15.4411 0.41703C16.0246 -0.138684 16.9786 -0.138684 17.5621 0.41703C18.1456 0.972744 18.1456 1.88132 17.5621 2.43703L10.1461 9.49846C10.1401 9.50417 10.0711 9.57846 10.0651 9.58417Z"})))},fo=i.a.forwardRef((function(e,t){return i.a.createElement(uo,lo({svgRef:t},e))})),mo=(a.p,["up","className"]),po=Object(g.a)((function(e){return{arrowIcon:{cursor:"pointer",color:e.palette.primary.main,fill:"#B2B5B2",width:18,height:10,"&.rotate":{transform:"rotate(180deg)"}}}})),bo=function(e){var t=e.up,a=void 0!==t&&t,n=e.className,r=Object(Ca.a)(e,mo),o=po();return i.a.createElement(fo,Object.assign({className:ja()(o.arrowIcon,{rotate:a},n)},r))},go=Object(g.a)((function(e){return{clickable:{cursor:"pointer"},expandIcon:{marginLeft:e.spacing(2)},icon:{color:e.palette.common.white},queryButton:{marginTop:e.spacing(2)},title:{marginRight:e.spacing(1)}}})),ho=function(e){var t=e.address,a=e.func,n=go(),r=ga(Mt),o=dr(),l=o.safe,s=o.provider,u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)(),b=Object(x.a)(p,2),g=b[0],h=b[1],E=function(){var e=Object(c.useState)(!1),t=Object(x.a)(e,2),a=t[0],n=t[1],r=Object(c.useState)(),o=Object(x.a)(r,2),i=o[0],l=o[1],s=Object(c.useState)(),u=Object(x.a)(s,2),d=u[0],f=u[1];return{loading:a,error:d,result:i,fetch:Object(c.useCallback)((function(){n(!0),l(void 0),Se.apply(void 0,arguments).then((function(e){l(e),f(void 0)})).catch((function(e){f(e.message),l(void 0)})).finally((function(){return n(!1)}))}),[])}}(),v=E.loading,O=E.result,w=E.fetch,j=E.error,C=ot(a),k=ct(a),S=k&&a.outputs?a.outputs[0].baseType:"",N=void 0!==O&&k?dt(S,O[0]).length:0,I=Object(c.useCallback)((function(e){h(void 0),w(s,l.chainId,t,[a],a.name,e)}),[t,w,a,l.chainId,s]);Object(c.useEffect)((function(){!v&&O&&h(new Date)}),[v,O]),Object(c.useEffect)((function(){C&&I()}),[I,C,r]);var T=k&&N<60&&!j,A=!T||!C,R=i.a.createElement(i.a.Fragment,null,i.a.createElement(Qr,{error:j}),T?null:i.a.createElement(Kr,{loading:v,func:a,result:O}),i.a.createElement(Wr,{func:a},(function(e){var t=e.paramInputProps,a=e.areParamsValid,r=e.getParams;return i.a.createElement(i.a.Fragment,null,t.map((function(e,t){return i.a.createElement(J.a,{marginTop:2,key:t},i.a.createElement(co,e))})),t.length?i.a.createElement(Ar,{fullWidth:!0,disabled:!a,className:n.queryButton,onClick:function(){return I(r())},startIcon:i.a.createElement(ao,{className:n.icon})},"Run Query"):null)})));return i.a.createElement(Gr,{open:f&&A,content:R},i.a.createElement(Pa,{style:{alignItems:"center"},className:ja()(Object(P.a)({},n.clickable,A)),onClick:function(){return m(!f)}},i.a.createElement(y.a,{className:n.title},a.name),i.a.createElement(Or,null),i.a.createElement(qr,{func:a,result:O,loading:v,date:g,showResult:T}),A?i.a.createElement(bo,{up:f,className:n.expandIcon}):null))},Eo=Object(g.a)((function(e){return{root:{opacity:.5},expandIcon:{marginLeft:e.spacing(2)},icon:{color:e.palette.secondary.main},title:{marginRight:e.spacing(1)}}}));function vo(e){if(!ct(e)||!e.outputs)return"";var t=e.outputs[0].baseType;return t.includes("int")?"0":"bool"===t?"true":"0x0000000000000000000000000000000000000000"}var yo=function(e){var t=e.func,a=Eo(),n=ot(t),r=ct(t),o=n&&r;return i.a.createElement(Gr,{className:a.root},i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(y.a,{className:a.title},t.name),i.a.createElement(Or,null),i.a.createElement(qr,{func:t,showResult:o,result:o?[vo(t)]:void 0}),o?null:i.a.createElement(bo,{className:a.expandIcon})))},Oo=function(e){var t=e.abi,a=e.address,n=e.preview,r=Object(c.useMemo)((function(){return function(e){return(e instanceof R.b?e:new R.b(e)).fragments.filter(Ve.f.isFunctionFragment).map(Ve.f.from).filter(nt)}(t)}),[t]);return i.a.createElement(i.a.Fragment,null,r.map((function(e){return n?i.a.createElement(yo,{key:e.name,func:e}):i.a.createElement(ho,{key:e.name,address:a,func:e})})))},xo=a(505),wo=a(504),jo=a(384),Co=a(378),ko=a.n(Co),So=["InputProps","InputLabelProps","label","append","variantAppend","AppendProps","tooltipMsg"],No=Object(qa.a)((function(e){return{root:{"& label.Mui-focused":{position:"relative",transform:"none",color:e.palette.text.primary,marginBottom:e.spacing(1)},"& .MuiInputBase-root":{marginTop:0,minHeight:"37px"},"& .MuiSelect-select:focus":{backgroundColor:"transparent"}}}}))(xo.a),Io=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:"4px"},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},icon:{fontSize:"1rem"},append:{display:"flex",alignItems:"center",padding:e.spacing(1),borderWidth:1,borderStyle:"solid",borderLeftWidth:0},primary:{borderColor:e.palette.primary.light},secondary:{borderColor:h.f.tan[300]},error:{background:"rgba(244, 67, 54, 0.1)",border:"1px solid rgba(244, 67, 54, 0.3)"}}})),To=function(e){var t=e.InputProps,a=e.InputLabelProps,n=e.label,r=e.append,o=e.variantAppend,c=e.AppendProps,l=e.tooltipMsg,s=Object(Ca.a)(e,So),u=Io();return s.select||!r?i.a.createElement(No,Object.assign({focused:!s.disabled,label:n,placeholder:n,InputProps:Object(N.a)({disableUnderline:!0},t),InputLabelProps:Object(N.a)({shrink:!0},a)},s)):i.a.createElement("div",null,i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Z.a,Object.assign({},a,{className:u.label}),n)),l&&i.a.createElement(q.a,{item:!0},i.a.createElement(wo.a,{title:l},i.a.createElement(ko.a,{className:u.icon})))),i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,className:u.inputContainer},i.a.createElement(jo.a,Object.assign({disabled:s.disabled,placeholder:s.placeholder,onClick:s.onClick,inputMode:s.inputMode,value:s.value,onChange:s.onChange},t,{className:ja()(u.input,null===t||void 0===t?void 0:t.className)}))),i.a.createElement(q.a,Object.assign({item:!0,xs:8},c,{className:ja()("".concat(u.append," ").concat(function(){switch(o){case"primary":return u.primary;case"secondary":return u.secondary;case"error":return u.error}}()),null===c||void 0===c?void 0:c.className)}),r)))},Ao=function(e){var t=Object(c.useState)(!1),a=Object(x.a)(t,2),n=a[0],r=a[1];function o(t){t.key===e&&r(!0)}var i=function(t){t.key===e&&r(!1)};return Object(c.useEffect)((function(){return window.addEventListener("keydown",o),window.addEventListener("keyup",i),function(){window.removeEventListener("keydown",o),window.removeEventListener("keyup",i)}}),[]),n},Ro=a(129),Mo=a.n(Ro),Bo=a(379),Do=a.n(Bo),Lo={seconds:1,minutes:60,hours:3600,days:86400,months:2592e3},Po=Object(g.a)((function(e){return{select:{padding:0,border:0,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"120px"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1},primary:{borderColor:e.palette.primary.light},secondary:{borderColor:h.f.tan[300]},error:{background:"rgba(244, 67, 54, 0.1)",borderColor:"rgba(244, 67, 54, 0.3)"},errorIcon:{fill:"rgba(244, 67, 54, 1)"}}}));function Fo(e,t){return T.a.from(e).mul(Lo[t])}var Uo,Vo=function(e){var t=e.onChange,a=e.defaultUnit,n=void 0===a?"hours":a,r=e.defaultValue,o=void 0===r?"0":r,l=e.value,s=e.valueUnit,u=e.label,d=e.variant,f=void 0===d?"primary":d,m=e.tooltipMsg,p=e.alertType,b=Po(),g=Ao("Tab"),h=Object(c.useState)(n),E=Object(x.a)(h,2),v=E[0],y=E[1],O=Object(c.useState)(T.a.from(o).div(Lo[v]).toString()),w=Object(x.a)(O,2),j=w[0],C=w[1],k=Object(c.useState)(!1),S=Object(x.a)(k,2),N=S[0],I=S[1],A=function(){return I(!1)},R=function(){return I(!0)},M=i.a.useRef(null),B=function(e){try{var a=Fo(e||"0",v);C(e),t(a.toString(),v)}catch(n){console.warn("invalid time")}},D=function(e){A(),y(e),j&&t(Fo(j,e).toString(),e)};return Object(c.useEffect)((function(){g&&N&&A()}),[g,N]),Object(c.useEffect)((function(){M.current&&M.current.addEventListener("keyup",(function(e){"Tab"===e.code&&R()}))}),[M]),Object(c.useEffect)((function(){if(l&&s){var e=T.a.from(l).div(Lo[s]).toString();e!==j&&C(e),["hours","days"].includes(v)&&s!==v&&y(s)}}),[l,s,j,v]),i.a.createElement(To,{label:u,variantAppend:f,tooltipMsg:m,InputProps:{value:j,placeholder:"24",classes:{root:function(){switch(f){case"primary":return b.primary;case"secondary":return b.secondary;case"error":return b.error}}()},onChange:function(e){return B(e.target.value)},startAdornment:function(){if(p)switch(p){case"error":return i.a.createElement(Mo.a,{className:b.errorIcon});case"warning":return i.a.createElement(Do.a,{className:b.errorIcon})}return null}()},AppendProps:{className:b.dropdownContainer},append:i.a.createElement(X.a,{disableUnderline:!0,open:N,value:v,ref:M,onOpen:R,onClose:A,className:"".concat(b.select," ").concat("primary"===f?b.primary:b.secondary),MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:b.dropdown,list:b.itemList}},renderValue:function(e){return e},onChange:function(e){return D(e.target.value)}},Object.keys(Lo).map((function(e){return i.a.createElement(Q.a,{key:e,value:e,className:b.item},e,i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"}))})))})},Ho=["label","value","onChange"],_o=function(e){var t=e.param,a=e.func;if(1===a.inputs.length){var n=Object(x.a)(a.inputs,1)[0];if(["setTxCooldown","setTxExpiration"].includes(a.name)&&n.type.includes("int"))return i.a.createElement(Go,t)}return i.a.createElement(co,t)},Go=function(e){var t=e.label,a=e.value,n=e.onChange,r=Object(Ca.a)(e,Ho),o=a||"0";return i.a.createElement(Vo,Object.assign({},r,{label:t||"Time",defaultValue:o,defaultUnit:"seconds",onChange:function(e){return n(e,!0)}}))},Wo=Object(g.a)((function(e){return{greyText:{"& select":{color:e.palette.primary.main}},icon:{color:e.palette.common.white},addButton:{marginTop:e.spacing(2)},header:{padding:e.spacing(1),marginBottom:e.spacing(1.5)},text:{maxWidth:366},content:{padding:e.spacing(1.5)},field:{marginTop:e.spacing(2.5)}}})),zo=function(e){var t=e.func,a=e.onAdd,n=e.defaultParams,r=Wo(),o=ga(At);if(!t)return i.a.createElement(Ar,{fullWidth:!0,disabled:!0,className:r.addButton,startIcon:i.a.createElement(kr,{className:r.icon})},"Add this transaction");return i.a.createElement(Wr,{func:t,defaultParams:n},(function(e){var n=e.paramInputProps,c=e.areParamsValid,l=e.getParams;return i.a.createElement(i.a.Fragment,null,n.map((function(e,a){return i.a.createElement("div",{className:r.field,key:a},i.a.createElement(_o,{func:t,param:e}))})),i.a.createElement(Ar,{fullWidth:!0,onClick:function(){return e=l(),void(o&&a({func:t,params:e,module:o,to:o.address,id:"".concat(t.name,"_").concat((new Date).getTime())}));var e},disabled:!c,className:r.addButton,startIcon:i.a.createElement(kr,{className:r.icon})},"Add this transaction"))}))},Ko=function(e,t){if(t){var a=e.findIndex((function(e){return e.format()===t}));if(a>=0)return a}return-1},Yo=function(e){var t=e.abi,a=e.onAdd,n=Wo(),r=ba(),o=Object(c.useMemo)((function(){return function(e){return(e instanceof R.b?e:new R.b(e)).fragments.filter(Ve.f.isFunctionFragment).map(Ve.f.from).filter(at)}(t)}),[t]),l=ga(Dr),s=l.func,u=l.params,d=Object(c.useState)((function(){return Ko(o,s)})),f=Object(x.a)(d,2),m=f[0],p=f[1];Object(c.useEffect)((function(){s&&p(Ko(o,s))}),[s,o]);return i.a.createElement(i.a.Fragment,null,i.a.createElement(h.c,{className:n.header,elevation:0},i.a.createElement(y.a,{variant:"h5",gutterBottom:!0},"Add Transaction"),i.a.createElement(y.a,{variant:"body2",className:n.text},"Add multiple transactions here, and we will bundle them together into a single transaction, to save you gas.")),i.a.createElement(h.c,{className:n.content,elevation:0},i.a.createElement(h.e,{select:!0,value:m,onChange:function(e){p(parseInt(e.target.value)),r(la())},className:ja()(Object(P.a)({},n.greyText,void 0===m)),color:"secondary",label:"Function"},i.a.createElement(Q.a,{value:-1},"Select function"),o.map((function(e,t){return i.a.createElement(Q.a,{key:e.format("full"),value:t},e.name)}))),i.a.createElement(zo,{key:"".concat(m,"_").concat(s),defaultParams:u,func:void 0!==m?o[m]:void 0,onAdd:function(e){p(-1),a(e)}})))},Zo=a(1717),qo=a(1725),Xo=["disabled"],Qo=Object(qa.a)((function(e){return{root:{width:"50%",padding:e.spacing(1,2.5),"& span":{fontSize:16,textTransform:"none",color:e.palette.text.primary+" !important"}},selected:{backgroundColor:e.palette.secondary.main+" !important"}}}))(Zo.a),Jo=function(e){var t=e.disabled,a=void 0!==t&&t,n=Object(Ca.a)(e,Xo);return i.a.createElement(qo.a,Object.assign({exclusive:!0,size:"small"},n),i.a.createElement(Qo,{disabled:a,value:"read",disableRipple:!0},"Read Contract"),i.a.createElement(Qo,{disabled:a,value:"write",disableRipple:!0},"Write Contract"))},$o=Object(g.a)((function(e){return{content:{padding:e.spacing(2),marginTop:e.spacing(3),background:h.f.tan[100]},hide:{display:"none"}}})),ec=function(e){var t=e.address,a=e.abi,n=$o(),r=ba(),o=ga(Lt);return i.a.createElement(i.a.Fragment,null,i.a.createElement(Jo,{value:o,onChange:function(e,t){return function(e){e&&r(Qt(e))}(t)}}),i.a.createElement(h.c,{className:n.content},i.a.createElement("div",{className:ja()(Object(P.a)({},n.hide,"read"!==o))},i.a.createElement(Oo,{address:t,abi:a})),i.a.createElement("div",{className:ja()(Object(P.a)({},n.hide,"write"!==o))},i.a.createElement(Yo,{abi:a,onAdd:function(e){r(ua(Rr(e)))}}))))},tc=Object(g.a)((function(e){return{root:{padding:e.spacing(2.5)},title:{marginBottom:e.spacing(2)},link:{fontSize:16}}})),ac=function(){var e=tc(),t=Object(p.useSafeAppsSDK)().safe,a=(_(t.chainId)||{}).verifyUrl;return i.a.createElement(h.c,{borderStyle:"double",className:e.root},i.a.createElement(y.a,{variant:"h5",className:e.title},"No Read or Write functions available"),i.a.createElement(y.a,null,"We couldn't find an ABI and didn't recognize it as one of the known Zodiac contracts."),i.a.createElement(Xa,{target:"_blank",href:a,className:e.link},"Verify this contract on Etherscan to fix this."))},nc=function(e){var t=e.module,a=dr(),n=a.safe,r=a.sdk,o=a.provider,l=Object(c.useState)(!0),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(),m=Object(x.a)(f,2),p=m[0],b=m[1];return Object(c.useEffect)((function(){d(!0),b(void 0),ut(o,r,n.chainId,t.address).then((function(e){var t=e.abi;return b(t)})).catch((function(e){return console.warn("getModuleABI",e)})).finally((function(){return d(!1)}))}),[t,n,r,o]),u?i.a.createElement(xa.a,{variant:"rect",width:300,height:48}):p?i.a.createElement(ec,{address:t.address,abi:p}):i.a.createElement(ac,null)},rc=Object(g.a)((function(e){return{content:{padding:e.spacing(0,2,2,2)}}})),oc=function(e){var t=e.module,a=rc();return i.a.createElement(i.a.Fragment,null,i.a.createElement(Vr,{module:t}),i.a.createElement("div",{className:a.content},i.a.createElement(nc,{key:t.address,module:t})))},cc=["children","className"],ic=Object(g.a)((function(e){return{tag:{display:"inline-block",borderRadius:8,lineHeight:1,padding:e.spacing(.75,.5),margin:e.spacing(0,1,1,0),backgroundColor:"rgba(0,20,40,0.5)",color:e.palette.common.white}}})),lc=function(e){var t=e.children,a=e.className,n=Object(Ca.a)(e,cc),r=ic();return i.a.createElement("div",Object.assign({className:ja()(r.tag,a)},n),t)},sc=Object(g.a)((function(e){return{root:{display:"flex",flexDirection:"column",alignItems:"center",userSelect:"none",padding:e.spacing(2),cursor:"pointer",transition:"0.2s ease all","&:hover":{background:"rgba(217, 212, 173, 0.15)"}},badgeIcon:{background:h.f.sepia[100],marginBottom:e.spacing(1)},title:{marginBottom:e.spacing(.5)}}})),uc=function(e){var t=e.title,a=e.description,n=e.icon,r=e.available,o=e.deprecated,c=e.className,l=e.onClick,s=sc();return r?i.a.createElement(h.c,{borderStyle:"double",className:ja()(s.root,c),onClick:l},i.a.createElement(h.a,{icon:n,size:60,className:s.badgeIcon}),i.a.createElement(y.a,{variant:"h6",className:s.title},t),o&&i.a.createElement(lc,null,"Deprecated"),i.a.createElement(y.a,{variant:"body2",align:"center"},a)):null},dc=a(708),fc=a(1718),mc=function(e){var t=e.tags,a=e.className,n=e.style;return i.a.createElement("div",null,t.map((function(e){return i.a.createElement(lc,{key:e,className:a,style:n},e)})))},pc=["svgRef","title"];function bc(){return(bc=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var hc,Ec,vc,yc=function(e){var t=e.svgRef,a=e.title,n=gc(e,pc);return i.a.createElement("svg",bc({width:11,height:13,viewBox:"0 0 11 13",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Uo||(Uo=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.79066 6.19787L6.50066 3.90787V11.4949C6.50066 12.0449 6.05066 12.4949 5.50066 12.4949C4.94966 12.4949 4.50066 12.0449 4.50066 11.4949V3.90787L2.20966 6.19787C1.82066 6.58687 1.18466 6.58687 0.795656 6.19787C0.406656 5.80887 0.406656 5.17287 0.795656 4.78387L4.79366 0.786873C4.85166 0.726872 4.92566 0.694874 4.99366 0.653873C5.03566 0.628874 5.06966 0.592874 5.11566 0.572873C5.15666 0.554873 5.20266 0.554873 5.24566 0.544873C5.45766 0.487873 5.68166 0.488873 5.88566 0.572873C5.92966 0.591873 5.96266 0.626873 6.00366 0.651873C6.07366 0.692873 6.14666 0.725873 6.20766 0.786873L10.2047 4.78387C10.5937 5.17287 10.5937 5.80887 10.2047 6.19787C9.81566 6.58787 9.17966 6.58787 8.79066 6.19787Z",fill:"white"})))},Oc=i.a.forwardRef((function(e,t){return i.a.createElement(yc,bc({svgRef:t},e))})),xc=(a.p,Object(g.a)((function(e){return{root:{width:"100%",outline:"none",maxWidth:380,margin:e.spacing(14,1,1,1),padding:e.spacing(2),backgroundColor:"rgba(78, 72, 87, 0.8)"},modal:{position:"absolute !important",paddingBottom:e.spacing(2),overflow:"auto",alignItems:"flex-start"},backdrop:{backdropFilter:"blur(4px)"},description:{marginTop:e.spacing(1)},gutterBottom:{marginBottom:e.spacing(3)},row:{display:"flex",flexDirection:"row"},center:{justifyContent:"center"},imageContainer:{marginRight:e.spacing(2),minWidth:68},infoContainer:{flexGrow:1},readMore:{display:"block",marginTop:e.spacing(1.5),fontSize:16},loader:{display:"block",margin:"0 auto"},warningIcon:{marginRight:e.spacing(1),"& .icon-color":{fill:"#E0B325 !important"}},warningText:{color:"#E0B325"}}}))),wc=function(e){var t=e.open,a=e.title,n=e.description,r=e.onAdd,o=e.tags,c=void 0===o?[]:o,l=e.icon,s=e.readMoreLink,u=e.onClose,d=e.children,f=e.ButtonProps,p=e.warning,b=e.hideButton,g=void 0!==b&&b,E=xc();return i.a.createElement(dc.a,{keepMounted:!0,open:t,onClose:u,className:ja()(E.modal,E.row,E.center),BackdropProps:{className:E.backdrop}},i.a.createElement(fc.a,{in:t},i.a.createElement(h.c,{borderStyle:"double",className:E.root,elevation:3},i.a.createElement("div",{className:ja()(E.row,E.gutterBottom)},i.a.createElement(h.a,{icon:l,size:68,className:E.imageContainer}),i.a.createElement("div",{className:E.infoContainer},i.a.createElement(y.a,{variant:"h5",gutterBottom:!0},a),i.a.createElement(mc,{tags:c}),n?i.a.createElement(y.a,{gutterBottom:!0,className:E.description},n):null,p?i.a.createElement(Pa,null,i.a.createElement(m.Icon,{type:"error",size:"md",className:E.warningIcon}),i.a.createElement(y.a,{variant:"body1",className:E.warningText},p)):null,s?i.a.createElement(Xa,{href:s,target:"_blank",className:E.readMore},"Read more here"):null)),d?i.a.createElement("div",{className:ja()(Object(P.a)({},E.gutterBottom,!g))},d):null,g?null:i.a.createElement(Ar,Object.assign({fullWidth:!0,startIcon:i.a.createElement(Oc,null),onClick:r},f),"Add Module"))))},jc=a(705),Cc=Object(g.a)((function(e){return{root:{color:e.palette.text.secondary,"&:hover":{background:"none"}}}})),kc=function(e){var t=Object.assign({},e),a=Cc();return i.a.createElement(jc.a,Object.assign({disableFocusRipple:!0,disableRipple:!0,disableTouchRipple:!0,color:"default"},t,{classes:{root:a.root}}))},Sc=a(704),Nc=["svgRef","title"];function Ic(){return(Ic=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Ac,Rc,Mc=function(e){var t=e.svgRef,a=e.title,n=Tc(e,Nc);return i.a.createElement("svg",Ic({width:32,height:32,viewBox:"0 0 32 32",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,hc||(hc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,fill:"#E0C5AD",fillOpacity:.1})),Ec||(Ec=i.a.createElement("path",{d:"M10 17L14 21L23 11",stroke:"white",strokeWidth:2,strokeLinejoin:"round"})),vc||(vc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,stroke:"white"})))},Bc=i.a.forwardRef((function(e,t){return i.a.createElement(Mc,Ic({svgRef:t},e))})),Dc=(a.p,["svgRef","title"]);function Lc(){return(Lc=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var Fc=function(e){var t=e.svgRef,a=e.title,n=Pc(e,Dc);return i.a.createElement("svg",Lc({width:32,height:32,viewBox:"0 0 32 32",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Ac||(Ac=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,fill:"#E0C5AD",fillOpacity:.1})),Rc||(Rc=i.a.createElement("rect",{x:.5,y:.5,width:31,height:31,rx:3.5,stroke:"white"})))},Uc=i.a.forwardRef((function(e,t){return i.a.createElement(Fc,Lc({svgRef:t},e))})),Vc=(a.p,Object(g.a)((function(){return{root:{padding:0,backgroundColor:"transparent !important",borderRadius:0}}}))),Hc=function(e){var t=Object.assign({},e),a=Vc();return i.a.createElement(Sc.a,Object.assign({disableFocusRipple:!0,disableRipple:!0,disableTouchRipple:!0,icon:i.a.createElement(Uc,null),checkedIcon:i.a.createElement(Bc,null),classes:{root:a.root}},t))},_c=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."),Gc=Object(g.a)((function(e){return{container:{marginLeft:e.spacing(1.5)},item:{marginTop:e.spacing(2)},text:{fontSize:12},delayText:{marginBottom:e.spacing(.5)}}})),Wc=function(e){var t=e.modules,a=e.value,n=e.description,r=void 0===n?_c:n,o=e.type,l=e.onChange,s=Gc(),u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1];return i.a.createElement(Pa,{style:{alignItems:"flex-start"}},i.a.createElement(Hc,{checked:f,onChange:function(){f&&l(void 0),m(!f)}}),i.a.createElement("div",{className:s.container},i.a.createElement(y.a,{gutterBottom:!0},"Attach to ",o.replace(/^\w/,(function(e){return e.toUpperCase()}))," Module"),r,f?t.map((function(e){return i.a.createElement(Pa,{key:e.address,className:s.item},i.a.createElement(kc,{checked:a===e.address,onClick:function(){return l(e.address)}}),i.a.createElement(Na,{style:{justifyContent:"center"}},mt(e)?i.a.createElement(Va,{className:ja()(s.text,s.delayText)},Ga(e.expiration)," delay"):null,i.a.createElement(Ka,{short:!0,hideCopyBtn:!0,hideExplorerBtn:!0,address:e.address,TypographyProps:{className:s.text}})))})):null))},zc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),Kc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=zc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(1===d.length?d[0].address:""),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)({owner:s.safeAddress,oracle:se(s.chainId),cooldown:"86400",expiration:"604800"}),h=Object(x.a)(g,2),E=h[0],v=h[1],O=Object(c.useState)({oracle:!!E.oracle}),w=Object(x.a)(O,2),j=w[0],S=w[1],I=Object.values(j).every((function(e){return e})),T=function(e,t,a){v(Object(N.a)(Object(N.a)({},E),{},Object(P.a)({},e,t))),void 0!==a&&S(Object(N.a)(Object(N.a)({},j),{},Object(P.a)({},e,a)))},A=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Object(N.a)(Object(N.a)({},E),{},{executor:p||s.safeAddress}),r=ge(u,s.safeAddress,s.chainId,t),e.next=5,l.txs.send({txs:r});case 5:n&&n(),a&&a(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}(),R=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return i.a.createElement(wc,{open:t,onClose:a,title:"Tellor Module",description:"Allows successful Snapshot proposals to execute transactions using the Tellor oracle.",icon:"tellor",tags:["From Tellor"],onAdd:A,readMoreLink:"https://github.com/tellor-io/snapshot-zodiac-module",ButtonProps:{disabled:!I}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",label:"Owner Address",onChange:function(e,t){return T("owner",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:E.oracle,label:"Oracle Address",onChange:function(e,t){return T("oracle",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:E.cooldown,defaultUnit:"hours",onChange:function(e){return T("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:E.expiration,defaultUnit:"days",onChange:function(e){return T("expiration",e)}}))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:R,modules:d,value:p,onChange:function(e){return b(e)},type:Fe.DELAY})):null)},Yc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},errorMessage:{color:"red"}}})),Zc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=Yc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(1===d.length?d[0].address:""),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(!0),h=Object(x.a)(g,2),E=h[0],v=h[1],O=Object(c.useState)({finder:de(s.chainId),owner:s.safeAddress,collateral:fe(s.chainId,E),bond:"2",rules:"",identifier:"0x4153534552545f54525554480000000000000000000000000000000000000000",liveness:"86400",snapshotURL:"https://snapshot.org/#/",votingQuorum:"5",votingPeriod:"24"}),w=Object(x.a)(O,2),j=w[0],S=w[1],I=Object(c.useState)({finder:!!j.finder,bond:!!j.bond,snapshotURL:!!j.snapshotURL,votingPeriod:!!j.votingPeriod,votingQuorum:!!j.votingQuorum}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object.values(A).every((function(e){return e})),B=function(e,t,a){S(Object(N.a)(Object(N.a)({},j),{},Object(P.a)({},e,t))),void 0!==a&&R(Object(N.a)(Object(N.a)({},A),{},Object(P.a)({},e,a)))},D=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Object(N.a)(Object(N.a)({},j),{},{owner:s.safeAddress,executor:p||s.safeAddress}),r=Be(u,s.safeAddress,s.chainId,t,E),e.next=5,l.txs.send({txs:r});case 5:n&&n(),a&&a(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}(),L=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return j.rules="I assert that this transaction proposal is valid according to the following rules: Proposals approved on Snapshot, as verified at ".concat(j.snapshotURL,", are valid as long as there is a minimum quorum of ").concat(j.votingQuorum," and a minimum voting period of ").concat(j.votingPeriod," hours and it does not appear that the Snapshot voting system is being exploited or is otherwise unavailable. The quorum and voting period are minimum requirements for a proposal to be valid. Quorum and voting period values set for a specific proposal in Snapshot should be used if they are more strict than the rules parameter. The explanation included with the on-chain proposal must be the unique IPFS identifier for the specific Snapshot proposal that was approved or a unique identifier for a proposal in an alternative voting system approved by DAO social consensus if Snapshot is being exploited or is otherwise unavailable."),i.a.createElement(wc,{open:t,onClose:a,title:"UMA oSnap Module",description:"Allows successful Snapshot proposals to execute transactions using UMA's optimistic oracle.",icon:"optimisticGov",tags:["From UMA"],onAdd:D,readMoreLink:"https://docs.uma.xyz/developers/osnap",ButtonProps:{disabled:!M}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(le,{label:"Collateral",defaultAddress:j.collateral,defaultOption:re.WETH,onChange:function(e){B("collateral",e),v(!E)},chainId:s.chainId})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("string"),color:"secondary",value:j.bond,label:"Bond",onChange:function(e,t){return B("bond",e,t)}}),i.a.createElement(y.a,{className:r.errorMessage},Number(j.bond)<1500&&!E?"Warning: A minimum bond of 1,500 is recommended for USDC":Number(j.bond)<2&&E?"Warning: A bond of 2 is recommended for WETH":null)),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Liveness",defaultValue:j.liveness,defaultUnit:"hours",onChange:function(e){return B("liveness",e)}}),i.a.createElement(y.a,{className:r.errorMessage},Number(j.liveness)<86400?"Warning: The minimum recommended liveness period is 24 hours.":null)),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("string"),color:"secondary",value:j.snapshotURL,label:"Snapshot Space URL",onChange:function(e,t){return B("snapshotURL",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("uint256"),color:"secondary",value:j.votingQuorum,label:"Voting Quorum",onChange:function(e,t){return B("votingQuorum",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(co,{param:Ve.g.from("uint256"),color:"secondary",value:j.votingPeriod,label:"Voting Period (hours)",onChange:function(e,t){return B("votingPeriod",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(y.a,null,"Rules Parameter:"),i.a.createElement(y.a,null,j.rules))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:L,modules:d,value:p,onChange:function(e){return b(e)},type:Fe.DELAY})):null)},qc=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),Xc=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=qc(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({expiration:"86400",cooldown:"86400"}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=function(e,t){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,t)))},g=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=he(u,s.safeAddress,s.chainId,{executor:s.safeAddress,cooldown:m.cooldown,expiration:m.expiration}),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Delay Modifier",description:"Adds a settable delay time to any transaction originating from this module.",icon:"delay",tags:["Stackable","From Gnosis Guild"],onAdd:g,readMoreLink:"https://zodiac.wiki/index.php/Category:Delay_Modifier"},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:m.cooldown,defaultUnit:"hours",onChange:function(e){return b("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:m.expiration,defaultUnit:"hours",onChange:function(e){return b("expiration",e)}}))))},Qc=Object(g.a)((function(e){return{addButton:{marginTop:e.spacing(2)},addTransactionButton:{marginTop:e.spacing(1)},addIcon:{stroke:e.palette.common.white,width:20,height:20}}})),Jc=function(e){var t=e.onSubmit,a=e.open,n=e.onClose,r=Object(p.useSafeAppsSDK)(),o=r.sdk,l=r.safe,s=ba(),u=Qc(),d=Object(c.useState)(""),f=Object(x.a)(d,2),m=f[0],b=f[1],g=Object(c.useState)(!1),h=Object(x.a)(g,2),E=h[0],v=h[1],y=function(){n&&n(),b(""),v(!1)},O=function(){var e=Object(k.a)(C.a.mark((function e(){var a;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=je(l.safeAddress,m),e.prev=1,e.next=4,o.txs.send({txs:[a]});case 4:y(),t&&t(),n&&n(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(1),console.warn("error adding custom module",e.t0);case 12:case"end":return e.stop()}}),e,null,[[1,9]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{hideButton:!0,open:a,onClose:n,title:"Custom Module",icon:"custom",readMoreLink:"https://zodiac.wiki/index.php/Category:Custom_Module",warning:"Modules do not require multisig approval for transactions. Only add modules that you trust!"},i.a.createElement(co,{placeholder:"0xCcBFc37093009fd31f85F1Bf90c34F1e03FB351E",label:"Module Address",param:Ve.g.fromString("address"),onChange:function(e,t){b(e),v(!!e.length&&t)}}),i.a.createElement(Ar,{fullWidth:!0,disableElevation:!0,className:u.addButton,variant:"contained",disabled:!E,startIcon:i.a.createElement(Oc,null),onClick:O},"Add Module"),i.a.createElement(Ar,{fullWidth:!0,className:u.addTransactionButton,disabled:!E,startIcon:i.a.createElement(kr,null),onClick:function(){var e={func:new R.b(B.a).getFunction("enableModule"),to:l.safeAddress,params:[m],id:"add_module_"+(new Date).getTime()};s(ua(Rr(e))),y(),n&&n()},variant:"outlined"},"Add to Transaction Bundle"))},$c=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),ei=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=$c(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({amb:!1,controller:!1,chainId:!1}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({amb:"",chainId:"",controller:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Ee(u,s.safeAddress,s.chainId,Object(N.a)(Object(N.a)({},h),{},{executor:s.safeAddress})),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Bridge Module",description:"This module allows for execution of transactions initiated by a designated address on the other side of a designated arbitrary message bridge (AMB).",icon:"bridge",tags:["From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Bridge_Module",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.amb,label:"AMB Contract Address",onChange:function(e,t){return O("amb",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.controller,label:"Controller Contract Address",onChange:function(e,t){return O("controller",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("uint256"),label:"Chain Id",value:h.chainId,onChange:function(e,t){return O("chainId",e,t)}}))))},ti=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},textLink:{cursor:"pointer"}}})),ai=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ti(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({tokenContract:!1}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({tokenContract:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,ye(u,s.safeAddress,s.chainId,Object(N.a)(Object(N.a)({},h),{},{executor:s.safeAddress}));case 3:return t=e.sent,e.next=6,l.txs.send({txs:t});case 6:n&&n(),a&&a(),e.next=13;break;case 10:e.prev=10,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Exit Module",description:"This module allows any holders of a designated ERC20, at any time, to redeem their designated ERC20 tokens in exchange for a proportional share of the Safe\u2019s ERC20 compatible assets.",icon:"exit",tags:["From Gnosis Guild"],onAdd:O,readMoreLink:"https://zodiac.wiki/index.php/Category:Exit_Pattern",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.tokenContract,label:"Token Contract Address",onChange:function(e,t){return function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))}("tokenContract",e,t)}}))))},ni=a(269),ri=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),oi=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ri(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({target:!0,multisend:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({target:s.safeAddress,multisend:ci(s)}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Re(u,s.safeAddress,s.chainId,h),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Roles Modifier v1",description:"Legacy version of the Roles Modifier",icon:"roles",tags:["Deprecated","Stackable","From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Roles_Modifier",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.target,label:"Target Address",onChange:function(e,t){return O("target",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.multisend,label:"Multisend Address",onChange:function(e,t){return O("multisend",e,t)}}))))};function ci(e){return ni.b[e.chainId]||ni.a}var ii=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),li=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=ii(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useState)({target:!0,multisend:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({target:s.safeAddress,multisend:si(s)}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object.values(m).every((function(e){return e})),O=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},w=function(){var e=Object(k.a)(C.a.mark((function e(){var t;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=Me(u,s.safeAddress,s.chainId,h),e.next=4,l.txs.send({txs:t});case 4:n&&n(),a&&a(),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),console.log(e.t0);case 11:case"end":return e.stop()}}),e,null,[[0,8]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Roles Modifier",description:"Allows avatars to enforce granular, role-based, permissions for attached modules",icon:"roles",tags:["Stackable","From Gnosis Guild"],onAdd:w,readMoreLink:"https://zodiac.wiki/index.php/Category:Roles_Modifier",ButtonProps:{disabled:!v}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.target,label:"Target Address",onChange:function(e,t){return O("target",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h.multisend,label:"Multisend Address",onChange:function(e,t){return O("multisend",e,t)}}))))};function si(e){return ni.b[e.chainId]||ni.a}var ui=a(172),di={NO_ARBITRATOR:"No arbitration (highest bond wins)",KLEROS:"Kleros",OTHER:"Other (custom address)"},fi=[o.MAINNET,o.GOERLI,o.GNOSIS_CHAIN,o.POLYGON],mi=Object(g.a)((function(e){return{root:{position:"relative",flexWrap:"nowrap",justifyContent:"flex-end"},label:{color:e.palette.text.primary,marginBottom:e.spacing(1)},inputContainer:{flexGrow:1},input:{borderTopRightRadius:0,borderBottomRightRadius:0,"& input":{textAlign:"right"}},select:{marginBottom:-1,textIndent:e.spacing(1)},itemList:{padding:0},item:{display:"flex",flexDirection:"row",padding:e.spacing(1.5,1),"&:not(:last-child)":{borderBottomWidth:1,borderBottomStyle:"solid",borderBottomColor:e.palette.primary.light},"& .show-if-selected":{display:"none"},"&.Mui-selected .show-if-selected":{display:"block"},"&.Mui-selected::after":{content:'""',right:0,top:0}},dropdownContainer:{maxWidth:"100%"},dropdown:{borderRadius:8,borderTopLeftRadius:0,borderTopRightRadius:0,borderTopWidth:2,borderTopColor:e.palette.primary.light,borderTopStyle:"solid",marginTop:-1}}})),pi=function(e){var t=e.onChange,a=e.defaultOption,n=void 0===a?di.NO_ARBITRATOR:a,r=e.defaultAddress,o=void 0===r?"":r,l=e.label,s=e.chainId,u=mi(),d=Object(c.useState)(n),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)(o),g=Object(x.a)(b,2),h=g[0],E=g[1],v=Object(c.useState)(!1),y=Object(x.a)(v,2),O=y[0],w=y[1],j=function(){return w(!1)},C=function(){return w(!0)},k=i.a.useRef(null),S=function(e,a){try{!0===a&&(E(e),t(e))}catch(n){console.warn("invalid arbitrator option")}},N=function(e){j();var a=Object.keys(di).find((function(t){return di["".concat(t)]===e}));if(p(e),"OTHER"===a)E(""),t("");else{var n=pe(s,oe[a]);E(n),t(n)}};return Object(c.useEffect)((function(){k.current&&k.current.addEventListener("keyup",(function(e){"Tab"===e.code&&C()}))}),[k]),i.a.createElement("div",null,i.a.createElement(Z.a,{className:u.label},l),i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,xs:12,className:u.dropdownContainer},i.a.createElement(X.a,{disableUnderline:!0,open:O,value:m,ref:k,onOpen:C,onClose:j,className:u.select,MenuProps:{anchorOrigin:{vertical:"bottom",horizontal:"left"},anchorPosition:{top:0,left:0},getContentAnchorEl:null,elevation:0,classes:{paper:u.dropdown,list:u.itemList}},renderValue:function(e){return e},onChange:function(e){return N(e.target.value)}},Object.keys(di).map((function(e){return fi.includes(s)||"KLEROS"!==e?i.a.createElement(Q.a,{key:e,value:di["".concat(e)],className:u.item},di["".concat(e)],i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}),i.a.createElement(ne,{className:"show-if-selected"})):null}))))),m===di.OTHER&&i.a.createElement(q.a,{container:!0,className:u.root},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:Ve.g.from("address"),color:"secondary",value:h,label:"",placeholder:"address (0x...)",onChange:function(e,t){return S(e,t)}}))))};function bi(e,t,a,n,r){var o=r?M.d.REALITY_ERC20:M.d.REALITY_ETH,c=n.timeout,i=n.cooldown,l=n.expiration,s=n.bond,u=n.templateId,d=n.oracle,f=n.executor,m=n.arbitrator,p=d||ue(a),b=Object(M.f)(o,{types:["address","address","address","address","uint32","uint32","uint32","uint256","uint256","address"],values:[t,t,f,p,c,i,l,s,u,m]},e,a,Date.now().toString()),g=b.transaction,h=b.expectedModuleAddress,E=[Object(N.a)(Object(N.a)({},g),{},{value:g.value.toString()})];if(f!==t){var v=Object(M.h)(M.d.DELAY,f,e),y=L(v.interface,v.address,"enableModule",[h]);E.push(y)}else{var O=je(t,h);E.push(O)}return E}var gi=Object(g.a)((function(e){return{fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"}}})),hi=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=gi(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=ga(Dt),f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(1===d.length?d[0].address:""),E=Object(x.a)(g,2),v=E[0],O=E[1],w=Object(c.useState)(V[s.chainId].nativeAsset),j=Object(x.a)(w,2),S=j[0],T=j[1],A=Object(c.useState)({oracle:ue(s.chainId),templateId:"",timeout:172800..toString(),cooldown:172800..toString(),expiration:604800..toString(),bond:"0.1",arbitrator:pe(s.chainId,oe.NO_ARBITRATOR)}),R=Object(x.a)(A,2),M=R[0],B=R[1],D=Object(c.useState)({oracle:!!M.oracle,templateId:!!M.templateId,bond:!!M.bond}),L=Object(x.a)(D,2),F=L[0],U=L[1],H=Object.values(F).every((function(e){return e}));Object(c.useEffect)((function(){M.oracle&&I.ethers.utils.isAddress(M.oracle)&&function(e,t,a){return K.apply(this,arguments)}(u,M.oracle,s.chainId).then((function(e){T(e.coin),b(e.isERC20)})).catch((function(){T(V[s.chainId].nativeAsset),b(!1)}))}),[M.oracle,s.chainId,u]);var _=function(e,t,a){B(Object(N.a)(Object(N.a)({},M),{},Object(P.a)({},e,t))),void 0!==a&&U(Object(N.a)(Object(N.a)({},F),{},Object(P.a)({},e,a)))},G=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r,o;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=I.ethers.utils.parseUnits(M.bond,S.decimals),r=Object(N.a)(Object(N.a)({},M),{},{executor:v||s.safeAddress,bond:t.toString()}),e.next=5,bi(u,s.safeAddress,s.chainId,r,p);case 5:return o=e.sent,e.next=8,l.txs.send({txs:o});case 8:n&&n(),a&&a(),e.next=15;break;case 12:e.prev=12,e.t0=e.catch(0),console.log("Error deploying module: ",e.t0);case 15:case"end":return e.stop()}}),e,null,[[0,12]])})));return function(){return e.apply(this,arguments)}}(),W=i.a.createElement(y.a,{variant:"body2"},"This will add a timedelay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours).");return i.a.createElement(wc,{open:t,onClose:a,title:"Reality Module",description:"Allows Reality.eth questions to execute a transaction when resolved.",icon:"reality",tags:["Stackable","From Gnosis Guild"],onAdd:G,readMoreLink:"https://zodiac.wiki/index.php/Category:Reality_Module",ButtonProps:{disabled:!H}},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(co,{param:ui.ParamType.from("address"),color:"secondary",value:M.oracle,label:"Oracle Address",onChange:function(e,t){return _("oracle",e,t)}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement(y.a,null,"TemplateId"),i.a.createElement(Or,null),i.a.createElement(Ma.a,{color:"textSecondary",href:"https://reality.eth.link/app/template-generator/",target:"_blank"},"Get a template here")),i.a.createElement(co,{param:ui.ParamType.from("uint256"),color:"secondary",placeholder:"10929783",label:void 0,value:M.templateId,onChange:function(e,t){return _("templateId",e,t)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Timeout",defaultValue:M.timeout,defaultUnit:"days",onChange:function(e){return _("timeout",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:M.cooldown,defaultUnit:"days",onChange:function(e){return _("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:M.expiration,defaultUnit:"days",onChange:function(e){return _("expiration",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Bond",color:"secondary",value:M.bond,append:null===S||void 0===S?void 0:S.symbol,onChange:function(e){var t=e.target.value||"0",a=t.startsWith("0")&&t.length>1?t.substr(1):t;a=a.startsWith(".")?"0"+a:a;try{I.ethers.utils.parseUnits(a,S.decimals),_("bond",a)}catch(n){console.warn("invalid bond",t,n)}}})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(pi,{label:"Arbitrator",defaultAddress:M.arbitrator,defaultOption:di.NO_ARBITRATOR,onChange:function(e){return _("arbitrator",e)},chainId:s.chainId}))),d.length?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:W,modules:d,value:v,onChange:function(e){return O(e)},type:Fe.DELAY})):null)},Ei=a(510),vi=a(477),yi=a(488),Oi=a.n(yi),xi=a(747);function wi(e,t,a,n,r,o,c){return ji.apply(this,arguments)}function ji(){return(ji=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i){var l,s,u,d,f,m,p,b,g,h,E,v,y,O,x,w,j,k,S,T;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(l=i?M.d.REALITY_ERC20:M.d.REALITY_ETH,s=o.timeout,u=o.cooldown,d=o.expiration,f=o.bond,m=o.oracle,p=o.executor,b=o.arbitrator,null!=(g=null!=m&&I.ethers.utils.isAddress(m)?m:ue(r))){e.next=5;break}throw new Error("No oracle address provided and no default oracle available for this chain (chainID: ".concat(r,")"));case 5:return h=Date.now().toString(),E={types:["address","address","address","address","uint32","uint32","uint32","uint256","uint256","address"],values:[n,a,p,g,s,u,d,f,0,b]},v=Object(M.f)(l,E,t,r,h),y=v.transaction,O=v.expectedModuleAddress,x=[Object(N.a)(Object(N.a)({},y),{},{value:y.value.toString()})],p!==a?(w=Object(M.h)(M.d.DELAY,p,t),j=L(w.interface,w.address,"enableModule",[O]),x.push(j)):(k=je(a,O),x.push(k)),S=new I.ethers.Contract(n,xi.abi,t),e.next=13,S.populateTransaction.createTemplateAndChangeOwner(O,g,JSON.stringify({type:"bool",title:c.templateQuestion,category:"DAO proposal",lang:"en"}),a);case 13:if(null!=(T=e.sent).to){e.next=16;break}throw new Error("Missing to address");case 16:if(null!=T.data){e.next=18;break}throw new Error("Missing data");case 18:return x.push({to:T.to,data:T.data,value:"0"}),e.abrupt("return",{txs:x,meta:{expectedModuleAddress:O}});case 20:case"end":return e.stop()}}),e)})))).apply(this,arguments)}a(111);var Ci,ki=a(748),Si=(new TextDecoder,function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=Ci){e.next=4;break}return e.next=3,ki.create();case 3:Ci=e.sent;case 4:return e.abrupt("return",Ci);case 5:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()),Ni=function(){var e=Object(k.a)(C.a.mark((function e(t){var a,n,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Si();case 2:return a=e.sent,e.next=5,a.add(t);case 5:return n=e.sent,r=n.cid,e.abrupt("return",r);case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Ii=a(194),Ti="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",Ai=["function setText(bytes32 node, string calldata key, string calldata value) external","function text(bytes32 node, string calldata key) external view returns (string memory)"],Ri=["function owner(bytes32 node) external view returns (address)","function resolver(bytes32 node) external view returns (address)"],Mi=["function ownerOf(uint256 tokenId) public view returns (address owner)"],Bi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return o=new I.ethers.Contract(Ti,Ri,t),c=I.ethers.utils.namehash(a),e.next=4,o.resolver(c);case 4:return i=e.sent,l=new I.ethers.Contract(i,Ai,t),e.next=8,l.populateTransaction.setText(c,n,r);case 8:if(null!=(s=e.sent).to){e.next=11;break}throw new Error("Missing to address");case 11:if(null!=s.data){e.next=13;break}throw new Error("Missing data");case 13:return e.abrupt("return",{to:s.to,data:s.data,value:"0"});case 14:case"end":return e.stop()}}),e)})));return function(t,a,n,r){return e.apply(this,arguments)}}(),Di=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i,l,s;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=I.ethers.BigNumber,o=a.split(".")[0],c=I.ethers.utils.keccak256(I.ethers.utils.toUtf8Bytes(o)),i=r.from(c).toString(),l=new I.ethers.Contract("0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",Mi,t),e.next=7,l.ownerOf(i);case 7:return s=e.sent,e.abrupt("return",I.ethers.utils.getAddress(s)===I.ethers.utils.getAddress(n));case 9:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Li=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c,i,l;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=I.ethers.utils.namehash(t),o=new I.ethers.Contract(Ti,Ri,n),e.next=4,o.resolver(r);case 4:return c=e.sent,i=new I.ethers.Contract(c,Ai,n),l=i.functions.text(r,a),e.abrupt("return",l);case 8:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Pi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n){var r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=new I.ethers.Contract(Ti,Ri,t),o=I.ethers.utils.namehash(a),e.next=4,r.owner(o);case 4:return c=e.sent,e.abrupt("return",I.ethers.utils.getAddress(n)===I.ethers.utils.getAddress(c));case 6:case"end":return e.stop()}}),e)})));return function(t,a,n){return e.apply(this,arguments)}}(),Fi=a(489),Ui=a.n(Fi),Vi=["flagged","verified","hibernated","turbo"],Hi=function(){var e=Object(k.a)(C.a.mark((function e(t,a){var n;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Gi(t,a);case 2:return e.next=4,fetch("".concat(Wi(a),"/api/spaces/").concat(t));case 4:if(!(n=e.sent).ok){e.next=17;break}return e.prev=6,e.next=9,n.json().then((function(e){e.flagged,e.verified,e.hibernated,e.turbo;return Object(Ca.a)(e,Vi)}));case 9:return e.abrupt("return",e.sent);case 12:return e.prev=12,e.t0=e.catch(6),e.abrupt("return",void 0);case 15:e.next=18;break;case 17:throw n;case 18:case"end":return e.stop()}}),e,null,[[6,12]])})));return function(t,a){return e.apply(this,arguments)}}(),_i=function(e){return Ui.a.utils.validateSchema(Ui.a.schemas.space,e)},Gi=function(e,t){return fetch("".concat(Wi(t),"/api/spaces/").concat(e,"/poke"))},Wi=function(e){return e===o.GOERLI?"https://testnet.hub.snapshot.org":"https://hub.snapshot.org"},zi="https://api.zodiac.gnosisguild.org/api";var Ki=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d,f;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(console.log(),""!==(null!==(o=r.apiKey)&&void 0!==o?o:"")&&""!==(null!==(c=r.secretKey)&&void 0!==c?c:"")){e.next=3;break}throw new Error("API keys for monitoring service missing. Monitoring will NOT be set up.");case 3:if(""!==(null!==(i=r.discordKey)&&void 0!==i?i:"")||""!==(null!==(l=r.slackKey)&&void 0!==l?l:"")||0!==r.email.length||""!==(null!==(s=r.telegram.botToken)&&void 0!==s?s:"")||null===(u=r.telegram.chatId)||void 0===u||!u){e.next=5;break}throw new Error("No notification channel(s) specified. Monitoring will NOT be set up.");case 5:return d=[],r.email.length>0&&d.push({channel:"email",config:{emails:r.email}}),r.discordKey.length>0&&d.push({channel:"discord",config:{url:r.discordKey}}),r.slackKey.length>0&&d.push({channel:"slack",config:{url:r.slackKey}}),r.telegram.botToken.length>0&&d.push({channel:"telegram",config:r.telegram}),f={apiKey:r.apiKey,apiSecret:r.secretKey,network:Zi(t),oracleAddress:n,realityModuleAddress:a,notificationChannels:d},e.abrupt("return",fetch(zi+"/monitoring/notification",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(f)}));case 12:case"end":return e.stop()}}),e)})));return function(t,a,n,r){return e.apply(this,arguments)}}(),Yi=function(){var e=Object(k.a)(C.a.mark((function e(t){var a,n;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=t.apiKey,n=t.apiSecret,e.abrupt("return",fetch("".concat(zi,"/monitoring/validation?apiKey=").concat(a,"&apiSecret=").concat(n),{method:"GET",mode:"cors",headers:{"Content-Type":"application/json",Accept:"application/json"}}));case 2:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Zi=function(e){switch(e){case o.MAINNET:return"mainnet";case o.GOERLI:return"goerli";case o.OPTIMISM:return"optimism";case o.BSC:return"bsc";case o.GNOSIS_CHAIN:return"xdai";case o.POLYGON:return"matic";case o.ARBITRUM:return"arbitrum";case o.AVALANCHE:return"avalanche";default:throw new Error("Unsupported network")}};var qi,Xi=function(){var e=Object(k.a)(C.a.mark((function e(t){var a;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,fetch("https://api.zodiac.gnosisguild.org/api/ipfs-pinning/snapshot-settings",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});case 2:return a=e.sent,e.abrupt("return",a.json());case 4:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Qi=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c){var i,l,s,u,d,f;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c("Setting up Reality Module deployment transactions"),e.next=3,Ji(t,n.chainId,n.safeAddress,r,o).catch((function(e){c("Error while setting up Reality Module deployment transactions",e)}));case 3:if(null!=(l=e.sent)){e.next=6;break}throw new Error("The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE. Should be handled in the 'statusCallback' function.");case 6:if(null==(s=null===(i=l.meta)||void 0===i?void 0:i.expectedModuleAddress)&&(u=new Error("Unable to calculate the Reality Module future address."),c(u.message,u)),null!=s){e.next=10;break}throw new Error("The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.");case 10:return c("Setting up transaction for adding the new snapshot space to the ENS record"),e.next=13,el(t,o.proposal.ensName,s,n.chainId).catch((function(e){c("Error when setting up transactions to add SafeSnap to the Snapshot Space",e)}));case 13:if(d=e.sent,null!=l&&null!=d){e.next=16;break}throw new Error("The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE.");case 16:return f=[].concat(Object(w.a)(l.txs),Object(w.a)(d.txs)),c("Setting up monitoring with OZ Defender"),e.next=20,Ki(n.chainId,s,o.oracle.instanceData.instanceAddress,o.monitoring).catch((function(e){c("Error when setting up monitoring.",e)}));case 20:return c("Proposing transactions to the Safe"),e.next=23,a.txs.send({txs:f}).catch((function(e){c("Error when proposing transactions to the Safe",e)}));case 23:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c){return e.apply(this,arguments)}}(),Ji=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c=V[a].nativeAsset,i={executor:r,bond:I.ethers.utils.parseUnits(o.oracle.bondData.bond.toString(),c.decimals).toString(),timeout:o.oracle.delayData.timeout.toString(),cooldown:o.oracle.delayData.cooldown.toString(),expiration:o.oracle.delayData.expiration.toString(),arbitrator:pe(a,o.oracle.arbitratorData.arbitratorOption),oracle:o.oracle.instanceData.instanceAddress},e.next=4,wi(t,n,"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c",a,i,o.oracle.templateData,!1);case 4:return e.abrupt("return",e.sent);case 5:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}(),$i=function(e,t,a){return Ii.b(["plugins","safeSnap"],{safes:[{network:t,realityAddress:a,multisend:"0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761"}]},e)},el=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r){var o,c,i,l,s,u,d;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Hi(a,r);case 2:if(o=e.sent,c=$i(o,r,n),f=o,m=c,Ii.a(Ii.d(Ii.e(["plugins","safeSnap"],f),Ii.e(["plugins","safeSnap"],m)),!0===_i(m))){e.next=6;break}throw new Error("The new settings file is changed in unexpected ways");case 6:return e.next=8,Ni(JSON.stringify(c));case 8:return i=e.sent.toV0().toString(),l="",e.prev=10,e.next=13,Xi({snapshotSpaceEnsName:a,snapshotSpaceSettings:c,chainId:r});case 13:s=e.sent,u=s.cidV0,l=u,e.next=21;break;case 18:throw e.prev=18,e.t0=e.catch(10),new Error("Failed to pin the new snapshot space settings file. Error from backend: "+e.t0);case 21:if(""!==l&&null!=l){e.next=23;break}throw new Error("Communication with the backend pinning service failed. No CID was returned.");case 23:if(null==i||i===l){e.next=25;break}throw new Error("The CID from the locale browser node (".concat(i,") does not correspond the CID from the pinning service (").concat(l,")"));case 25:return e.next=27,Bi(t,a,"snapshot","ipfs://".concat(i));case 27:return d=e.sent,e.abrupt("return",{txs:[d]});case 29:case"end":return e.stop()}var f,m}),e,null,[[10,18]])})));return function(t,a,n,r){return e.apply(this,arguments)}}(),tl=Object(g.a)((function(){return{label:{marginBottom:4},select:{border:"1px solid ".concat(h.f.tan[300])},selectContainer:{padding:2,boxSizing:"border-box",border:"1px solid ".concat(h.f.tan[300])},icon:{fontSize:"1rem"}}})),al=function(e){var t=tl();return i.a.createElement(J.a,null,e.label&&i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",className:t.label},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,e.label)),e.tooltipMsg&&i.a.createElement(q.a,{item:!0},i.a.createElement(wo.a,{title:e.tooltipMsg},i.a.createElement(ko.a,{className:t.icon})))),i.a.createElement(J.a,{className:t.selectContainer},i.a.createElement(X.a,Object.assign({},Ii.c("tooltipMsg",e),{className:t.select}),e.options.map((function(e){return i.a.createElement(Q.a,{key:e.value,value:e.value},e.label,i.a.createElement(J.a,{className:"show-if-selected",flexGrow:1}))})))))},nl=a(1719),rl=function(e){return"Did the Snapshot proposal with the id %s in the ".concat(e," space pass the execution of the array of Module transactions that have the hash 0x%s and does it meet the requirements of the document referenced in the dao requirements record at ").concat(e,"? The hash is the keccak of the concatenation of the individual EIP-712 hashes of the Module transactions. If this question was asked before the corresponding Snapshot proposal was resolved, it should ALWAYS be resolved to INVALID!")},ol="Provide a question. This must include two %s placeholders.\nThe first placeholder is for the id of the proposal (e.g., an IPFS hash).\nThe second is the hash of the concatenation of the EIP-712 transaction hashes.",cl=[{label:"Zodiac Reality Module (default)",value:"default"},{label:"Custom",value:"custom"}],il=[{label:"English",value:"english"}],ll=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},textFieldSmall:{"& .MuiFormLabel-root":{fontSize:12}},select:{border:"1px solid rgba(217, 212, 173, 0.3)"},paperTemplateContainer:{marginTop:4,padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)"},templateQuestion:{fontFamily:"Roboto Mono","& .MuiInputBase-root":{border:"none",fontSize:"0.85rem"}},input:{"& .MuiInputBase-root":{padding:"9px 8px",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},button:{width:"100%",padding:"4px 15px"},buttonContainer:{marginTop:8,cursor:"pointer"},icon:{color:h.f.tan[1e3],fontSize:"1rem",marginTop:3},text:{fontSize:"0.75rem"},tooltipIcon:{fontSize:"1rem"}}})),sl=function(e){var t=e.data,a=e.setData,n=e.ensName,r=ll(),o=function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}},c=function(e){return t[e]};return i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Oracle Template")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"The oracle template creates an appropriate question based on the data of the proposal. We highly recommend using the default Zodiac Reality Module template")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",spacing:2,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(al,{value:c("templateType"),options:cl,onChange:function(e){return r=e.target.value,void a("default"===r?Object(N.a)(Object(N.a)({},t),{},{templateQuestion:rl(n),templateType:r}):Object(N.a)(Object(N.a)({},t),{},{templateQuestion:"",templateType:r}));var r},label:"Select template:",tooltipMsg:"The Zodiac Reality Module type has defaults set for connecting the Reality Module to Safesnap. If you need a more specific setup, use the \u2018Custom\u2019 type."})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(al,{value:c("language"),options:il,disableUnderline:"default"===c("templateType"),label:"Language:",disabled:"default"===c("templateType"),onChange:function(e){var t=e.target;return o("language")(t.value)}})),i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(y.a,null,"Template question preview:"),i.a.createElement(wo.a,{title:ol},i.a.createElement(nl.a,{className:r.tooltipIcon}))),i.a.createElement(h.c,{className:r.paperTemplateContainer},i.a.createElement(h.e,{className:r.templateQuestion,value:c("templateQuestion"),onChange:function(e){var t=e.target;return o("templateQuestion")(t.value)},multiline:!0,minRows:5,disabled:"default"===c("templateType"),placeholder:"default"===c("templateType")?rl(n):ol})))))))},ul=a(381),dl=a.n(ul),fl=["svgRef","title"];function ml(){return(ml=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var bl=function(e){var t=e.svgRef,a=e.title,n=pl(e,fl);return i.a.createElement("svg",ml({width:15,height:12,viewBox:"0 0 15 12",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,qi||(qi=i.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z"})))},gl=i.a.forwardRef((function(e,t){return i.a.createElement(bl,ml({svgRef:t},e))})),hl=(a.p,function(){var e=Object(c.useState)(!1),t=Object(x.a)(e,2),a=t[0],n=t[1],r=Object(c.useState)(),o=Object(x.a)(r,2),i=o[0],l=o[1];return{loading:a,error:i,execute:function(){var e=Object(k.a)(C.a.mark((function e(t,a){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n(!0),l(void 0),e.prev=2,e.next=5,Yi({apiKey:t,apiSecret:a}).then((function(e){if(n(!1),200===e.status)return l(!1);l(!0)}));case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(2),n(!1);case 10:case"end":return e.stop()}}),e,null,[[2,7]])})));return function(t,a){return e.apply(this,arguments)}}()}}),El=Object(g.a)((function(e){return{errorIcon:{fill:"rgba(244, 67, 54, 1)",width:"20px"},warningIcon:{fill:"rgba(230, 230, 54, 1)",width:"20px"},fields:{marginBottom:e.spacing(1)},loadMessage:{textAlign:"center"},loadingContainer:{marginRight:4,padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:14,width:14,border:"1px solid ".concat(h.f.tan[300])},spinner:{width:"8px !important",height:"8px !important",color:"yellow !important",fill:"yellow !important",opacity:"100% !important"},addSpinner:{color:"white !important",fill:"white !important",opacity:"100% !important"},detailsContainer:{width:"95%"},messageContainer:{width:"85%",fill:"rgba(244, 67, 54, 1)"},errorMessageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer",color:"rgba(244, 67, 54, 1)"},warningMessageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer",color:"rgba(230, 230, 54, 1)"},errorMessage:{fontSize:12,color:"rgba(244, 67, 54, 1)",fontWeight:"bolder"},warningMessage:{fontSize:12,color:"rgba(230, 230, 54, 1)"},linkStyle:{color:"rgba(190, 190, 120, 1)"},flexRow:{display:"flex",flexDirection:"row"}}})),vl=Object(qa.a)({switchBase:{"&.Mui-checked":{color:"white"}},colorSecondary:{"&.Mui-checked + .MuiSwitch-track":{backgroundColor:"yellow"}},track:{backgroundColor:"black"}})(Ei.a),yl=function(e){var t=e.status,a=e.message,n=e.link,r=El();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:1},"error"===t&&i.a.createElement(Mo.a,{className:r.errorIcon}),"warning"===t&&i.a.createElement(dl.a,{className:r.warningIcon})),i.a.createElement(q.a,{item:!0,className:r.detailsContainer,xs:11},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0,className:r.messageContainer},i.a.createElement(y.a,{className:"error"===t?r.errorMessage:r.warningMessage},a)),n?i.a.createElement(q.a,{item:!0},i.a.createElement(Ma.a,{className:"error"===t?r.errorMessageDetails:r.warningMessageDetails,href:n,target:"_blank"},"Details")):i.a.createElement(q.a,null))))},Ol=function(e){var t=e.open,a=e.onClose,n=e.onSubmit,r=El(),o=dr(),l=o.sdk,s=o.safe,u=o.provider,d=Object(c.useMemo)((function(){return new I.ethers.providers.InfuraProvider(1,"0de1a96486754f8b98f284d093905198")}),[]),f=Object(c.useMemo)((function(){return new I.ethers.providers.InfuraProvider(5,"0de1a96486754f8b98f284d093905198")}),[]),p=V[s.chainId].nativeAsset,b=Object(c.useState)({snapshotEns:"",timeout:172800..toString(),cooldown:172800..toString(),expiration:604800..toString(),bond:"0.1"}),g=Object(x.a)(b,2),E=g[0],v=g[1],O=Object(c.useState)(!1),j=Object(x.a)(O,2),S=j[0],T=j[1],A=Object(c.useState)(!1),R=Object(x.a)(A,2),M=R[0],B=R[1],D=Object(c.useState)(!1),L=Object(x.a)(D,2),F=L[0],U=L[1],H=Object(c.useState)(""),_=Object(x.a)(H,2),G=_[0],W=_[1],z=Object(c.useState)(!1),K=Object(x.a)(z,2),Y=K[0],Z=K[1],X=Object(c.useState)(!1),Q=Object(x.a)(X,2),$=Q[0],ee=Q[1],te=!!E.snapshotEns&&E.snapshotEns.includes(".eth")&&!S&&M&&F,ae=Object(c.useState)({snapshotEns:te,bond:!!E.bond}),ne=Object(x.a)(ae,2),re=ne[0],oe=ne[1],ce=Object(c.useState)(!1),ie=Object(x.a)(ce,2),le=ie[0],se=ie[1],de=Object(c.useState)(""),fe=Object(x.a)(de,2),pe=fe[0],be=fe[1],ge=Object(c.useState)(""),he=Object(x.a)(ge,2),Ee=he[0],ve=he[1],ye=Object(c.useState)(!1),Oe=Object(x.a)(ye,2),xe=Oe[0],we=Oe[1],je=Object(c.useState)(""),Ce=Object(x.a)(je,2),ke=Ce[0],Se=Ce[1],Ne=Object(c.useState)([]),Ie=Object(x.a)(Ne,2),Te=Ie[0],Ae=Ie[1],Re=Object(c.useState)(""),Me=Object(x.a)(Re,2),Be=Me[0],De=Me[1],Le=Object(c.useState)(""),Pe=Object(x.a)(Le,2),Fe=Pe[0],Ue=Pe[1],Ve=Object(c.useState)(""),He=Object(x.a)(Ve,2),_e=He[0],Ge=He[1],We=Object(c.useState)("form"),ze=Object(x.a)(We,2),Ke=ze[0],Ye=ze[1],Ze=Object.values(re).every((function(e){return e})),qe=/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.test(ke)&&!Te.includes(ke),Xe=Ze&&(!le||void 0!==pe&&void 0!==Ee&&Te.length>0),Qe=Object(c.useState)(!1),Je=Object(x.a)(Qe,2),$e=Je[0],et=Je[1],tt=Object(c.useCallback)(Object(k.a)(C.a.mark((function e(){var t,a,n,r,o,c;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=5===s.chainId?f:d,e.next=3,t.resolveName(E.snapshotEns);case 3:if(a=e.sent,console.log({address:a}),!a){e.next=24;break}return e.next=8,Hi(E.snapshotEns,s.chainId);case 8:return n=e.sent,e.next=11,Li(E.snapshotEns,"daorequirements",t);case 11:if(r=e.sent,W(r[0]),U(void 0!==n),void 0===n){e.next=22;break}return ee(!!(null===(o=n.plugins)||void 0===o?void 0:o.safeSnap)),e.next=18,Pi(t,E.snapshotEns,s.safeAddress);case 18:c=e.sent,Z(c),console.log({isController:c,snapshotSpace:n}),console.log({snapshotSpace:n});case 22:e.next=24;break;case 24:case"end":return e.stop()}}),e)}))),[E.snapshotEns,s.chainId,s.safeAddress,d,f]),at=Oi()((function(){(U(!1),W(""),Z(!1),ee(!1),B(!1),E.snapshotEns&&E.snapshotEns.includes(".eth"))&&(T(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,tt();case 2:T(!1),B(!0);case 4:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()())}),300);Object(c.useEffect)((function(){at()}),[E.snapshotEns]);var nt=hl(),rt=nt.loading,ot=nt.execute,ct=nt.error,it=Oi()(Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return we(!1),e.next=3,ot(pe,Ee);case 3:we(!0);case 4:case"end":return e.stop()}}),e)}))),300);Object(c.useEffect)((function(){pe&&Ee&&it()}),[pe,Ee]),Object(c.useEffect)((function(){if(s.chainId){var e=1===s.chainId?"1":100===s.chainId?"1500":137===s.chainId?"1000":"1";v((function(t){return Object(N.a)(Object(N.a)({},t),{},{bond:e})}))}}),[s.chainId]),Object(c.useEffect)((function(){oe({snapshotEns:te,bond:!!E.bond})}),[E,S,te]);var lt=function(e,t,a){v(Object(N.a)(Object(N.a)({},E),{},Object(P.a)({},e,t)))},st=function(){var e=Object(k.a)(C.a.mark((function e(){var t,r,o,c,i,d,f,m,b,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return et(!0),e.prev=1,r=I.ethers.utils.parseUnits(E.bond,p.decimals),o=Object(N.a)(Object(N.a)({},E),{},{oracle:ue(s.chainId),arbitrator:me(s.chainId),executor:s.safeAddress,bond:r.toString()}),c=rl(o.snapshotEns),i={templateType:"default",language:"english",category:"DAO proposal",templateQuestion:c},e.next=8,wi(u,s.safeAddress,"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c",s.chainId,o,i);case 8:if(d=e.sent,f=Object(w.a)(d.txs),m=null===(t=d.meta)||void 0===t?void 0:t.expectedModuleAddress,!Y||1!==s.chainId){e.next=19;break}if(null!=m){e.next=14;break}throw new Error("The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.");case 14:return e.next=16,el(u,o.snapshotEns,m,s.chainId);case 16:b=e.sent,g=b.txs,f.push(g[0]);case 19:if(!le){e.next=23;break}return h={apiKey:pe,secretKey:Ee,discordKey:Be,email:Te,slackKey:"",telegram:{botToken:Fe,chatId:_e}},e.next=23,Ki(s.chainId,m,o.oracle,h);case 23:return e.next=25,l.txs.send({txs:f});case 25:n&&n(),a&&a(),e.next=32;break;case 29:e.prev=29,e.t0=e.catch(1),console.log("Error deploying module: ",e.t0);case 32:et(!1);case 33:case"end":return e.stop()}}),e,null,[[1,29]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{open:t,onClose:a,title:"Kleros Snapshot Module",description:"Execute transactions for successful Snapshot proposals using Reality.eth, secured by Kleros.",icon:"reality",tags:["Stackable","From Kleros"],hideButton:!0,readMoreLink:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module"},"form"===Ke?i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(q.a,{container:!0,spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:E.snapshotEns,onChange:function(e){return lt("snapshotEns",e.target.value)},label:"Snapshot Name",placeholder:"gnosis.eth",rightIcon:i.a.createElement(i.a.Fragment,null,S?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):M&&F?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner})):null)}),!S&&M&&!te&&i.a.createElement(yl,{message:"This Snapshot space does not exist.",status:"error"})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Timeout",defaultValue:E.timeout,defaultUnit:"days",onChange:function(e){return lt("timeout",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Cooldown",defaultValue:E.cooldown,defaultUnit:"days",onChange:function(e){return lt("cooldown",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Vo,{label:"Expiration",defaultValue:E.expiration,defaultUnit:"days",onChange:function(e){return lt("expiration",e)}})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Bond",prefix:p.symbol,color:"secondary",value:E.bond,onChange:function(e){var t=e.target.value||"0",a=t.startsWith("0")&&t.length>1?t.substr(1):t;a=a.startsWith(".")?"0"+a:a;try{I.ethers.utils.parseUnits(a,p.decimals),lt("bond",a)}catch(n){console.warn("invalid bond",t,n)}}}))),i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(y.a,{variant:"body1"},"Configure Monitoring")),i.a.createElement(q.a,{xs:6,style:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"space-between"}},i.a.createElement("div",null),i.a.createElement(vl,{value:le,onClick:function(){se(!le)}}))),le&&i.a.createElement(q.a,{container:!0,direction:"column",spacing:2,className:r.fields},i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(y.a,{variant:"body2"},"Setting up an effective monitoring strategy is critical for the security of your safe. First, you need to"," ",i.a.createElement(Ma.a,{className:r.linkStyle,underline:"always",href:"https://defender.openzeppelin.com/#/auth/sign-in",target:"_blank"},"create an Open Zeppelin account"),".")),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:pe,onChange:function(e){be(e.target.value)},label:"API Key",placeholder:"3pwZzZZZzzZZZzzZZzZZZAAaaAAaaZZzz",rightIcon:rt?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):xe&&!ct&&i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner}))})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(h.e,{value:Ee,onChange:function(e){ve(e.target.value)},label:"API Secret",placeholder:"2LUwZwwuUuuUUzzZZdDddooodudDDdaaDDdaAAAddDDadDzZZzdDDdcCCdDDaaAA",rightIcon:rt?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:r.spinner})):xe&&!ct&&i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(gl,{className:r.spinner}))})),xe&&ct&&i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(yl,{message:"These credentials are wrong.",status:"error"})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Email"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(required)")),i.a.createElement(y.a,{variant:"body2"},"Enter as many email addresses as you need"),i.a.createElement(h.e,{placeholder:"john@doe.com",value:ke,onChange:function(e){Se(e.target.value)},onKeyDown:function(e){"Enter"===e.key&&qe&&(Ae([].concat(Object(w.a)(Te),[ke])),Se(""))},rightIcon:i.a.createElement(i.a.Fragment,null,qe?i.a.createElement(J.a,{className:r.loadingContainer},i.a.createElement(vi.a,{size:"small",onClick:function(){Ae([].concat(Object(w.a)(Te),[ke])),Se("")}}," ",i.a.createElement(m.Icon,{size:"sm",type:"add",color:"primary"}))):null)}),Te.length>0?Te.map((function(e){return i.a.createElement(q.a,{container:!0,key:e},i.a.createElement(q.a,{item:!0,xs:1},i.a.createElement(vi.a,{size:"small",onClick:function(){return Ae(Te.filter((function(t){return t!==e})))}},i.a.createElement(m.Icon,{size:"sm",type:"delete",color:"warning"}))),i.a.createElement(q.a,{item:!0,xs:11},i.a.createElement(y.a,null,e)))})):i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},qe?"Press Enter or click + to add this email":"(No emails entered, at least one is required)")),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Discord Integration"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(optional)")),i.a.createElement(q.a,{container:!0,style:{display:"flex",flexDirection:"row",justifyContent:"space-between"}},i.a.createElement(y.a,{variant:"body2"},"Include the Discord channel's url key"),i.a.createElement(Ma.a,{className:r.linkStyle,href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks",target:"_blank"},"Learn more")),i.a.createElement(h.e,{value:Be,onChange:function(e){De(e.target.value)},placeholder:"https://discord.com/api/webhooks/.../"})),i.a.createElement(q.a,{item:!0,xs:12},i.a.createElement(q.a,{item:!0,style:{display:"flex"}},i.a.createElement(y.a,null,"Telegram Integration"),i.a.createElement(y.a,{style:{fontStyle:"italic",opacity:"0.7"}},"\xa0(optional)")),i.a.createElement(q.a,{container:!0,style:{display:"flex",flexDirection:"row",justifyContent:"space-between"}},i.a.createElement(y.a,{variant:"body2"},"Include the Telegram bot token and Chat ID"),i.a.createElement(Ma.a,{className:r.linkStyle,href:"https://core.telegram.org/bots#6-botfather",target:"_blank"},"Learn more")),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"row",alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{placeholder:"123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",value:Fe,onChange:function(e){Ue(e.target.value)}})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{placeholder:"1234567890",value:_e,onChange:function(e){Ge(e.target.value)}})))))),i.a.createElement(Ar,{fullWidth:!0,startIcon:i.a.createElement(Oc,null),onClick:function(){Ye("confirm")},disabled:!Xe,style:{marginTop:"16px"}},Xe||!le?"Add Module":rt?"Validating OpenZeppelin Credentials...":!xe||ct?"Missing OpenZeppelin API":"Missing Email")):i.a.createElement(i.a.Fragment,null,i.a.createElement(y.a,null,"It's almost ready! Just a reminder:"),M&&(te?Y&&1===s.chainId?$?i.a.createElement("div",null,"SafeSnap plugin is already installed, and will be overwritten."):i.a.createElement("div",null,"The SafeSnap plugin will be automatically installed."):i.a.createElement("div",{style:{marginTop:"4px"}},i.a.createElement(yl,{message:"Install SafeSnap after creating the module.",link:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module#safesnap",status:"warning"})):i.a.createElement(yl,{message:"This Snapshot space does not exist.",status:"error"})),M&&""===G&&i.a.createElement(yl,{message:"Missing DAO requirements ENS record.",link:"https://kleros.gitbook.io/docs/integrations/types-of-integrations/1.-dispute-resolution-integration-plan/channel-partners/kleros-reality-module#missing-daorequirements",status:"warning"}),i.a.createElement(q.a,{container:!0,spacing:2,style:{display:"flex",flexDirection:"row",marginTop:"16px"}},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Ar,{fullWidth:!0,disabled:$e,startIcon:i.a.createElement(Oc,{style:{rotate:"270deg"}}),onClick:function(){return Ye("form")}},"Return")),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(Ar,{fullWidth:!0,disabled:$e,startIcon:$e?i.a.createElement(m.Loader,{size:"xs",className:r.addSpinner}):i.a.createElement(Oc,null),onClick:function(){st()}},"Add Module")),$e&&le&&i.a.createElement(q.a,{xs:12,style:{marginLeft:"8px"}},i.a.createElement("div",null,"This can take around a minute, please wait...")))))},xl=Object(g.a)((function(e){return{addButton:{marginTop:e.spacing(2)},addTransactionButton:{marginTop:e.spacing(1)},addIcon:{stroke:e.palette.common.white,width:20,height:20},inputParam:{marginTop:e.spacing(2)},errorMessage:{marginTop:e.spacing(1),color:"red"}}})),wl=function(e){var t=e.onSubmit,a=e.open,n=e.onClose,r=dr(),o=r.sdk,l=r.safe,s=r.provider,u=xl(),d=Object(c.useState)({owner:!1,avatar:!1,target:!1,domainId:!0,sender:!0}),f=Object(x.a)(d,2),m=f[0],p=f[1],b=Object(c.useState)({owner:l.safeAddress,avatar:l.safeAddress,target:l.safeAddress,domainId:0,sender:""}),g=Object(x.a)(b,2),h=g[0],E=g[1],v=function(e,t,a){p(Object(N.a)(Object(N.a)({},m),{},Object(P.a)({},e,!a))),E(Object(N.a)(Object(N.a)({},h),{},Object(P.a)({},e,t)))},O=function(){var e=Object(k.a)(C.a.mark((function e(){var a,r;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,a=Object(N.a)({},h),r=De(s,l.safeAddress,l.chainId,a),e.next=5,o.txs.send({txs:r});case 5:t&&t(),n&&n(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),console.error("Error deploying module: ",e.t0);case 12:case"end":return e.stop()}}),e,null,[[0,9]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement(wc,{hideButton:!0,open:a,onClose:n,title:"Connext Module",description:"This module allows for execution of transactions initiated by a designated address on the other chain via Connext.",tags:["From Connext"],icon:"connext",readMoreLink:"https://github.com/gnosis/zodiac-module-connext/"},i.a.createElement(y.a,{gutterBottom:!0},"Parameters"),i.a.createElement(co,{placeholder:"Origin Sender Address",label:"Origin sender address",param:Ve.g.fromString("address"),onChange:function(e,t){return v("sender",e,t)}}),i.a.createElement(co,{placeholder:"Connext origin domain ID",label:"Connext origin domain ID",className:u.inputParam,param:Ve.g.fromString("uint256"),onChange:function(e,t){return v("domainId",e,t)}}),i.a.createElement(y.a,{className:u.errorMessage},be(l.chainId)?null:"Not supported network for the Module"),i.a.createElement(Ar,{fullWidth:!0,disableElevation:!0,className:u.addButton,variant:"contained",disabled:m.domainId||m.sender||!be(l.chainId),startIcon:i.a.createElement(Oc,null),onClick:O},"Add Module"))},jl=function(e){var t=e.selected,a=e.onClose,n=e.onSubmit;return i.a.createElement(i.a.Fragment,null,i.a.createElement(Kc,{open:t===Fe.TELLOR,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.TELLOR)}))}),i.a.createElement(Zc,{open:t===Fe.OPTIMISTIC_GOVERNOR,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.OPTIMISTIC_GOVERNOR)}))}),i.a.createElement(Xc,{open:t===Fe.DELAY,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.DELAY)}))}),i.a.createElement(ei,{open:t===Fe.BRIDGE,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.BRIDGE)}))}),i.a.createElement(ai,{open:t===Fe.EXIT,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.EXIT)}))}),i.a.createElement(oi,{open:t===Fe.ROLES_V1,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.ROLES_V1)}))}),i.a.createElement(li,{open:t===Fe.ROLES_V2,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.ROLES_V2)}))}),i.a.createElement(hi,{open:t===Fe.REALITY_ETH,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.REALITY_ETH)}))}),i.a.createElement(Ol,{open:t===Fe.KLEROS_REALITY,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.KLEROS_REALITY)}))}),i.a.createElement(wl,{open:t===Fe.CONNEXT,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.CONNEXT)}))}),i.a.createElement(Jc,{open:t===Fe.UNKNOWN,onClose:a,onSubmit:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return n&&n(Fe.UNKNOWN)}))}))},Cl=Object(g.a)((function(e){return{root:{padding:e.spacing(1.5)},gridContainer:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(180px, 1fr))",gap:e.spacing(2)},paper:{padding:e.spacing(2.5,2)},title:{marginBottom:e.spacing(2)},introBox:{gridColumn:"1/3","@media (max-width:930px)":{gridColumn:"1/2"}},firstModule:{gridColumn:1},link:{color:e.palette.text.primary}}})),kl=function(){var e=Cl(),t=ba(),a=Object(p.useSafeAppsSDK)().safe,n=ga((function(e){return Rt(e).length>0})),r=Object(c.useState)(),l=Object(x.a)(r,2),s=l[0],u=l[1],d=M.b[a.chainId],f=n?"Add another mod":"Start by adding a mod";return i.a.createElement("div",{className:e.root},i.a.createElement("div",{className:e.gridContainer},i.a.createElement("div",{className:e.introBox},i.a.createElement(h.c,{variant:"outlined",className:e.paper},i.a.createElement(y.a,{variant:"h5",className:e.title},f),i.a.createElement(y.a,{variant:"body2"},"Built according to an open standard, the Zodiac collection of tools are mods that support, expand, and transform how organizations operate. Learn more about Zodiac in"," ",i.a.createElement("a",{href:"https://gnosisguild.mirror.xyz/OuhG5s2X5uSVBx1EK4tKPhnUc91Wh9YM0fwSnC8UNcg",target:"_blank",rel:"noopener noreferrer",className:e.link},"this article")," ","and about Gnosis Safe modules more generally in"," ",i.a.createElement("a",{href:"https://help.gnosis-safe.io/en/articles/4934378-what-is-a-module",target:"_blank",rel:"noopener noreferrer",className:e.link},"this article"),"."))),i.a.createElement(uc,{title:"Bridge Module",description:"Enables an address on one chain to control an avatar on another chain using an Arbitrary Message Bridge (AMB)",icon:"bridge",onClick:function(){return u(Fe.BRIDGE)},className:e.firstModule,available:!!d[M.d.BRIDGE]}),i.a.createElement(uc,{title:"Delay Modifier",description:"Enables a time delay between when a module initiates a transaction and when it can be executed",icon:"delay",onClick:function(){return u(Fe.DELAY)},available:!!d[M.d.DELAY]}),i.a.createElement(uc,{title:"Exit Module",description:"Enables participants to redeem a designated token for a proportional share of this account\u2019digital assets",icon:"exit",onClick:function(){return u(Fe.EXIT)},available:!!d[M.d.EXIT_ERC20]}),i.a.createElement(uc,{title:"Roles Modifier",description:"Allows avatars to enforce granular, role-based, permissions for attached modules",icon:"roles",onClick:function(){return u(Fe.ROLES_V2)},available:!!d[M.d.ROLES_V2]}),i.a.createElement(uc,{title:"Reality Module",description:"Enables on-chain execution based on the outcome of events reported by the Reality.eth oracle",icon:"reality",onClick:function(){return t(ea(!0))},available:[o.MAINNET,o.GOERLI].includes(a.chainId)}),i.a.createElement(uc,{title:"Reality Module",description:"Enables on-chain execution based on the outcome of events reported by the Reality.eth oracle",icon:"reality",onClick:function(){return u(Fe.REALITY_ETH)},available:[o.MAINNET,o.GOERLI].includes(a.chainId)}),i.a.createElement(uc,{title:"Kleros Snapshot Module",description:"Execute transactions for successful Snapshot proposals using Reality.eth, secured by Kleros.",icon:"reality",onClick:function(){return u(Fe.KLEROS_REALITY)},available:fi.includes(a.chainId)}),i.a.createElement(uc,{title:"Tellor Module",description:"Enables on-chain execution of successful Snapshot proposals reported by the Tellor oracle",icon:"tellor",onClick:function(){return u(Fe.TELLOR)},available:!!d[M.d.TELLOR]}),i.a.createElement(uc,{title:"UMA oSnap Module",description:"Enables on-chain execution of successful Snapshot proposals utilizing UMA's optimistic oracle.",icon:"optimisticGov",onClick:function(){return u(Fe.OPTIMISTIC_GOVERNOR)},available:!0}),i.a.createElement(uc,{title:"Governor Module",description:"Enables an Open Zeppelin Governor contract as a module.",icon:"ozGov",onClick:function(){return t(ta(!0))},available:!!d[M.d.OZ_GOVERNOR]}),i.a.createElement(uc,{title:"Connext Module",description:"Enables an address on one chain to control an avatar on another chain using Connext as the messaging layer.",icon:"connext",onClick:function(){return u(Fe.CONNEXT)},available:!!d[M.d.CONNEXT]}),i.a.createElement(uc,{title:"Roles Modifier v1",description:"Legacy version of the Roles Modifier",icon:"roles",deprecated:!0,onClick:function(){return u(Fe.ROLES_V1)},available:!!d[M.d.ROLES_V1]}),i.a.createElement(uc,{title:"Custom Module",description:"Enable a custom contract as a module",icon:"custom",onClick:function(){return u(Fe.UNKNOWN)},available:!0})),i.a.createElement(jl,{selected:s,onClose:function(){return u(void 0)},onSubmit:function(){t(Kt(a)),t($t(!0))}}))},Sl=Object(g.a)((function(e){return{content:{padding:e.spacing(2.5),marginTop:e.spacing(3)}}})),Nl=function(e){var t=e.address,a=e.abi,n=Sl();return i.a.createElement(i.a.Fragment,null,i.a.createElement(Jo,{value:"read",disabled:!0}),i.a.createElement(h.c,{borderStyle:"double",className:n.content},i.a.createElement(Oo,{preview:!0,address:t,abi:a})))},Il=Object(g.a)((function(e){return{root:{padding:e.spacing(3)},paper:{padding:e.spacing(2.5),maxWidth:500},title:{marginBottom:e.spacing(2)},header:{display:"grid",gridTemplateColumns:"50px auto",gridGap:e.spacing(2),alignItems:"center",marginBottom:e.spacing(3)},addressText:{margin:e.spacing(0,2,0,3),fontWeight:"bold"},icon:{marginLeft:"16px"},buttons:{marginTop:e.spacing(3),opacity:.5}}}));function Tl(){var e=ga(Ht);if(!e)return null;var t=Ze(e.module);return t&&t.abi?i.a.createElement(Nl,{address:e.address,abi:t.abi}):null}var Al=function(){var e=Il(),t=1===ga(Vt);return i.a.createElement("div",{className:e.root},i.a.createElement("div",{className:e.header},i.a.createElement(xa.a,{variant:"circle",width:50,height:50}),i.a.createElement(xa.a,{variant:"rect",width:380,height:20})),t?i.a.createElement(Tl,null):i.a.createElement(h.c,{borderStyle:"double",className:e.paper},i.a.createElement(y.a,{variant:"h5",className:e.title},"Waiting on module approval"),i.a.createElement(y.a,null,"Once this module transaction has been approved by the other signers, you will be able to read and write to it.")))},Rl=a(1720),Ml=a(711),Bl=a(518),Dl=a(706),Ll=a(1721),Pl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{padding:"9px 8px",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}}}})),Fl=function(e){var t=e.data,a=e.setData,n=Pl(),r=1===Object(p.useSafeAppsSDK)().safe.chainId?Ql:Jl,o=Object(c.useState)(""),l=Object(x.a)(o,2),s=l[0],u=l[1];Object(c.useEffect)((function(){if(t&&r.length&&""===s){var e=r.filter((function(e){return e.label.includes(t.instanceAddress)}));u(e[0].value)}}),[t,r,s]);var d=function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}},f=function(e){return t[e]};return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Oracle Instance")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"The oracle instance sets the appropriate bond token. It's recommended to use the default (ETH) oracle instance unless you have a specific reason to use something like a native token which can potentially be more prone to price manipulation.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(al,{value:s,options:r,disableUnderline:!0,label:"Select oracle:",onChange:function(e){!function(e){if("custom"!==e){var t=e.substr(e.indexOf("-")+1),a=e.substr(0,e.indexOf("-"));u(e),d("instanceAddress")(t),d("instanceType")(a)}else d("instanceType")(e)}(e.target.value)}})),"custom"===f("instanceType")&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",spacing:1},i.a.createElement(q.a,{item:!0,sm:10},i.a.createElement(h.e,{label:"Contract Address",value:f("instanceAddress"),borderStyle:"double",className:n.input,onChange:function(e){return d("instanceAddress")(e.target.value)}})),i.a.createElement(q.a,{item:!0,sm:2},i.a.createElement(y.a,{style:{marginTop:15}},"WEENUS")))))},Ul=function(e,t,a){var n=parseInt(t),r=parseInt(a);switch(e){case"timeout":if(n<86400)return!1;break;case"cooldown":if(n<=0)return!1;break;case"expiration":if(0===n)return!0;if(a&&n=86400&&a<172800)return!1;break;case"cooldown":if(a>=0&&a<172800)return!1;break;case"expiration":if(0===a)return!1;if(a>=86400&&a<432e3)return!1}return!0},Hl=Object(g.a)((function(){return{errorIcon:{fill:"rgba(244, 67, 54, 1)"},warningIcon:{fill:h.f.tan[800]},message:{fontSize:12,color:"rgba(244, 67, 54, 1)"},warningMessage:{fontSize:12,color:h.f.tan[800]}}})),_l=function(e){var t=e.type,a=e.message,n=Hl();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},"error"===t&&i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:n.errorIcon})," "),"warning"===t&&i.a.createElement(q.a,{item:!0},i.a.createElement(Do.a,{className:n.warningIcon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:"error"===t?n.message:n.warningMessage},a)))},Gl=function(e){var t=e.type,a=e.delayValue,n=e.dependsDelayValue,r=Ul("timeout",parseInt(a)),o=Ul("cooldown",parseInt(a)),l=Ul("expiration",parseInt(a),n),s=Vl("timeout",parseInt(a)),u=Vl("cooldown",parseInt(a)),d=Vl("expiration",parseInt(a)),f=Object(c.useState)(void 0),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)(void 0),h=Object(x.a)(g,2),E=h[0],v=h[1],y=Object(c.useState)(void 0),O=Object(x.a)(y,2),w=O[0],j=O[1];return Object(c.useEffect)((function(){return r?s?void b(void 0):b({type:"warning",message:"We highly recommend that your timeout delay exceeds 48 hours."}):b({type:"error",message:"Your timeout delay must exceed 24 hours."})}),[r,s]),Object(c.useEffect)((function(){return o?u?void v(void 0):v({type:"warning",message:"We highly recommend that your cooldown delay exceeds 48 hours."}):v({type:"error",message:"Your cooldown delay must exceed 0"})}),[o,u]),Object(c.useEffect)((function(){return l?d?void j(void 0):j({type:"warning",message:"We highly recommend that your expiration delay exceeds cooldown + 5 days."}):j({type:"error",message:"Your expiration delay must exceeds cooldown + 1 days."})}),[l,d]),i.a.createElement(c.Fragment,null,"timeout"===t&&p&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:p.type,message:p.message})),"cooldown"===t&&E&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:E.type,message:E.message})),"expiration"===t&&w&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:w.type,message:w.message})))},Wl=Object(g.a)((function(){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"}}})),zl=function(e){var t=e.data,a=e.setData,n=Wl(),r=function(e){return t[e]},o=r("timeout"),c=r("cooldown"),l=r("expiration"),s=Ul("timeout",o),u=Ul("cooldown",c),d=Ul("expiration",l,c);return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Delay Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"These Parameters are very important for your DAO's security and should be considered carefully. Allowing enough time in these configurations will enable the safe to have a final chance to veto or circumvent any potential malicious proposals that have snuck through.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:6,alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:s?"secondary":"error",alertType:s?void 0:"error",label:"Timeout",tooltipMsg:"Duration that answers can be submitted to the oracle (resets when a new answer is submitted)",valueUnit:r("timeoutUnit"),value:o,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{timeout:e,timeoutUnit:n}))}})),i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:u?"secondary":"error",alertType:u?void 0:"error",label:"Cooldown",tooltipMsg:"Duration required before the transaction can be executed (after the timeout has expired).",valueUnit:r("cooldownUnit"),value:c,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{cooldown:e,cooldownUnit:n}))}})),i.a.createElement(q.a,{item:!0,xs:4},i.a.createElement(Vo,{variant:d?"secondary":"error",alertType:d?void 0:"error",label:"Expiration",tooltipMsg:"Duration that a transaction is valid in seconds (or 0 if valid forever) after the cooldown (note this applies to all proposals on this module).",valueUnit:r("expirationUnit"),value:null!==l&&void 0!==l?l:0,onChange:function(e,n){a(Object(N.a)(Object(N.a)({},t),{},{expiration:e,expirationUnit:n}))}})))),i.a.createElement(Gl,{type:"timeout",delayValue:parseInt(o)}),i.a.createElement(Gl,{type:"cooldown",delayValue:parseInt(c)}),i.a.createElement(Gl,{type:"expiration",delayValue:parseInt(l),dependsDelayValue:parseInt(c)}))},Kl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},error:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}}}})),Yl=function(e){var t=e.data,a=e.setData,n=Kl(),r=t["bond"];return i.a.createElement(q.a,{container:!0,spacing:2,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:n.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Bond")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:n.textSubdued},"Minimum bond required for an answer to be accepted. New answers must be submitted with double the previous bond. For more on why a bond is required in an escalation-game-based oracle, read more in the"," ",i.a.createElement(Ma.a,{underline:"always",href:"http://reality.eth.link/app/docs/html/whitepaper.html",target:"_blank",color:"inherit"},"Reality.eth whitepaper."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Bond",color:"secondary",borderStyle:"double",className:r<.1?n.error:n.input,prefix:"ETH",value:r,onChange:function(e){return function(e){return function(n){return a(Object(N.a)(Object(N.a)({},t),{},Object(P.a)({},e,n)))}}("bond")(e.target.value)}})),r<.1&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:"warning",message:"We highly recommend that your bond exceeds 0.1 ETH."})))},Zl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},textSubdued:{color:"rgba(255 255 255 / 70%)"}}})),ql=function(e){var t,a=e.data,n=e.setData,r=Zl();return i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Arbitration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"An arbitrator is responsible for providing a final answer to a question when there is a dispute, in exchange for a fee. In most cases, the bond escalation-game eliminates the need for this. However, if you feel it's necessary to include a backup arbitration strategy incase of a dispute, you can select one from below. Read more in the"," ",i.a.createElement(Ma.a,{underline:"always",href:"https://reality.eth.link/app/docs/html/arbitrators.html",target:"_blank",color:"inherit"},"Reality.eth arbitrators documentation"),".")))),i.a.createElement(q.a,{item:!0},i.a.createElement(al,{value:(t="arbitratorOption",a[t]),options:[{label:"No arbitration (highest bond wins)",value:oe.NO_ARBITRATOR},{label:"Kleros",value:oe.KLEROS}],disableUnderline:!0,label:"Arbitrator:",onChange:function(e){var t=e.target;return function(e){return function(t){return n(Object(N.a)(Object(N.a)({},a),{},Object(P.a)({},e,t)))}}("arbitratorOption")(t.value)}})))},Xl=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},icon:{fill:"white",width:"20px"},divider:{marginTop:8,marginBottom:8},warningModal:{maxWidth:650},errorPaperContainer:{width:"100%",padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)",border:0,borderRadius:4,display:"inline-block","& .MuiTypography-root":{fontFamily:"Roboto Mono"}}}})),Ql=[{label:"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c",value:"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c"},{label:"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9",value:"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9"}],Jl=[{label:"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f",value:"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f"}],$l=function(e){var t=e.handleBack,a=e.handleNext,n=e.setupData,r=Xl(),o=1===Object(p.useSafeAppsSDK)().safe.chainId?Ql:Jl,l=Object(c.useState)(!1),s=Object(x.a)(l,2),u=s[0],d=s[1];if(null==(null===n||void 0===n?void 0:n.proposal.ensName))throw new Error("ENS name is not set");var f=Object(c.useState)({templateType:"default",language:"english",category:"DAO proposal",templateQuestion:rl(null===n||void 0===n?void 0:n.proposal.ensName)}),m=Object(x.a)(f,2),b=m[0],g=m[1],E=Object(c.useState)({instanceAddress:o[0].value.substr(o[0].value.indexOf("-")+1),instanceType:o[0].value.substr(0,o[0].value.indexOf("-"))}),v=Object(x.a)(E,2),w=v[0],j=v[1],C=Object(c.useState)({timeout:172800,timeoutUnit:"days",cooldown:172800,cooldownUnit:"days",expiration:604800,expirationUnit:"days"}),k=Object(x.a)(C,2),S=k[0],N=k[1],I=Object(c.useState)({bond:.1}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=S.timeout,B=S.cooldown,D=S.expiration,L=A.bond,P=Ul("timeout",M),F=Ul("cooldown",B),U=Ul("expiration",D,B),V=Vl("timeout",M),H=Vl("cooldown",B),_=Vl("expiration",D),G=Object(c.useState)({arbitratorOption:oe.NO_ARBITRATOR}),W=Object(x.a)(G,2),z=W[0],K=W[1],Y=function(){return{templateData:b,instanceData:w,delayData:S,bondData:A,arbitratorData:z}};if(Object(c.useEffect)((function(){if(n&&n.oracle){var e=n.oracle,t=e.bondData,a=e.delayData,r=e.instanceData,o=e.templateData,c=e.arbitratorData;R(t),N(a),j(r),g(o),K(c)}}),[n]),null==(null===n||void 0===n?void 0:n.proposal.ensName))throw new Error("The ENS name is not available, it needs to already be in the setupData, before initiating this step.");return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Set up the Oracle")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Now, it's time to set up the oracle for your reality module. The oracle ensures the results of proposals are brought accurately on-chain. The Reality.eth oracle uses a mechanism known as the"," ",i.a.createElement(Xa,{underline:"always",href:"https://reality.eth.limo/app/docs/html/whitepaper.html",target:"_blank",color:"inherit"},"escalation game")," ","to generate correct answers that can be used as inputs for smart contracts. The following parameters are very important for your DAO's security and should be considered carefully.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(sl,{data:b,setData:g,ensName:null===n||void 0===n?void 0:n.proposal.ensName})),i.a.createElement(q.a,{item:!0},i.a.createElement(Fl,{data:w,setData:j})),i.a.createElement(q.a,{item:!0},i.a.createElement(zl,{data:S,setData:N})),i.a.createElement(q.a,{item:!0},i.a.createElement(Yl,{data:A,setData:R})),i.a.createElement(q.a,{item:!0},i.a.createElement(ql,{data:z,setData:K})),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return t(Y())}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:[P,F,U].includes(!1),onClick:function(){if([V,H,_].includes(!1)||L<.1)return d(!0);a(Y())}},"Next"))))),i.a.createElement(h.b,{className:r.warningModal,open:u,isOpen:u,onClose:function(){return d(!u)},children:i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:r.icon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4"},"Security Risk Detected")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"The following security risks have been detected. We highly recommend that you resolve them before moving forward, as these can leave to loss of funds.")),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:r.errorPaperContainer},i.a.createElement(Gl,{type:"timeout",delayValue:M}),i.a.createElement(Gl,{type:"cooldown",delayValue:B}),i.a.createElement(Gl,{type:"expiration",delayValue:D,dependsDelayValue:B}),L<.1&&i.a.createElement(q.a,{item:!0},i.a.createElement(_l,{type:"warning",message:"We highly recommend that your bond exceeds 0.1 ETH."})))),i.a.createElement(q.a,{item:!0,className:r.divider},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,alignItems:"center",justifyContent:"center",spacing:3},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",onClick:function(){return a(Y())}},"Proceed")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",onClick:function(){return d(!1)}},"Resolve (Recommended)")))))}))},es=Object(g.a)((function(e){return{icon:{fill:"white",width:"20px"},paperContainer:{padding:e.spacing(2),background:"rgba(244, 67, 54, 0.1)",border:"1px solid rgba(244, 67, 54, 0.3)","&, &:before, &:after":{border:"1px solid rgba(244, 67, 54, 0.3)"}},addressPaperContainer:{width:"100%",padding:e.spacing(1),background:"rgba(0, 0, 0, 0.2)",border:0,borderRadius:4,display:"inline-block","& .MuiTypography-root":{fontFamily:"Roboto Mono"}}}})),ts=function(e){var t=e.title,a=e.type,n=e.address,r=es();return i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(Mo.a,{className:r.icon})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4"},t)))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"controller"===a&&"The safe you are currently using with Zodiac is not the controller of the ENS you've entered. Try one of the following: ","owner"===a&&"The ENS that you've entered is not owned by a safe. This gives unilateral control to the individual with this address: ","safesnap"===a&&"The Snapshot space has already installed the Safesnap plugin.","snapshot"===a&&t.includes("Invalid")&&"The current snapshot settings file is invalid. Check the browser console for validation details. The schema for validating the settings file can be found","snapshot"===a&&t.includes("Invalid")&&i.a.createElement(i.a.Fragment,null," ",i.a.createElement(Xa,{underline:"always",href:"https://github.com/snapshot-labs/snapshot.js/blob/master/src/schemas/space.json",target:"_blank",color:"inherit"},"here.")),"snapshot"===a&&!t.includes("Invalid")&&"The ENS you've entered is not setup with a Snapshot space. To setup a snapshot space with this ENS, follow the guide","snapshot"===a&&!t.includes("Invalid")&&i.a.createElement(i.a.Fragment,null," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.snapshot.org/spaces/create",target:"_blank",color:"inherit"},"here.")))),n&&i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"double",className:r.paperContainer},i.a.createElement(h.c,{borderStyle:"single",className:r.addressPaperContainer},i.a.createElement(y.a,{variant:"body2"},n)))),["controller","owner"].includes(a)&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"controller"===a&&"- Check that your ENS is typed correctly.","owner"===a&&"We highly recommend transferring the ENS to a multisig safe before continuing.")),"controller"===a&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"- Update your ENS controller settings via the"," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.ens.domains/contract-api-reference/.eth-permanent-registrar/controller",target:"_blank",color:"inherit"},"ENS."))))},as=Object(g.a)((function(e){return{message:{fontSize:12,color:"rgba(244, 67, 54, 1)"},messageDetails:{fontSize:12,textDecoration:"underline",cursor:"pointer"},errorIcon:{fill:"rgba(244, 67, 54, 1)",width:"20px"},detailsContainer:{width:"95%"},messageContainer:{width:"85%"}}})),ns=function(e){var t=e.status,a=e.message,n=e.type,r=e.address,o=as(),l=Object(c.useState)(!1),s=Object(x.a)(l,2),u=s[0],d=s[1],f=function(){switch(n){case"controller":return"Safe not controller of ENS";case"owner":return"Security Risk Detected";case"snapshot":return(null===a||void 0===a?void 0:a.includes("invalid"))?"Invalid Snapshot settings file":"Snapshot space not found";case"safesnap":return"Safesnap plugin is already installed";default:return""}}();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},"error"===t&&i.a.createElement(Mo.a,{className:o.errorIcon}),"warning"===t&&i.a.createElement(dl.a,{className:o.errorIcon})),i.a.createElement(q.a,{item:!0,className:o.detailsContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0,className:o.messageContainer},i.a.createElement(y.a,{className:o.message},a)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:o.messageDetails,onClick:function(){return d(!u)}},"Details")))),i.a.createElement(h.b,{open:u,isOpen:u,onClose:function(){return d(!u)},children:i.a.createElement(ts,{title:f,type:n,address:r})}))},rs=function(e,t,a,n,r,o,c){if(!t){if("snapshot"===e&&!r)return"error";if("snapshot"===e&&!o)return"error";if("controller"===e&&!a)return"error";if("safesnap"===e&&c)return"error";if("owner"===e&&!n)return"warning"}return null},os=function(e,t,a,n,r,o){return"snapshot"!==e||n?"snapshot"!==e||r?"controller"!==e||t?"owner"!==e||a?"safesnap"===e&&o?"The plugin is already installed on the Snapshot space.":null:"The safe is not the owner of the ENS name. We highly recommend transferring the ENS to this safe or enter a different ENS before continuing.":"The safe must be the controller of the ENS name.":"Your snapshot settings file is invalid.":"The ENS name should have a Snapshot space created."},cs=a(265),is=a.n(cs),ls=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},doneIcon:{marginRight:4,fill:"#A8E07E",width:"16px"},errorIcon:{marginRight:4,fill:"rgba(244, 67, 54, 1)",width:"16px"},loadingContainer:{marginRight:4,padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:14,width:14,border:"1px solid ".concat(h.f.tan[300])},spinner:{width:"8px !important",height:"8px !important",color:"".concat(h.f.tan[300]," !important")},loading:{width:"15px !important",height:"15px !important",marginRight:8},radio:{marginLeft:-2,padding:2,"& ~ .MuiFormControlLabel-label":{fontSize:12,marginLeft:4},"&$checked":{color:h.f.tan[1e3]}},checked:{},textSubdued:{color:"rgba(255 255 255 / 70%)"},textFieldSmall:{"& .MuiFormLabel-root":{fontSize:12}},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}},errorContainer:{margin:8,display:"flex",alignItems:"center"}}})),ss=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=dr(),o=r.safe,l=r.provider,s=ls(),u=Object(c.useState)(""),d=Object(x.a)(u,2),f=d[0],p=d[1],b=Object(c.useState)(""),g=Object(x.a)(b,2),E=g[0],v=g[1],w=Object(c.useState)(!1),j=Object(x.a)(w,2),S=j[0],N=j[1],I=Object(c.useState)(!1),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object(c.useState)(!1),B=Object(x.a)(M,2),D=B[0],L=B[1],P=Object(c.useState)(!1),F=Object(x.a)(P,2),U=F[0],V=F[1],H=Object(c.useState)(!1),_=Object(x.a)(H,2),G=_[0],W=_[1],z=Object(c.useState)(!1),K=Object(x.a)(z,2),Y=K[0],Z=K[1],X=Object(c.useState)(!1),Q=Object(x.a)(X,2),$=Q[0],ee=Q[1];Object(c.useEffect)((function(){l&&n&&n.proposal&&p(n.proposal.ensName)}),[]),Object(c.useEffect)((function(){f&&(f.includes(".eth")?(ee(!0),Z(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,te();case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()()):(ee(!1),L(!1),N(!1)))}),[f]);var te=function(){var e=Object(k.a)(C.a.mark((function e(){var t,a,n,r,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,l.resolveName(f);case 2:if(!(t=e.sent)){e.next=26;break}return e.next=6,Hi(f,o.chainId);case 6:return a=e.sent,n=_i(a),e.next=10,Di(l,f,o.safeAddress);case 10:return r=e.sent,e.next=13,Pi(l,f,o.safeAddress);case 13:return c=e.sent,(i=null===a||void 0===a?void 0:a.plugins)&&R(!!i.safeSnap),!0!==n&&(console.log("The current snapshot space is not valid. Valid snapshot space schema. Errors:"),console.log(JSON.stringify(_i(a),void 0,2))),V(!!a),W(!0===n),N(r),L(c),v(t),Z(!1),e.abrupt("return");case 26:return v(""),Z(!1),N(!1),L(!1),V(!1),W(!1),R(!1),e.abrupt("return");case 34:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),ae=function(){return{ensName:f}};return i.a.createElement(h.c,{borderStyle:"single",className:s.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Configure Proposal Space")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Add your preferred proposal type below to get started. If you're unsure, we recommend starting with Snapshot.")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Don't have a snapshot space setup yet?"," ",i.a.createElement(Xa,{underline:"always",href:Rn(o,"https://snapshot.org/#/setup?step=1"),target:"_blank",color:"inherit"},"Get started here."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:s.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Proposal Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:s.textSubdued},"Enter your snapshot space ENS domain below to get started. The Safe must be the controller of this ENS domain.")),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{value:f,onChange:function(e){var t,a=e.target;""===(t=a.value)?(L(!1),N(!1),V(!1),W(!1),p("")):p(t)},label:"Enter the Snapshot ENS name.",placeholder:"ex: gnosis.eth",borderStyle:"double",className:"".concat(s.textFieldSmall," ").concat(!f.includes(".eth")||Y||U&&D&&S?s.input:s.inputError),rightIcon:i.a.createElement(i.a.Fragment,null,Y&&i.a.createElement(J.a,{className:s.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:s.spinner})),f.includes(".eth")&&!Y&&(!U||!D||!S)&&i.a.createElement(Mo.a,{className:s.errorIcon}),f.includes(".eth")&&!Y&&U&&D&&S&&i.a.createElement(is.a,{className:s.doneIcon}))}),i.a.createElement("br",null),i.a.createElement("br",null),$&&i.a.createElement(i.a.Fragment,null,i.a.createElement(ns,{type:"snapshot",status:rs("snapshot",Y,!1,!1,U,G,!1),message:os("snapshot",!1,!1,U,G,!1)}),i.a.createElement(ns,{type:"safesnap",status:rs("safesnap",Y,!1,!1,!1,!1,A),message:os("safesnap",!1,!1,!1,!1,A)}),i.a.createElement(ns,{type:"controller",status:rs("controller",Y,D,!1,!1,!1,!1),message:os("controller",D,!1,!1,!1,!1)}),i.a.createElement(ns,{type:"owner",status:rs("owner",Y,!1,S,!1,!1,!1),message:os("owner",!1,S,!1,!1,!1),address:E}))))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(ae())}},"Cancel")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:!D||A,onClick:function(){return t(ae())}},"Next"))))))},us=Object(g.a)((function(e){return{circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:25,width:25,border:"1px solid ".concat(h.f.tan[300]),background:h.f.blue[500]},label:{display:"inline",fontFamily:"Roboto Mono",cursor:"pointer","&:hover":{textDecoration:"underline"}}}})),ds=function(e){var t=e.label,a=e.number,n=e.disabled,r=e.onClick,o=us();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center",onClick:function(){!n&&r()}},i.a.createElement(q.a,{item:!0},i.a.createElement(J.a,{className:o.circle},i.a.createElement(y.a,null,a))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:o.label},t)))},fs=a(383),ms=a.n(fs),ps=a(753),bs=a.n(ps),gs=a(752),hs=a.n(gs),Es=a(382),vs=a.n(Es),ys=Object(g.a)((function(e){return{message:{fontSize:"0.9rem"},messageError:{fontSize:"0.9rem",color:"rgba(244, 67, 54, 1)"},circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,background:h.f.tan[1e3]},loadingContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid ".concat(h.f.tan[300])},errorContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.3)"},errorIcon:{width:"12px",height:"12px",color:"#F44336"},loading:{width:"12px !important",height:"12px !important",color:"".concat(h.f.tan[300]," !important")},doneIcon:{fill:"black",width:"16px"}}})),Os=function(e){var t=e.statusLog,a=ys();return i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},t.map((function(e,n){return i.a.createElement(q.a,{item:!0,xs:12,key:"status-".concat(n)},i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center",key:n},i.a.createElement(q.a,{item:!0},t.length>n+1&&!e.error&&i.a.createElement(J.a,{className:a.circle},i.a.createElement(is.a,{className:a.doneIcon})),t.length===n+1&&!e.error&&i.a.createElement(J.a,{className:a.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:a.loading})),t.length===n+1&&e.error&&i.a.createElement(J.a,{className:a.errorContainer},i.a.createElement(vs.a,{className:a.errorIcon}))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:e.error?a.messageError:a.message},e.msg))))})))},xs=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},paperTemplateContainer:{marginTop:4,padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)"},textSubdued:{color:"rgba(255 255 255 / 70%)"},icon:{fill:"white",cursor:"pointer"},collapse:{textDecoration:"underline",cursor:"pointer"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},textarea:{"& .MuiInputBase-root":{padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},link:{fontFamily:"Roboto Mono",fontSize:12,textDecoration:"underline",fontWeight:"bold"},label:{fontFamily:"Roboto Mono",fontSize:12,fontWeight:"bold"},loading:{width:"15px !important",height:"15px !important"}}})),ws=[{label:"Proposal",number:1,section:0},{label:"Oracle",number:2,section:1},{label:"Monitoring",number:3,section:2}],js=i.a.createElement(y.a,{variant:"body2"},"This will add a time delay to any transactions created by this module."," ",i.a.createElement("b",null,"Note that this delay is cumulative with the cooldown set above")," (e.g. if both are set to 24 hours, the cumulative delay before the transaction can be executed will be 48 hours)."),Cs=function(e){var t=e.handleBack,a=e.handleNext,n=e.goToStep,r=e.delayModules,l=e.setupData,s=e.loading,u=e.statusLog,d=xs(),f=Object(p.useSafeAppsSDK)().safe,b=Object(c.useState)(),g=Object(x.a)(b,2),E=g[0],v=g[1],w=Object(c.useState)(!1),j=Object(x.a)(w,2),C=j[0],k=j[1],S=Object(c.useState)(void 0),N=Object(x.a)(S,2),I=N[0],A=N[1],R=Object(c.useState)(1===r.length?r[0].address:""),M=Object(x.a)(R,2),B=M[0],D=M[1],L=l&&l.monitoring;return Object(c.useEffect)((function(){var e,t;l&&l.proposal&&v((e=f.chainId,t=l.proposal.ensName,(e===o.GOERLI?"https://testnet.snapshot.org":"https://snapshot.org")+"/#/".concat(t))),l&&l.oracle&&A(l.oracle)}),[l]),i.a.createElement(h.c,{borderStyle:"single",className:d.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:d.container},!C&&i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:d.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Review")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Here is an overview of your reality module configuration. Please review carefully. Once you've confirmed that the details are correct, you can submit the transaction which will add the reality module to this safe, and automatically integrate the SafeSnap plugin with the snapshot space you've include.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),ws.map((function(e){return i.a.createElement(i.a.Fragment,{key:e.label},i.a.createElement(q.a,{item:!0},i.a.createElement(ds,{label:e.label,number:e.number,disabled:s,onClick:function(){return n(e.section)}})),"Proposal"===e.label&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Snapshot Space:"),i.a.createElement(Ma.a,{color:"inherit",href:E,target:"_blank",className:d.link},E)),"Oracle"===e.label&&I&&l&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Template question preview:"),i.a.createElement(h.c,{className:d.paperTemplateContainer},i.a.createElement(y.a,null,l.oracle.templateData.templateQuestion))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Oracle Address:"),i.a.createElement(Ma.a,{color:"inherit",href:"".concat(H[f.chainId],"/search?f=0&q=").concat(I.instanceData.instanceAddress),target:"_blank",className:d.link},I.instanceData.instanceAddress)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,justifyContent:"space-between",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Timeout:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.timeout).div(Lo[I.delayData.timeoutUnit]).toString()," ",I.delayData.timeoutUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Cooldown:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.cooldown).div(Lo[I.delayData.cooldownUnit]).toString()," ",I.delayData.cooldownUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Expiration:"),i.a.createElement(y.a,{className:d.label},T.a.from(I.delayData.expiration).div(Lo[I.delayData.expirationUnit]).toString()," ",I.delayData.expirationUnit)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Bond:"),i.a.createElement(y.a,{className:d.label},I.bondData.bond," ETH")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Arbitrator:"),i.a.createElement(y.a,{className:d.label},0===I.arbitratorData.arbitratorOption&&"No arbitration (highest bond wins)",1===I.arbitratorData.arbitratorOption&&"Kleros")))),"Monitoring"===e.label&&L&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"API key/secret:"),i.a.createElement(y.a,{className:d.label},"Valid")),L.email.length>0&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Emails:"),L.email.map((function(e,t){return i.a.createElement(y.a,{className:d.label,key:t},"- ",e)}))),""!==L.discordKey&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Discord:"),i.a.createElement(y.a,{className:d.label},L.discordKey)),""!==L.telegram.botToken&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Telegram:"),i.a.createElement(y.a,{className:d.label},"Bot token: ",L.telegram.botToken),i.a.createElement(y.a,{className:d.label},"Chat ID: ",L.telegram.chatId)),""!==L.slackKey&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Slack:"),i.a.createElement(y.a,{className:d.label},L.slackKey)))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)))})),r.length>=1&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h6",gutterBottom:!0},"Deploy Options"),i.a.createElement(Wc,{description:js,modules:r,value:B,onChange:function(e){return D(e)},type:Fe.DELAY}))))),u.length>0&&i.a.createElement(q.a,{item:!0,onClick:function(){return k(!C)}},i.a.createElement(q.a,{container:!0,spacing:1},i.a.createElement(q.a,{item:!0},C?i.a.createElement(bs.a,{className:d.icon}):i.a.createElement(hs.a,{className:d.icon})),i.a.createElement(q.a,{item:!0,className:d.collapse},i.a.createElement(y.a,null,C?"Show More":"Show Less")))),u.length>0&&i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:d.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Setting up Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(Os,{statusLog:u})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:t,disabled:s},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",startIcon:s?i.a.createElement(m.Loader,{className:d.loading,size:"sm",color:"background"}):i.a.createElement(ms.a,null),disabled:s,onClick:function(){k(!0),a(l)}},"Submit"))))))},ks=a(755),Ss=Object(g.a)((function(e){return{paperContainer:{background:"rgba(0, 0, 0, 0.2)"},message:{fontSize:12,color:"rgba(244, 67, 54, 1)"}}})),Ns={control:function(e,t){return Object(N.a)(Object(N.a)({},e),{},{background:"none",border:"none",fontFamily:"Roboto Mono !important",color:"yellow !important",boxShadow:(t.isFocused,null),"&:hover":{border:"none"}})},option:function(e){return Object(N.a)(Object(N.a)({},e),{},{color:"white",backgroundColor:"#101010",cursor:"pointer"})},menu:function(e){return Object(N.a)(Object(N.a)({},e),{},{borderRadius:0,backgroundColor:"#101010",marginTop:0})},menuList:function(e){return Object(N.a)(Object(N.a)({},e),{},{padding:0})},multiValue:function(e){return Object(N.a)(Object(N.a)({},e),{},{color:"white !important",background:h.f.tan[300],maxWidth:"calc(28% - 4px)","&:hover":{background:h.f.tan[300]},"& > div":{color:"white !important"},"& > div[role=button]:hover":{cursor:"pointer",color:"blue",background:h.f.tan[500]}})}},Is=function(e){var t=Ss();return i.a.createElement(q.a,{container:!0,spacing:1,direction:"column"},i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{className:t.paperContainer,borderStyle:"double"},i.a.createElement(ks.a,Object.assign({},e,{isMulti:!0,styles:Ns,options:e.options,theme:function(e){return Object(N.a)(Object(N.a)({},e),{},{colors:Object(N.a)(Object(N.a)({},e.colors),{},{font:"#101010",primary25:"#101010",primary:"#101010",neutral80:"white"})})}})))),e.invalidText&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:t.message},e.invalidText)))},Ts=function(e){var t=Object(c.useRef)();return Object(c.useEffect)((function(){t.current=e}),[e]),t.current},As=Object(g.a)((function(e){return{message:{fontSize:"0.9rem"},messageError:{fontSize:"0.8rem",color:"rgba(244, 67, 54, 1)"},circle:{padding:6,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,background:h.f.tan[1e3]},loadingContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid ".concat(h.f.tan[300])},errorContainer:{padding:2,display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"50%",height:20,width:20,border:"1px solid rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.3)"},errorIcon:{width:"12px",height:"12px",color:"#F44336"},loading:{width:"12px !important",height:"12px !important",color:"".concat(h.f.tan[300]," !important")},doneIcon:{fill:"black",width:"16px"}}})),Rs=function(e){var t=e.status,a=e.message,n=As();return t&&i.a.createElement(q.a,{container:!0,spacing:1,alignItems:"center"},i.a.createElement(q.a,{item:!0},"success"===t&&i.a.createElement(J.a,{className:n.circle},i.a.createElement(is.a,{className:n.doneIcon})),"loading"===t&&i.a.createElement(J.a,{className:n.loadingContainer},i.a.createElement(m.Loader,{size:"sm",className:n.loading})),"error"===t&&i.a.createElement(J.a,{className:n.errorContainer},i.a.createElement(vs.a,{className:n.errorIcon}))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{className:"error"===t?n.messageError:n.message},a)))},Ms=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},textSubdued:{color:"rgba(255 255 255 / 70%)"},inputContainer:{width:"50%"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}},textarea:{"& .MuiInputBase-root":{padding:e.spacing(2),background:"rgba(0, 0, 0, 0.2)",borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},spinner:{width:"8px !important",height:"8px !important",color:"".concat(h.f.tan[300]," !important")}}})),Bs={apiKey:"",secretKey:"",email:[],discordKey:"",telegram:{botToken:"",chatId:""},slackKey:""},Ds=function(e){var t=e.handleBack,a=e.handleNext,n=e.setupData,r=Ms(),o=hl(),l=o.loading,s=o.execute,u=o.error,d=null===n||void 0===n?void 0:n.monitoring,f=Object(c.useState)(null!==d&&void 0!==d?d:Bs),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)([]),E=Object(x.a)(g,2),v=E[0],w=E[1],j=Object(c.useState)(!1),S=Object(x.a)(j,2),I=S[0],T=S[1],A=Object(c.useState)(!1),R=Object(x.a)(A,2),M=R[0],B=R[1],D=p.apiKey,L=p.secretKey,F=p.email,U=p.discordKey,V=p.slackKey,H=p.telegram,_=Ts(D),G=Ts(L);Object(c.useEffect)((function(){if(d&&d.email.length){var e=[];d.email.forEach((function(t){return e.push({label:t,value:t})})),w(e)}}),[d]),Object(c.useEffect)((function(){l||[D,L].includes("")||M||(B(!0),function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,s(D,L);case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()())}),[D,L,l,M,s]),Object(c.useEffect)((function(){_===D&&G===L||!M||B(!1)}),[D,L,_,G,M]);var W=function(e,t){if(e.preventDefault(),["chatId","botToken"].includes(t)){var a=Object(N.a)({},p.telegram),n=Object(N.a)(Object(N.a)({},a),{},Object(P.a)({},t,e.target.value));b(Object(N.a)(Object(N.a)({},p),{},{telegram:n}))}else b(Object(N.a)(Object(N.a)({},p),{},Object(P.a)({},t,e.target.value)))};return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Configure Monitoring")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Setting up an effective monitoring strategy is critical for the security of your safe. In order to set up the monitoring for this module, you'll need to first"," ",i.a.createElement(Xa,{underline:"always",href:"https://defender.openzeppelin.com/#/auth/sign-in",target:"_blank",color:"inherit"},"create an Open Zeppelin account."))))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"API Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Include the API Key and Secret Key from your Open Zeppelin account below. Follow the Open Zeppelin guide ","",i.a.createElement(Xa,{underline:"always",href:"https://docs.openzeppelin.com/defender/guide-factory#generate-api-key",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"API Key",placeholder:"0f9u8yuiahkjdh8qhiflahfjajdhafa",borderStyle:"double",value:p.apiKey,onChange:function(e){return W(e,"apiKey")},className:u?r.inputError:r.input})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"API Secret",placeholder:"hkjdh8qhiflahfjajdhafa0f9u8yuiahkjdh8qhiflahfjajdhafa",value:p.secretKey,onChange:function(e){return W(e,"secretKey")},borderStyle:"double",className:u?r.inputError:r.input})),i.a.createElement(q.a,{item:!0},i.a.createElement(Rs,{status:l?"loading":u?"error":u||"boolean"!==typeof u?null:"success",message:l?"Validating API credentials...":u?"The API credentials that you have provided are not valid. Please verify that you have the correct information.":u||"boolean"!==typeof u?null:"API credentials are valid."})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Email")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Add as many emails as you'd like.")),i.a.createElement(q.a,{item:!0},i.a.createElement(Is,{invalidText:I?"Please provide a valid email":void 0,onChange:function(e){return function(e){var t,a=null===(t=e[e.length-1])||void 0===t?void 0:t.value;!function(e){return/\S+@\S+\.\S+/.test(e)}(a)&&null!=a?T(!0):(T(!1),w(e),b(Object(N.a)(Object(N.a)({},p),{},{email:e.map((function(e){return e.value}))})))}(e)},value:v})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Discord")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Discord integration, include the Discord channel's url including key below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Discord Key",placeholder:"key",borderStyle:"double",className:r.input,value:p.discordKey,onChange:function(e){return W(e,"discordKey")}})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Telegram")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Telegram integration, include the telegram bot token and chat ID below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://core.telegram.org/bots#6-botfather",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,direction:"row",alignItems:"center",justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,className:r.inputContainer},i.a.createElement(h.e,{label:"Bot token",placeholder:"abc",borderStyle:"double",className:r.input,value:p.telegram.botToken,onChange:function(e){return W(e,"botToken")}})),i.a.createElement(q.a,{item:!0,className:r.inputContainer},i.a.createElement(h.e,{label:"Chat ID",placeholder:"123",borderStyle:"double",className:r.input,value:p.telegram.chatId,onChange:function(e){return W(e,"chatId")}})))))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Slack")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"To add a Slack integration, include the Slack channel's url including key below. Find out more"," ",i.a.createElement(Xa,{underline:"always",href:"https://docs.openzeppelin.com/defender/sentinel#notifications",target:"_blank",color:"inherit"},"here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Slack Channel URL",placeholder:"https://slack.com/url/key",borderStyle:"double",className:r.input,value:p.slackKey,onChange:function(e){return W(e,"slackKey")}})))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return t(p)}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",type:"submit",disabled:function(){var e=H.botToken,t=H.chatId;return!(!l&&!u)||(""===e&&""!==t||""!==e&&""===t||""===e&&""===t&&""===U&&""===V&&0===F.length)}(),onClick:function(){return a(p)}},"Next"))))))},Ls=["proposal","oracle","monitoring","review"],Ps=Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},container:{display:"flex",flexDirection:"column"},tag:{background:e.palette.secondary.main},paperContainer:{padding:e.spacing(2)},paperTitle:{margin:0},step:{"& text":{fontFamily:"Roboto Mono"},"& .step-label":{textTransform:"capitalize",display:"inline",fontFamily:"Roboto Mono","&.clickable":{cursor:"pointer","&:hover":{textDecoration:"underline"}}}},stepperRoot:{backgroundColor:"transparent",border:"none",padding:e.spacing(0),"& .MuiStepIcon-active":{color:e.palette.secondary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"},"& .MuiStepIcon-completed":{background:e.palette.text.primary,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%",color:e.palette.secondary.main},"& .Mui-disabled .MuiStepIcon-root":{color:e.palette.primary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"}}}})),Fs=function(){var e=Ps(),t=dr(),a=t.sdk,n=t.safe,r=t.provider,o=ga(Dt),l=ba(),s=ga(Rt),u=Object(c.useState)(s.length),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)([]),b=Object(x.a)(p,2),g=b[0],E=b[1],v=Object(c.useState)(0),w=Object(x.a)(v,2),j=w[0],S=w[1],I=Object(c.useState)({proposal:!1,oracle:!1,monitoring:!1,review:!1}),T=Object(x.a)(I,2),A=T[0],R=T[1],M=Object(c.useState)(!1),B=Object(x.a)(M,2),D=B[0],L=B[1],F=Object(c.useState)(),U=Object(x.a)(F,2),V=U[0],H=U[1],_=function(e,t,a){return function(n){S(e),R(Object(N.a)(Object(N.a)({},A),{},Object(P.a)({},t,a))),H(Object(N.a)(Object(N.a)({},V),{},Object(P.a)({},t,n)))}},G=function(){var e=Object(k.a)(C.a.mark((function e(t){var o,c,i;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(o=[],L(!0),null!=V){e.next=5;break}throw L(!1),new Error("No setup data");case 5:return c=""!==t||null==t?n.safeAddress:t,i=function(e,t){if(null!=t)throw"OpenError"===t.name?o.push({error:!0,msg:t.toString()+"This error can be caused by add/track blockers. Please disable any blockers (for instance, the Brave Shield) and try again."}):o.push({error:!0,msg:t.toString()}),t;o.push({error:!1,msg:e}),E(o)},e.prev=7,e.next=10,Qi(r,a,n,c,V,i);case 10:e.next=16;break;case 12:e.prev=12,e.t0=e.catch(7),L(!1),console.error(e.t0);case 16:l(Kt(n)),l($t(!0));case 18:case"end":return e.stop()}}),e,null,[[7,12]])})));return function(t){return e.apply(this,arguments)}}();return Object(c.useEffect)((function(){D&&s.length>f&&(m(s.length),L(!1),l(ea(!1)))}),[l,D,f,s]),i.a.createElement("div",{className:e.root},i.a.createElement(q.a,{container:!0,spacing:2,className:e.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0},i.a.createElement(h.a,{icon:"reality",size:60})),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h5"},"Reality Module"),i.a.createElement(mc,{className:e.tag,tags:["Stackable","From Gnosis Guild"]})))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{gutterBottom:!0},"Allows Reality.eth questions to execute a transaction when resolved."," ",i.a.createElement(Xa,{underline:"always",href:"https://zodiac.wiki/index.php/Category:Reality_Module",target:"_blank",color:"inherit"},"Read more here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:e.paperContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",style:{marginBottom:15}},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",gutterBottom:!0,className:e.paperTitle},"Add Reality Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"outlined",onClick:function(){return l(ea(!1))}},"Cancel"))),i.a.createElement(Ml.a,{activeStep:j,className:e.stepperRoot,orientation:"vertical"},Ls.map((function(t,a){return i.a.createElement(Bl.a,{key:t,className:e.step},i.a.createElement(Dl.a,{onClick:function(){return e=a,void(A[t]&&S(e));var e}},i.a.createElement(y.a,{variant:"h6",className:ja()(a<=j&&"clickable","step-label")},t)," "),i.a.createElement(Ll.a,null,"proposal"===t&&i.a.createElement(ss,{handleNext:_(a+1,t,!0),handleBack:function(){return l(ea(!1))},setupData:V}),"oracle"===t&&i.a.createElement($l,{handleNext:_(a+1,t,!0),handleBack:_(j-1,t,!1),setupData:V}),"monitoring"===t&&i.a.createElement(Ds,{handleNext:_(a+1,t,!0),handleBack:_(j-1,t,!1),setupData:V}),"review"===t&&i.a.createElement(Cs,{handleNext:G,handleBack:_(j-1,t,!1),goToStep:S,setupData:V,delayModules:o,loading:D,statusLog:g})))})))))))},Us=a(710),Vs=a(508),Hs=a(476),_s=["function getVotes(address account) external view returns (uint256)","function getPastVotes(address account, uint256 blockNumber) external view returns (uint256)","function getPastTotalSupply(uint256 blockNumber) external view returns (uint256)","function delegates(address account) external view returns (address)","function delegate(address delegatee) external","function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external"],Gs="0xD028d504316FEc029CFa36bdc3A8f053F6E5a6e4",Ws=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},radio:{marginLeft:-2,padding:2,"& ~ .MuiFormControlLabel-label":{fontSize:12,marginLeft:4},"&$checked":{color:h.f.tan[1e3]}},checked:{},errorColor:{color:"rgba(244, 67, 54, 1)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},inputError:{"& .MuiInputBase-root":{borderColor:"rgba(244, 67, 54, 0.3)",background:"rgba(244, 67, 54, 0.1)","&::before":{borderColor:"rgba(244, 67, 54, 0.3)"}}}}})),zs={tokenAddress:void 0,tokenName:"",tokenSymbol:"",initialAmount:1e5,tokenConfiguration:"existingToken"},Ks=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=Ws(),o=n.token,l=Object(c.useState)(o),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=function(e){return function(){var t=Object(k.a)(C.a.mark((function t(a){var n;return C.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=new I.ethers.Contract(a,_s,e),t.prev=1,t.next=4,Promise.all([n.getVotes(Gs),n.getPastVotes(Gs,1234),n.getPastTotalSupply(1234),n.callStatic.delegates(Gs)]);case 4:n.functions.delegateBySig.name,t.next=11;break;case 7:return t.prev=7,t.t0=t.catch(1),console.log(t.t0),t.abrupt("return",!1);case 11:return t.abrupt("return",!0);case 12:case"end":return t.stop()}}),t,null,[[1,7]])})));return function(e){return t.apply(this,arguments)}}()}(dr().provider),E=u.tokenAddress,v=u.tokenName,w=u.tokenSymbol,j=u.tokenConfiguration,S=u.initialAmount,T=function(){return{tokenAddress:E,tokenName:v,tokenSymbol:w,tokenConfiguration:j,initialAmount:S}},A=function(e,t){d(Object(N.a)(Object(N.a)({},u),{},Object(P.a)({},t,e.target.value)))};Object(c.useEffect)((function(){[E].includes(void 0)||function(){var e=Object(k.a)(C.a.mark((function e(){return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(e.t0=I.ethers.utils.isAddress(E),!e.t0){e.next=5;break}return e.next=4,g(E);case 4:e.t0=e.sent;case 5:if(!e.t0){e.next=9;break}b(!0),e.next=10;break;case 9:b(!1);case 10:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()()}),[E,g]);var R="existingToken"===j?!(p&&![E].includes("")):"ERC721"!==j&&"ERC20"!==j||!![v,w].includes("");return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Setup Token for Voting")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"The following token will enable members to vote on proposals with this governor contract. The token must be ERC20Votes compatible.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Token Configuration")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2"},"Do you have an existing token in your safe that you'd like to use as the token for voting in this contract?"),i.a.createElement(Us.a,{"aria-label":"Token Configuration",name:"Token Configuration",value:j,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{tokenConfiguration:e.target.value}))}},i.a.createElement(Vs.a,{value:"existingToken",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Existing Token"}),i.a.createElement(Vs.a,{value:"ERC20",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Deploy a new ERC20 for voting."}),i.a.createElement(Vs.a,{value:"ERC721",control:i.a.createElement(jc.a,{classes:{root:r.radio,checked:r.checked}}),label:"Deploy a new ERC721 for voting."}))),"existingToken"===j&&i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Token Address",value:E,placeholder:"0xDf33060F476511F806C72719394da1Ad64",borderStyle:"double",className:[E].includes("")||[E].includes(void 0)||p?r.input:r.inputError,onChange:function(e){return A(e,"tokenAddress")}}),![E].includes(void 0)&&!p&&i.a.createElement(Hs.a,{className:r.errorColor},"Please provide a valid address")),("ERC20"===j||"ERC721"===j)&&i.a.createElement(c.Fragment,null,i.a.createElement(q.a,{item:!0,style:{width:"-webkit-fill-available"}},i.a.createElement(q.a,{container:!0,spacing:2,justifyContent:"space-between"},i.a.createElement(q.a,{item:!0,xs:9},i.a.createElement(h.e,{label:"Token Name",value:v,placeholder:"MyToken",borderStyle:"double",className:r.input,onChange:function(e){return A(e,"tokenName")},tooltipMsg:"The same as collection name in OpenSea, e.g. Nouns"})),i.a.createElement(q.a,{item:!0,xs:3},i.a.createElement(h.e,{label:"Token Symbol",value:w,placeholder:"TKN",borderStyle:"double",className:r.input,onChange:function(e){return A(e,"tokenSymbol")},tooltipMsg:"e.g. LOOT"}))))),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(T())}},"Cancel")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:R,onClick:function(){return t(T())}},"Next"))))))},Ys=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},icon:{fill:"white",cursor:"pointer"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}},label:{fontFamily:"Roboto Mono, monospace",fontSize:12,fontWeight:"bold"},loading:{width:"15px !important",height:"15px !important"},value:{fontFamily:"Roboto Mono, monospace",fontWeight:"bold",color:"white"},underline:{textDecoration:"underline"}}})),Zs=[{label:"Token",number:1,section:0},{label:"Governor",number:2,section:1}],qs=function(e){var t=e.handleBack,a=e.handleNext,n=e.goToStep,r=e.setupData,o=e.loading,c=Ys(),l=null===r||void 0===r?void 0:r.token,s=null===r||void 0===r?void 0:r.governor,u=Object(p.useSafeAppsSDK)().safe;return i.a.createElement(h.c,{borderStyle:"single",className:c.paperContainer},i.a.createElement(q.a,{container:!0,spacing:3,className:c.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:c.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Review")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Please take a final look at your OZ Governor Module details.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),Zs.map((function(e){return i.a.createElement(i.a.Fragment,{key:e.label},i.a.createElement(q.a,{item:!0},i.a.createElement(ds,{label:e.label,number:e.number,disabled:o||"Governor"===e.label,onClick:function(){return n(e.section)}})),"Token"===e.label&&l&&i.a.createElement(i.a.Fragment,null,l.tokenAddress&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Token:"),i.a.createElement(Ma.a,{target:"_blank",href:"".concat(H[u.chainId],"/token/").concat(l.tokenAddress),className:c.value},l.tokenAddress)),l.tokenName&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Token Name:"),i.a.createElement(y.a,{className:c.value},l.tokenName)),l.tokenSymbol&&i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Token Symbol:"),i.a.createElement(y.a,{className:c.value},l.tokenSymbol))),"Governor"===e.label&&s&&i.a.createElement(i.a.Fragment,null,i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Name:"),i.a.createElement(y.a,{className:c.value},s.daoName)),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Delay:"),i.a.createElement(y.a,{className:c.value},s.votingDelayInBlocks," blocks")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Voting Period:"),i.a.createElement(y.a,{className:c.value},s.votingPeriodInBlocks," blocks")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Proposal Threshold:"),i.a.createElement(y.a,{className:c.value},s.proposalThreshold,"%")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Quorum (%):"),i.a.createElement(y.a,{className:c.value},s.quorumPercent,"%"))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)))})),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:t,disabled:o},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",startIcon:o?i.a.createElement(m.Loader,{className:c.loading,size:"sm",color:"background"}):i.a.createElement(ms.a,null),onClick:function(){a(r)}},"Deploy and Enable Module"))))))};var Xs,Qs,Js,$s,eu,tu,au=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i,l){var s,u,d,f,m,p;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=a){e.next=2;break}throw new Error("No safe address provided");case 2:if(null!=n){e.next=4;break}throw new Error("No token address provided");case 4:if(null!=r){e.next=6;break}throw new Error("No name provided");case 6:if(null!=o){e.next=8;break}throw new Error("No voting delay provided");case 8:if(null!=c){e.next=10;break}throw new Error("No voting period provided");case 10:if(null!=i){e.next=12;break}throw new Error("No proposal threshold provided");case 12:if(null!=l){e.next=14;break}throw new Error("No quorum percent provided");case 14:if(!(l>100||l<0)){e.next=16;break}throw new Error("Quorum percent must be between 0 and 100");case 16:return s={values:[a,a,"0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761",n,r,o.toString(),c.toString(),i.toString(),l.toString(),"0"],types:["address","address","address","address","string","uint256","uint256","uint256","uint256","uint64"]},u=Date.now().toString(),e.next=20,t.getNetwork();case 20:return d=e.sent.chainId,f=Object(M.f)(M.d.OZ_GOVERNOR,s,t,d,u),m=f.transaction,p=f.expectedModuleAddress,e.abrupt("return",{txs:[Object(N.a)(Object(N.a)({},m),{},{value:m.value.toString()})],meta:{expectedAddress:p}});case 23:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c,i,l){return e.apply(this,arguments)}}(),nu=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o){var c,i,l,s,u,d;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=a){e.next=2;break}throw new Error("No safe address provided");case 2:if(null!=n){e.next=4;break}throw new Error("No token name provided");case 4:if(null!=r){e.next=6;break}throw new Error("No token symbol provided");case 6:if("ERC20"===o||"ERC721"===o){e.next=8;break}throw new Error("Invalid token kind");case 8:return c={values:[a,n,r],types:["address","string","string"]},i=Date.now().toString(),e.next=12,t.getNetwork();case 12:return l=e.sent.chainId,s=Object(M.f)("ERC20"===o?M.d.ERC20_VOTES:M.d.ERC721_VOTES,c,t,l,i),u=s.transaction,d=s.expectedModuleAddress,e.abrupt("return",{txs:[Object(N.a)(Object(N.a)({},u),{},{value:u.value.toString()})],meta:{expectedAddress:d}});case 15:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o){return e.apply(this,arguments)}}(),ru=function(){var e=Object(k.a)(C.a.mark((function e(t,a,n,r,o,c,i,l,s,u){var d,f,m,p,b,g,h,E;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=s||null!=u){e.next=4;break}throw new Error("No token address or create token args provided");case 4:if(null==s||null==u){e.next=6;break}throw new Error("Both token address and create token args provided");case 6:if(d=[],null==u){e.next=17;break}return e.next=10,nu(t,n,u.name,u.symbol,u.kind);case 10:if(f=e.sent,m=f.txs,p=f.meta,d.push.apply(d,Object(w.a)(m)),null!=(null===p||void 0===p?void 0:p.expectedAddress)){e.next=16;break}throw new Error("No expected address returned from token deployment");case 16:s=p.expectedAddress;case 17:if(null!=s){e.next=19;break}throw new Error("No token address provided. Should not be possible. Either the token address should be provided or a new token should be deployed.");case 19:return e.next=21,au(t,n,s,r,o,c,i,l);case 21:if(b=e.sent,g=b.txs,h=b.meta,d.push.apply(d,Object(w.a)(g)),null!=(null===h||void 0===h?void 0:h.expectedAddress)){e.next=27;break}throw new Error("The expected value is missing");case 27:return E=je(n,h.expectedAddress),d.push(E),e.abrupt("return",a.txs.send({txs:d}).catch((function(e){throw console.error(e),new Error("Error when proposing transactions to the Safe")})));case 30:case"end":return e.stop()}}),e)})));return function(t,a,n,r,o,c,i,l,s,u){return e.apply(this,arguments)}}(),ou=Object(g.a)((function(e){return{container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},textSubdued:{color:"rgba(255 255 255 / 70%)"},input:{"& .MuiInputBase-root":{borderColor:h.f.tan[300],"&::before":{borderColor:h.f.tan[300]}}}}})),cu={daoName:"",votingDelayInBlocks:0,votingPeriodInBlocks:50400,proposalThreshold:0,quorumPercent:4},iu=function(e){var t=e.handleNext,a=e.handleBack,n=e.setupData,r=ou(),o=n.governor,l=Object(c.useState)(o),s=Object(x.a)(l,2),u=s[0],d=s[1],f=function(e,t){d(Object(N.a)(Object(N.a)({},u),{},Object(P.a)({},t,e.target.value)))},m=function(){return u},p=u.daoName,b=u.votingDelayInBlocks,g=u.votingPeriodInBlocks,E=u.proposalThreshold,v=u.quorumPercent;return i.a.createElement(h.c,{borderStyle:"single",className:r.paperContainer},i.a.createElement(q.a,{container:!0,spacing:4,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h3"},"Setup OZ Governor Contract")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,null,"Configure your governor contract. It can always be changed later, so don't worry too much about getting it perfect the first time.")))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"DAO Name:",value:p,placeholder:"My Governor",borderStyle:"double",className:r.input,onChange:function(e){return f(e,"daoName")}})),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Voting Delay Configurations")),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"body2",className:r.textSubdued},"Configure a delay modifier to determine the duration required before voting (Cooldown), and the amount of time that the proposal will be valid (Expiration).")))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:6,alignItems:"center"},i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Voting Delay (in blocks)",value:b,type:"number",placeholder:"0",borderStyle:"double",className:r.input,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{votingDelayInBlocks:parseInt(e.target.value)}))},tooltipMsg:"The time between proposal submission and when voting starts."})),i.a.createElement(q.a,{item:!0,xs:6},i.a.createElement(h.e,{label:"Voting Period (in blocks)",value:g,type:"number",placeholder:"50400",borderStyle:"double",className:r.input,onChange:function(e){d(Object(N.a)(Object(N.a)({},u),{},{votingPeriodInBlocks:parseInt(e.target.value)}))},tooltipMsg:"The number of blocks between when a proposal's voting period starts and ends."})))),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:1,className:r.container},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",color:"textSecondary"},"Voting Thresholds")))),i.a.createElement(q.a,{item:!0},i.a.createElement(h.e,{label:"Proposal Threshold",color:"secondary",borderStyle:"double",className:r.input,type:"number",value:E,tooltipMsg:"How many tokens must someone own before they can submit a proposal to the DAO?",onChange:function(e){return f(e,"proposalThreshold")}})),i.a.createElement(q.a,{item:!0},i.a.createElement(h.d,{label:"Quorum (%):",defaultValue:v,hasInput:!0,onChangeSlider:function(e){"number"===typeof e&&v!==e&&e>=0&&d(Object(N.a)(Object(N.a)({},u),{},{quorumPercent:e}))}})),i.a.createElement(q.a,{item:!0,style:{paddingBottom:0}},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:3,justifyContent:"center",alignItems:"center"},i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{size:"medium",variant:"text",onClick:function(){return a(m())}},"Back")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"contained",disabled:!(![p].includes("")&&v>=0&&v<=100),onClick:function(){return t(m())}},"Next"))))))},lu=["token","governor","review"],su=Object(g.a)((function(e){return{root:{height:"100%",display:"flex",flexDirection:"column",padding:e.spacing(1.5),overflowY:"auto"},container:{display:"flex",flexDirection:"column"},paperContainer:{padding:e.spacing(2)},paperTitle:{margin:0},step:{"& text":{fontFamily:"Roboto Mono"},"& .step-label":{textTransform:"capitalize",display:"inline",fontFamily:"Roboto Mono","&.clickable":{cursor:"pointer","&:hover":{textDecoration:"underline"}}}},stepperRoot:{backgroundColor:"transparent",border:"none",padding:e.spacing(0),"& .MuiStepIcon-active":{color:e.palette.secondary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"},"& .MuiStepIcon-completed":{background:e.palette.text.primary,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%",color:e.palette.secondary.main},"& .Mui-disabled .MuiStepIcon-root":{color:e.palette.primary.main,border:"1px solid ".concat(h.f.tan[300]),borderRadius:"100%"}}}})),uu=function(){var e=su(),t=dr(),a=t.sdk,n=t.safe,r=t.provider,o=ba(),l=Object(c.useState)(0),s=Object(x.a)(l,2),u=s[0],d=s[1],f=Object(c.useState)(!1),m=Object(x.a)(f,2),p=m[0],b=m[1],g=Object(c.useState)({token:!1,governor:!1,review:!1}),E=Object(x.a)(g,2),v=E[0],w=E[1],j=Object(c.useState)({token:zs,governor:cu,review:{}}),S=Object(x.a)(j,2),I=S[0],T=S[1],A=function(e,t,a){return function(n){d(e),w(Object(N.a)(Object(N.a)({},v),{},Object(P.a)({},t,a))),T(Object(N.a)(Object(N.a)({},I),{},Object(P.a)({},t,n)))}},R=function(){var e=Object(k.a)(C.a.mark((function e(){var t,c,i,l,s,u,d,f,m,p,g,h;return C.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(b(!0),null!=I){e.next=4;break}throw b(!1),new Error("No setup data");case 4:return t=I.token,c=t.tokenAddress,i=t.tokenSymbol,l=t.tokenConfiguration,s=t.tokenName,u=I.governor,d=u.daoName,f=u.votingDelayInBlocks,m=u.votingPeriodInBlocks,p=u.proposalThreshold,g=u.quorumPercent,e.prev=6,h=void 0,"ERC20"!==l&&"ERC721"!==l||(h={name:s,symbol:i,kind:l}),e.next=11,ru(r,a,n.safeAddress,d,f,m,p,g,c,h);case 11:e.sent.safeTxHash&&(o(Kt(n)),o($t(!0))),e.next=19;break;case 15:e.prev=15,e.t0=e.catch(6),b(!1),console.error(e.t0);case 19:case"end":return e.stop()}}),e,null,[[6,15]])})));return function(){return e.apply(this,arguments)}}();return i.a.createElement("div",{className:e.root},i.a.createElement(q.a,{container:!0,spacing:2,className:e.container},i.a.createElement(q.a,{item:!0},i.a.createElement(q.a,{container:!0,spacing:2},i.a.createElement(q.a,{item:!0},i.a.createElement(h.a,{icon:"ozGov",size:60})),i.a.createElement(q.a,{item:!0,style:{display:"flex",alignItems:"center"}},i.a.createElement(y.a,{variant:"h5"},"Governor Module")))),i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{gutterBottom:!0},"Enables an Open Zeppelin Governor contract as a module."," ",i.a.createElement(Xa,{underline:"always",href:"https://blog.openzeppelin.com/governor-smart-contract/",target:"_blank",color:"inherit"},"Read more here."))),i.a.createElement(q.a,{item:!0},i.a.createElement(Rl.a,null)),i.a.createElement(q.a,{item:!0},i.a.createElement(h.c,{borderStyle:"single",className:e.paperContainer},i.a.createElement(q.a,{container:!0,justifyContent:"space-between",alignItems:"center",style:{marginBottom:15}},i.a.createElement(q.a,{item:!0},i.a.createElement(y.a,{variant:"h4",gutterBottom:!0,className:e.paperTitle},"Add Governor Module")),i.a.createElement(q.a,{item:!0},i.a.createElement(O.a,{color:"secondary",size:"medium",variant:"outlined",onClick:function(){return o(ta(!1))}},"Cancel"))),i.a.createElement(Ml.a,{activeStep:u,className:e.stepperRoot,orientation:"vertical"},lu.map((function(t,a){return i.a.createElement(Bl.a,{key:t,className:e.step},i.a.createElement(Dl.a,{onClick:function(){return e=a,void(v[t]&&d(e));var e}},i.a.createElement(y.a,{variant:"h6",className:ja()(a<=u&&"clickable","step-label")},t)," "),i.a.createElement(Ll.a,null,"token"===t&&i.a.createElement(Ks,{handleNext:A(a+1,t,!0),handleBack:function(){return o(ta(!1))},setupData:I}),"governor"===t&&i.a.createElement(iu,{handleNext:A(a+1,t,!0),handleBack:A(u-1,t,!1),setupData:I}),"review"===t&&i.a.createElement(qs,{handleNext:R,handleBack:A(a-1,t,!0),setupData:I,goToStep:d,loading:p})))})))))))},du=function(){var e=ga(At),t=ga(Ht),a=ga((function(e){return e.modules.loadingModules})),n=ga((function(e){return e.modules.realityModuleScreen})),r=ga((function(e){return e.modules.OzGovernorModuleScreen}));return e?i.a.createElement(oc,{module:e}):t?i.a.createElement(Al,null):n?i.a.createElement(Fs,null):r?i.a.createElement(uu,null):a?null:i.a.createElement(kl,null)},fu=a(514),mu=Object(g.a)((function(e){return{root:{marginBottom:e.spacing(2)},container:{"&.MuiPaper-root":{display:"flex",flexDirection:"row",alignItems:"center","&::before":Object(h.g)(-5,h.f.tan[300])}},header:{"&.MuiPaper-root":{padding:e.spacing(.5,2,.5,.5),"&::before":Object(h.g)(-5,h.f.tan[300])}},txBuilder:{"&.MuiPaper-root":{padding:e.spacing(.5,.5,.5,2),cursor:"pointer",transition:"0.2s ease all","&::before":Object(h.g)(-5,h.f.tan[300]),"&:hover":{background:"rgba(217, 212, 173, 0.15)"}}},img:{display:"block",width:36,height:36},title:{marginLeft:e.spacing(1)},bagIcon:{marginLeft:e.spacing(2),stroke:"white"},badge:{color:e.palette.common.white,display:"flex",position:"relative",transform:"none",textAlign:"center",background:"none",fontSize:16},badgeRoot:{display:"flex",justifyContent:"center",alignItems:"center",height:36,width:36,borderRadius:60,border:"1px solid ".concat(h.f.tan[300]),padding:e.spacing(.5)},txBuilderTitle:{marginRight:e.spacing(3)},circleIconContainer:{padding:e.spacing(.5)},banner:{"&.MuiPaper-root":{flexGrow:1,position:"relative",borderWidth:1,borderColor:h.f.tan[300],backgroundColor:h.f.tan[100],margin:e.spacing(0,2),"&::before":Object(h.g)(-5,h.f.tan[300])}}}})),pu=function(){var e=mu(),t=ba(),a=ga(Lr);return i.a.createElement(Pa,{className:e.root},i.a.createElement(h.c,{elevation:0,borderStyle:"double",rounded:"left",variant:"elevation",className:ja()(e.container,e.header)},i.a.createElement(h.a,{icon:"zodiac"}),i.a.createElement(y.a,{variant:"h5",className:e.title},"Zodiac")),i.a.createElement(h.c,{elevation:0,className:e.banner}),i.a.createElement(h.c,{borderStyle:"double",onClick:function(){return t(oa())},elevation:0,rounded:"right",className:ja()(e.container,e.txBuilder)},i.a.createElement(y.a,{className:e.txBuilderTitle},"Bundle Transactions"),i.a.createElement(h.c,{rounded:"full",variant:"outlined",className:e.circleIconContainer},i.a.createElement(fu.a,{showZero:!0,badgeContent:a.length,color:a.length?"error":"primary",classes:{badge:e.badge,root:e.badgeRoot}}))))},bu=a(310),gu=a(507),hu=["svgRef","title"];function Eu(){return(Eu=Object.assign||function(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var yu=function(e){var t=e.svgRef,a=e.title,n=vu(e,hu);return i.a.createElement("svg",Eu({width:9,height:16,viewBox:"0 0 9 16",fill:"none",ref:t},n),a?i.a.createElement("title",null,a):null,Xs||(Xs=i.a.createElement("circle",{cx:1.5,cy:2,r:1.5,fill:"#B2B5B2"})),Qs||(Qs=i.a.createElement("circle",{cx:1.5,cy:14,r:1.5,fill:"#B2B5B2"})),Js||(Js=i.a.createElement("circle",{cx:1.5,cy:8,r:1.5,fill:"#B2B5B2"})),$s||($s=i.a.createElement("circle",{cx:7.5,cy:2,r:1.5,fill:"#B2B5B2"})),eu||(eu=i.a.createElement("circle",{cx:7.5,cy:14,r:1.5,fill:"#B2B5B2"})),tu||(tu=i.a.createElement("circle",{cx:7.5,cy:8,r:1.5,fill:"#B2B5B2"})))},Ou=i.a.forwardRef((function(e,t){return i.a.createElement(yu,Eu({svgRef:t},e))})),xu=(a.p,Object(g.a)((function(e){return{icon:{color:e.palette.primary.main,width:20,height:20},iconContainer:{height:54,cursor:"pointer",padding:e.spacing(2,.5),marginRight:e.spacing(1)},button:{marginRight:e.spacing(1.5),color:e.palette.text.secondary},label:{color:e.palette.text.primary}}}))),wu=function(e){var t=e.edit,a=void 0!==t&&t,n=e.disabled,r=void 0!==n&&n,o=e.onCancel,c=e.onEdit,l=e.onSave,s=e.onDelete,u=xu();return a?i.a.createElement(i.a.Fragment,null,i.a.createElement(Ar,{disabled:r,className:u.button,onClick:l},"Save Changes"),i.a.createElement(Ar,{onClick:o,className:u.button,classes:{label:u.label},variant:"outlined"},"Cancel")):i.a.createElement(i.a.Fragment,null,i.a.createElement(J.a,{className:u.iconContainer,onClick:c},i.a.createElement(m.Icon,{type:"edit",size:"md",className:u.icon})),i.a.createElement(J.a,{className:u.iconContainer,onClick:s},i.a.createElement(m.Icon,{type:"delete",size:"md",className:u.icon})))},ju=Object(g.a)((function(e){return{root:{position:"relative",borderRadius:8},label:{marginBottom:e.spacing(.5)},field:{padding:e.spacing(1,0,1,1)}}})),Cu=function(e){var t=e.label,a=e.value,n=ju();return i.a.createElement("div",{className:n.root},i.a.createElement(y.a,{noWrap:!0,className:n.label},t),i.a.createElement(h.c,{borderStyle:"double",className:n.field},i.a.createElement(y.a,{noWrap:!0},a)))},ku=function(e){var t=e.edit?e.paramInputProps.map((function(e,t){return i.a.createElement(q.a,{item:!0,key:t,xs:12,md:6},i.a.createElement(co,Object.assign({key:t},e)))})):e.func.inputs.map((function(t,a){return i.a.createElement(q.a,{item:!0,key:a,xs:12,md:6},i.a.createElement(Cu,{label:"".concat(t.name," (").concat(t.type,")"),value:lt(t,e.params[a])}))}));return i.a.createElement(q.a,{container:!0,spacing:2},t)},Su=a(1723),Nu=["address","name"],Iu=Object(g.a)((function(e){return{name:{marginRight:e.spacing(1)},avatar:{"& img":{width:20,height:20}}}})),Tu=function(e){var t=e.address,a=e.name,n=Object(Ca.a)(e,Nu),r=Iu(),o=i.a.createElement(i.a.Fragment,null,a?i.a.createElement("b",{className:r.name},a):null,_a(t));return i.a.createElement(Su.a,Object.assign({},n,{avatar:i.a.createElement(Ra,{showAvatar:!0,showHash:!1,avatarSize:"sm",hash:t,className:r.avatar}),label:o}))},Au=Object(g.a)((function(e){return{title:{padding:e.spacing(2,.5,2,0),marginRight:e.spacing(1),display:"flex",alignItems:"center",flexDirection:"row",flexGrow:1},clickable:{cursor:"pointer"},moduleChip:{marginRight:e.spacing(1),fontSize:14}}})),Ru=function(e){var t=e.edit,a=e.open,n=e.transaction,r=e.onToggle,o=Au();return i.a.createElement(J.a,{className:ja()(o.title,Object(P.a)({},o.clickable,!t)),onClick:r},n.module?i.a.createElement(Tu,{className:o.moduleChip,address:n.module.address,name:n.module.name}):null,i.a.createElement(Su.a,{label:i.a.createElement("b",null,n.func.name)}),i.a.createElement(Or,null),t?null:i.a.createElement(bo,{up:a}))},Mu=Object(g.a)((function(e){return{container:{marginTop:"0 !important",padding:0},collapsableContainer:{margin:0,padding:e.spacing(1,2,2,2)},dragging:{borderColor:"#31AAB7",borderStyle:"solid",borderWidth:2},noDragging:{transform:"none !important"},dropAnimation:{transitionDuration:"0.001s !important"},grip:{display:"flex",cursor:"grab",padding:e.spacing(2)}}})),Bu=function(e){var t,a=e.open,n=e.edit,r=void 0!==n&&n,o=e.headerButtonProps,c=e.headerTitleProps,l=e.blockFieldsProps,s=e.drag,u=Mu();return i.a.createElement(Gr,Object.assign({open:a,innerRef:s.provider.innerRef},s.provider.draggableProps,{containerClassName:u.collapsableContainer,className:ja()(u.container,(t={},Object(P.a)(t,u.dragging,s.snapshot.isDragging),Object(P.a)(t,u.noDragging,!s.snapshot.isDragging),Object(P.a)(t,u.dropAnimation,s.snapshot.isDropAnimating),t)),content:i.a.createElement(ku,l)}),i.a.createElement(Pa,{style:{alignItems:"center"}},i.a.createElement("div",Object.assign({className:u.grip},s.provider.dragHandleProps),i.a.createElement(Ou,null)),i.a.createElement(Ru,Object.assign({open:a,edit:r},c)),i.a.createElement(wu,Object.assign({edit:r},o))))},Du=Object(g.a)((function(e){return{root:{position:"relative",paddingBottom:e.spacing(2.5)},placeholder:{position:"absolute",width:"100%",borderColor:"#31AAB7",borderStyle:"solid",borderWidth:0,borderBottomWidth:e.spacing(.5),"&.place-after":{bottom:e.spacing(1)},"&.place-before":{top:e.spacing(-1)}}}})),Lu=Object(qa.a)((function(e){return{root:{height:56,backgroundColor:e.palette.primary.light}}}))(gu.a),Pu=function(e){var t=e.index,a=e.isOver,n=e.isOverBefore,r=e.transaction,o=e.onUpdate,l=e.onDelete,s=Du(),u=Object(c.useState)(!1),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useState)(!1),b=Object(x.a)(p,2),g=b[0],h=b[1],E=r.id,v=r.params,y=r.func,O=function(){m(!0),h(!0)},w=function(){g||m(!f)},j=function(){h(!1)},C=function(){l(E)};return i.a.createElement(bu.b,{draggableId:E,index:t},(function(e,t){return i.a.createElement("div",{className:ja()(s.root,{over:a})},g?i.a.createElement(Wr,{func:y,defaultParams:v},(function(a){var n=a.paramInputProps,c=a.areParamsValid,l=a.getParams;return i.a.createElement(Bu,{edit:!0,open:f,drag:{provider:e,snapshot:t},blockFieldsProps:{edit:!0,paramInputProps:n},headerTitleProps:{transaction:r,onToggle:w},headerButtonProps:{disabled:!c,onCancel:j,onSave:function(){return e=l(),o(E,e),void h(!1);var e}}})})):i.a.createElement(Bu,{open:f,drag:{provider:e,snapshot:t},blockFieldsProps:{edit:!1,params:v,func:y},headerTitleProps:{transaction:r,onToggle:w},headerButtonProps:{onEdit:O,onDelete:C}}),a&&i.a.createElement("div",{className:ja()(s.placeholder,{"place-after":!n,"place-before":n})}),t.isDragging&&i.a.createElement(Lu,{elevation:0}))}))},Fu=Object(g.a)((function(e){return{root:{width:"100%",display:"flex",flexGrow:1,outline:"none",padding:e.spacing(1.5),marginBottom:e.spacing(2),backgroundColor:"#0d0b217a",border:"1px solid rgba(217, 212, 173, 0.3)",overflowY:"auto"}}})),Uu=function(e){var t=e.transactions,a=Fu(),n=ba(),r=Object(c.useState)(),o=Object(x.a)(r,2),l=o[0],s=o[1],u=Object(c.useState)(),d=Object(x.a)(u,2),f=d[0],m=d[1],p=Object(c.useCallback)((function(e,a){var r=t.map(Rr).map((function(t){return t.id!==e?t:Object(N.a)(Object(N.a)({},t),{},{params:a})}));n(da(r))}),[n,t]),b=Object(c.useCallback)((function(e){var a=Array.from(t).map(Rr),r=a.findIndex((function(t){return t.id===e}));r>=0&&(a.splice(r,1),n(da(a)))}),[n,t]);return i.a.createElement("div",{className:a.root},i.a.createElement(bu.a,{onDragStart:function(e){m(e.source.index)},onDragUpdate:function(e){e.destination&&e.destination.index!==e.source.index?s(e.destination.index):s(void 0)},onDragEnd:function(e){if(s(void 0),m(void 0),e.destination){var a=Array.from(t).map(Rr),r=a.splice(e.source.index,1),o=Object(x.a)(r,1)[0];a.splice(e.destination.index,0,o),n(da(a))}}},i.a.createElement(bu.c,{droppableId:"transactions"},(function(e){return i.a.createElement("div",Object.assign({ref:e.innerRef,style:{width:"100%"}},e.droppableProps),t.map((function(e,t){return i.a.createElement(Pu,{index:t,key:e.id,transaction:e,isOver:t===l,isOverBefore:!!f&&t = {\n ETH: { symbol: \"ETH\", decimals: 18 },\n XDAI: { symbol: \"xDai\", decimals: 18 },\n MATIC: { symbol: \"MATIC\", decimals: 18 },\n BNB: { symbol: \"BNB\", decimals: 18 },\n AVAX: { symbol: \"AVAX\", decimals: 18 },\n}\n\nexport const NETWORKS: Record = {\n [NETWORK.MAINNET]: {\n chainId: NETWORK.MAINNET,\n name: \"mainnet\",\n shortName: \"eth\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.GOERLI]: {\n chainId: NETWORK.GOERLI,\n name: \"goerli\",\n shortName: \"gor\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.OPTIMISM]: {\n chainId: NETWORK.OPTIMISM,\n name: \"optimism\",\n shortName: \"oeth\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.GNOSIS_CHAIN]: {\n chainId: NETWORK.GNOSIS_CHAIN,\n name: \"gnosis_chain\",\n shortName: \"gno\",\n nativeAsset: NATIVE_ASSET.XDAI,\n },\n [NETWORK.BSC]: {\n chainId: NETWORK.BSC,\n name: \"binance_smart_chain\",\n shortName: \"bnb\",\n nativeAsset: NATIVE_ASSET.BNB,\n },\n [NETWORK.POLYGON]: {\n chainId: NETWORK.POLYGON,\n name: \"polygon\",\n shortName: \"matic\",\n nativeAsset: NATIVE_ASSET.MATIC,\n },\n [NETWORK.ARBITRUM]: {\n chainId: NETWORK.ARBITRUM,\n name: \"arbitrum\",\n shortName: \"arb1\",\n nativeAsset: NATIVE_ASSET.ETH,\n },\n [NETWORK.AVALANCHE]: {\n chainId: NETWORK.AVALANCHE,\n name: \"avalanche\",\n shortName: \"avax\",\n nativeAsset: NATIVE_ASSET.AVAX,\n },\n}\n\nexport const NETWORK_NATIVE_ASSET: Record = {\n [NETWORK.MAINNET]: NATIVE_ASSET.ETH,\n [NETWORK.GOERLI]: NATIVE_ASSET.ETH,\n [NETWORK.OPTIMISM]: NATIVE_ASSET.ETH,\n [NETWORK.GNOSIS_CHAIN]: NATIVE_ASSET.XDAI,\n [NETWORK.POLYGON]: NATIVE_ASSET.MATIC,\n [NETWORK.BSC]: NATIVE_ASSET.BNB,\n [NETWORK.ARBITRUM]: NATIVE_ASSET.ETH,\n [NETWORK.AVALANCHE]: NATIVE_ASSET.AVAX,\n}\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n height: \"calc(100% - 70px)\",\n gridTemplateColumns: \"390px 1fr\",\n gridGap: theme.spacing(0.5),\n overflow: \"hidden\",\n padding: theme.spacing(0.5),\n },\n leftPanel: {\n overflowY: \"auto\",\n },\n content: {\n overflowY: \"auto\",\n },\n}));\n\ninterface AppLayoutProps {\n left: React.ReactElement;\n}\n\nexport const AppLayout: React.FC = ({ children, left }) => {\n const classes = useStyles();\n return (\n \n {left}\n \n {children}\n \n \n );\n};\n","import { Interface } from \"@ethersproject/abi\"\nimport { abi as SafeAbi } from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/gnosis_safe_l2.json\"\n\nexport const AddressOne = \"0x0000000000000000000000000000000000000001\"\n\nexport const buildTransaction = (\n iface: Interface,\n to: string,\n method: string,\n params: any[],\n value?: string,\n) => {\n return {\n to,\n data: iface.encodeFunctionData(method, params),\n value: value || \"0\",\n }\n}\n\nexport { SafeAbi }\n","import { NETWORK } from \"./networks\"\n\nconst isDev = process.env.NODE_ENV === \"development\"\nconst REACT_APP_ETHERSCAN_KEY = process.env.REACT_APP_ETHERSCAN_KEY\nif (!REACT_APP_ETHERSCAN_KEY) {\n throw new Error(\"REACT_APP_ETHERSCAN_KEY is not set\")\n}\n\nconst REACT_APP_GNOSISSCAN_KEY = process.env.REACT_APP_GNOSISSCAN_KEY\nif (!isDev && !REACT_APP_GNOSISSCAN_KEY) {\n throw new Error(\"REACT_APP_GNOSISSCAN_KEY is not set\")\n}\n\nconst REACT_APP_POLYGONSCAN_KEY = process.env.REACT_APP_POLYGONSCAN_KEY\nif (!isDev && !REACT_APP_POLYGONSCAN_KEY) {\n throw new Error(\"REACT_APP_POLYGONSCAN_KEY is not set\")\n}\n\nconst REACT_APP_BSCSCAN_KEY = process.env.REACT_APP_BSCSCAN_KEY\nif (!isDev && !REACT_APP_BSCSCAN_KEY) {\n throw new Error(\"REACT_APP_BSCSCAN_KEY is not set\")\n}\n\nconst REACT_APP_OPTIMISTIC_ETHERSCAN_KEY = process.env.REACT_APP_OPTIMISTIC_ETHERSCAN_KEY\nif (!isDev && !REACT_APP_OPTIMISTIC_ETHERSCAN_KEY) {\n throw new Error(\"REACT_APP_OPTIMISTIC_ETHERSCAN_KEY is not set\")\n}\n\nconst REACT_APP_ARBISCAN_KEY = process.env.REACT_APP_ARBISCAN_KEY\nif (!isDev && !REACT_APP_ARBISCAN_KEY) {\n throw new Error(\"REACT_APP_ARBISCAN_KEY is not set\")\n}\n\nconst REACT_APP_SNOWTRACE_KEY = process.env.REACT_APP_SNOWTRACE_KEY\nif (!isDev && !REACT_APP_SNOWTRACE_KEY) {\n throw new Error(\"REACT_APP_SNOWTRACE_KEY is not set\")\n}\n\ninterface ExplorerData {\n networkExplorerName: string\n networkExplorerUrl: string\n networkExplorerApiUrl: string\n safeTransactionApi: string\n safeUrl: string\n explorerApiKey?: string\n verifyContractUrl: string\n}\n\nexport const EXPLORERS_CONFIG: Record = {\n [NETWORK.MAINNET]: {\n networkExplorerName: \"Etherscan\",\n networkExplorerUrl: \"https://etherscan.io\",\n networkExplorerApiUrl: \"https://api.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-mainnet.safe.global/\",\n safeUrl: \"https://app.safe.global/eth:\",\n verifyContractUrl: \"https://etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ETHERSCAN_KEY,\n },\n [NETWORK.GOERLI]: {\n networkExplorerName: \"Etherscan\",\n networkExplorerUrl: \"https://goerli.etherscan.io\",\n networkExplorerApiUrl: \"https://api-goerli.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-goerli.safe.global/\",\n safeUrl: \"https://app.safe.global/gor:\",\n verifyContractUrl: \"https://goerli.etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ETHERSCAN_KEY,\n },\n [NETWORK.GNOSIS_CHAIN]: {\n networkExplorerName: \"GnosisScan\",\n networkExplorerUrl: \"https://gnosisscan.io\",\n networkExplorerApiUrl: \"https://api.gnosisscan.io/api\",\n safeUrl: \"https://app.safe.global/gno:\",\n safeTransactionApi: \"https://safe-transaction-gnosis-chain.safe.global/\",\n verifyContractUrl: \"https://gnosisscan.io/verifyContract\",\n explorerApiKey: REACT_APP_GNOSISSCAN_KEY,\n },\n [NETWORK.POLYGON]: {\n networkExplorerName: \"Polygonscan\",\n networkExplorerUrl: \"https://polygonscan.com\",\n networkExplorerApiUrl: \"https://api.polygonscan.com/api\",\n safeUrl: \"https://app.safe.global/matic:\",\n safeTransactionApi: \"https://safe-transaction-polygon.safe.global/\",\n verifyContractUrl: \"https://polygonscan.com/verifyContract\",\n explorerApiKey: REACT_APP_POLYGONSCAN_KEY,\n },\n [NETWORK.BSC]: {\n networkExplorerName: \"Bscscan\",\n networkExplorerUrl: \"https://bscscan.com/\",\n networkExplorerApiUrl: \"https://api.bscscan.com/api\",\n safeUrl: \"https://app.safe.global/bsc:\",\n safeTransactionApi: \"https://safe-transaction-bsc.safe.global/\",\n verifyContractUrl: \"https://bscscan.com/verifyContract\",\n explorerApiKey: REACT_APP_BSCSCAN_KEY,\n },\n [NETWORK.OPTIMISM]: {\n networkExplorerName: \"Optimism\",\n networkExplorerUrl: \"https://optimistic.etherscan.io/\",\n networkExplorerApiUrl: \"https://api-optimistic.etherscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-optimism.safe.global/\",\n safeUrl: \"https://app.safe.global/oeth:\",\n verifyContractUrl: \"https://optimistic.etherscan.io/verifyContract\",\n explorerApiKey: REACT_APP_OPTIMISTIC_ETHERSCAN_KEY,\n },\n [NETWORK.ARBITRUM]: {\n networkExplorerName: \"Arbiscan\",\n networkExplorerUrl: \"https://arbiscan.io/\",\n networkExplorerApiUrl: \"https://api.arbiscan.io/api\",\n safeTransactionApi: \"https://safe-transaction-arbitrum.safe.global/\",\n safeUrl: \"https://app.safe.global/arb1:\",\n verifyContractUrl: \"https://arbiscan.io/verifyContract\",\n explorerApiKey: REACT_APP_ARBISCAN_KEY,\n },\n [NETWORK.AVALANCHE]: {\n networkExplorerName: \"Snowtrace\",\n networkExplorerUrl: \"https://snowtrace.io/\",\n networkExplorerApiUrl: \"https://api.snowtrace.io/api\",\n safeTransactionApi: \"https://safe-transaction-avalanche.safe.global/\",\n safeUrl: \"https://app.safe.global/avax:\",\n verifyContractUrl: \"https://snowtrace.io/verifyContract\",\n explorerApiKey: REACT_APP_SNOWTRACE_KEY,\n },\n}\n\nexport const getNetworkExplorerInfo = (chainId: number) => {\n const networkBaseConfig = EXPLORERS_CONFIG[chainId as NETWORK]\n if (!networkBaseConfig) return\n return {\n name: networkBaseConfig.networkExplorerName,\n url: networkBaseConfig.networkExplorerUrl,\n apiUrl: networkBaseConfig.networkExplorerApiUrl,\n apiKey: networkBaseConfig.explorerApiKey,\n safeTransactionApi: networkBaseConfig.safeTransactionApi,\n safeUrl: networkBaseConfig.safeUrl,\n verifyUrl: networkBaseConfig.verifyContractUrl,\n }\n}\n\nexport const getExplorerInfo = (chainId: number, hash: string) => {\n const explorerData = getNetworkExplorerInfo(chainId)\n if (!explorerData) return\n const type = hash.length > 42 ? \"tx\" : \"address\"\n return () => ({\n url: `${explorerData.url}/${type}/${hash}`,\n alt: explorerData.name,\n })\n}\n","import { Contract, ethers } from \"ethers\"\nimport { Coin, NETWORK, NETWORKS } from \"../utils/networks\"\n\nconst REALITY_ETH_ERC20_CONTRACT_ABI = [\"function token() view returns (address)\"]\n\nconst ERC20_CONTRACT_ABI = [\n \"function name() view returns (string)\",\n \"function symbol() view returns (string)\",\n \"function decimals() public view returns (uint8)\",\n]\n\nexport const ERC721_CONTRACT_ABI = [\n \"function supportsInterface(bytes4 interfaceID) external view returns (bool)\",\n]\n\nexport async function getArbitratorBondToken(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n chainId: number,\n): Promise<{ isERC20: boolean; coin: Coin }> {\n try {\n const realityEthErc20Contract = new Contract(\n address,\n REALITY_ETH_ERC20_CONTRACT_ABI,\n provider,\n )\n const tokenAddress: string = await realityEthErc20Contract.token()\n const tokenContract = new Contract(tokenAddress, ERC20_CONTRACT_ABI, provider)\n const coin: Coin = {\n symbol: await tokenContract.symbol(),\n decimals: await tokenContract.decimals(),\n }\n return { isERC20: true, coin }\n } catch (err) {\n return {\n isERC20: false,\n coin: NETWORKS[chainId as NETWORK].nativeAsset,\n }\n }\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckmark = function SvgCheckmark(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 15,\n height: 12,\n viewBox: \"0 0 15 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z\",\n fill: \"#001428\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckmark, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkmark.23e86834.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useEffect, useState } from \"react\"\nimport { Box, Grid, InputLabel, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { getCollateral } from \"../../services\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const collateralOptions = {\n USDC: \"USDC\",\n WETH: \"WETH\",\n}\n\nexport function scaleBondDecimals(bond: string, isWeth: boolean): number {\n if (isWeth) {\n return Number(bond) * Math.pow(10, 18)\n } else {\n return Number(bond) * Math.pow(10, 6)\n }\n}\n\n// List of chain IDs where OG is available.\nconst optimisticGovernorAvailability: number[] = [\n NETWORK.MAINNET,\n NETWORK.POLYGON,\n NETWORK.GOERLI,\n NETWORK.GNOSIS_CHAIN,\n NETWORK.OPTIMISM,\n NETWORK.ARBITRUM,\n NETWORK.AVALANCHE,\n]\n\ntype Option = keyof typeof collateralOptions\n\ninterface CollateralSelectProps {\n defaultAddress?: string\n defaultOption?: string\n label: string\n chainId: number\n\n onChange(collateral: string): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n select: {\n marginBottom: -1,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"100%\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n}))\n\nexport const CollateralSelect = ({\n onChange,\n defaultOption = collateralOptions.USDC,\n label,\n chainId,\n}: CollateralSelectProps) => {\n const classes = useStyles()\n const [option, setOption] = useState(defaultOption)\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleCollateralOptionChange = (newOption: string) => {\n handleClose()\n const newOptionKey = Object.keys(collateralOptions).find(\n (k) => collateralOptions[`${k}` as Option] === newOption,\n ) as Option\n setOption(newOption)\n const isWeth = newOptionKey === \"WETH\" ? true : false\n const newCollateral = getCollateral(chainId, isWeth)\n onChange(newCollateral)\n }\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n return (\n
\n {label}\n \n \n value as string}\n onChange={(evt) => handleCollateralOptionChange(evt.target.value as string)}\n >\n {Object.keys(collateralOptions).map((optionKey) => {\n if (\n !optimisticGovernorAvailability.includes(chainId) &&\n optionKey === \"WETH\"\n ) {\n return null\n }\n return (\n \n {collateralOptions[`${optionKey}` as Option]}\n \n \n \n )\n })}\n \n \n \n
\n )\n}\n","import { BigNumber, Contract, ethers } from \"ethers\"\nimport { Interface } from \"@ethersproject/abi\"\nimport {\n calculateProxyAddress,\n deployAndSetUpModule,\n getModuleFactoryAndMasterCopy,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { AddressOne, buildTransaction, SafeAbi } from \"./helpers\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { getNetworkExplorerInfo } from \"../utils/explorers\"\nimport { SafeTransaction, SafeStatusResponse } from \"../store/modules/models\"\nimport { NETWORK } from \"../utils/networks\"\nimport { ERC721_CONTRACT_ABI } from \"./reality-eth\"\nimport { scaleBondDecimals } from \"components/input/CollateralSelect\"\n\ntype JsonRpcProvider = ethers.providers.JsonRpcProvider\n\nexport enum ARBITRATOR_OPTIONS {\n NO_ARBITRATOR,\n KLEROS,\n OTHER,\n}\n\nexport type TxWitMeta = {\n txs: BaseTransaction[]\n meta?: { [key: string]: string }\n}\n\ninterface TellorModuleParams {\n owner: string\n executor: string\n oracle?: string\n cooldown: string\n expiration: string\n}\n\ninterface OptimisticGovernorModuleParams {\n executor: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n}\n\ninterface DelayModuleParams {\n executor: string\n cooldown: string\n expiration: string\n}\n\nexport interface RolesModifierParams {\n target: string\n multisend: string\n}\n\nexport interface AMBModuleParams {\n amb: string\n controller: string\n executor: string\n chainId: string\n}\n\nexport interface ExitModuleParams {\n executor: string\n tokenContract: string\n}\n\nexport interface ConnextModuleParams {\n domainId: number\n sender: string\n owner: string\n avatar: string\n target: string\n}\n\nexport function getTellorOracle(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.POLYGON:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.GOERLI:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.OPTIMISM:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n case NETWORK.ARBITRUM:\n return \"0xD9157453E2668B2fc45b7A803D3FEF3642430cC0\"\n }\n return \"\"\n}\n\nexport function getDefaultOracle(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\"\n case NETWORK.BSC:\n return \"0xa925646Cae3721731F9a8C886E5D1A7B123151B9\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xE78996A233895bE74a66F451f1019cA9734205cc\"\n case NETWORK.POLYGON:\n return \"0x60573B8DcE539aE5bF9aD7932310668997ef0428\"\n case NETWORK.GOERLI:\n return \"0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\"\n case NETWORK.OPTIMISM:\n return \"0x0eF940F7f053a2eF5D6578841072488aF0c7d89A\"\n case NETWORK.ARBITRUM:\n return \"0x5D18bD4dC5f1AC8e9bD9B666Bd71cB35A327C4A9\"\n case NETWORK.AVALANCHE:\n return \"0xD88cd78631Ea0D068cedB0d1357a6eabe59D7502\"\n }\n return \"\"\n}\n\nexport function getFinder(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x40f941E48A552bF496B154Af6bf55725f18D77c3\"\n case NETWORK.POLYGON:\n return \"0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64\"\n case NETWORK.GOERLI:\n return \"0xE60dBa66B85E10E7Fd18a67a6859E241A243950e\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xeF684C38F94F48775959ECf2012D7E864ffb9dd4\"\n case NETWORK.OPTIMISM:\n return \"0x278d6b1aA37d09769E519f05FcC5923161A8536D\"\n case NETWORK.ARBITRUM:\n return \"0xB0b9f73B424AD8dc58156C2AE0D7A1115D1EcCd1\"\n case NETWORK.AVALANCHE:\n return \"0xCFdC4d6FdeC25e339ef07e25C35a482A6bedcfE0\"\n }\n return \"\"\n}\n\nexport function getCollateral(chainId: number, isWeth: boolean): string {\n if (isWeth) {\n return getWETHAddress(chainId)\n } else {\n return getUSDCAddress(chainId)\n }\n}\n\nfunction getUSDCAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"\n case NETWORK.POLYGON:\n return \"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\"\n case NETWORK.GOERLI:\n return \"0x07865c6E87B9F70255377e024ace6630C1Eaa37F\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83\"\n case NETWORK.OPTIMISM:\n return \"0x7F5c764cBc14f9669B88837ca1490cCa17c31607\"\n case NETWORK.ARBITRUM:\n return \"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8\"\n case NETWORK.AVALANCHE:\n return \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\"\n }\n return \"\"\n}\n\nfunction getWETHAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"\n case NETWORK.POLYGON:\n return \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\"\n case NETWORK.GOERLI:\n return \"0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1\"\n case NETWORK.OPTIMISM:\n return \"0x4200000000000000000000000000000000000006\"\n case NETWORK.ARBITRUM:\n return \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\"\n case NETWORK.AVALANCHE:\n return \"0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB\"\n }\n return \"\"\n}\n\nexport function getKlerosAddress(chainId: number): string {\n // TODO: Add addresses when Kleros becomes available.\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0xf72cfd1b34a91a64f9a98537fe63fbab7530adca\"\n case NETWORK.GOERLI:\n return \"0xba08deb3f07a9c55052777fed84a86be8e5ebc1c\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x29f39de98d750eb77b5fafb31b2837f079fce222\"\n case NETWORK.POLYGON:\n return \"0x5AFa42b30955f137e10f89dfb5EF1542a186F90e\"\n }\n return \"\"\n}\n\nexport function getArbitrator(chainId: number, arbitratorOption: number): string {\n switch (arbitratorOption) {\n case ARBITRATOR_OPTIONS.NO_ARBITRATOR:\n // Setting the oracle as the arbitrator is equivalent to setting a null arbitrator.\n return getDefaultOracle(chainId)\n case ARBITRATOR_OPTIONS.KLEROS:\n return getKlerosAddress(chainId)\n case ARBITRATOR_OPTIONS.OTHER:\n return \"\"\n }\n return \"\"\n}\n\nexport function getConnextAddress(chainId: number): string {\n switch (chainId) {\n case NETWORK.MAINNET:\n return \"0x8898B472C54c31894e3B9bb83cEA802a5d0e63C6\"\n case NETWORK.POLYGON:\n return \"0x11984dc4465481512eb5b777E44061C158CF2259\"\n case NETWORK.GOERLI:\n return \"0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649\"\n case NETWORK.GNOSIS_CHAIN:\n return \"0x5bB83e95f63217CDa6aE3D181BA580Ef377D2109\"\n case NETWORK.OPTIMISM:\n return \"0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA\"\n case NETWORK.ARBITRUM:\n return \"0xEE9deC2712cCE65174B561151701Bf54b99C24C8\"\n }\n return \"\"\n}\n\nexport function deployTellorModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: TellorModuleParams,\n) {\n const type = KnownContracts.TELLOR\n const { owner, oracle, cooldown, expiration, executor } = args\n const oracleAddress = oracle || getTellorOracle(chainId)\n\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"uint32\", \"uint32\"],\n values: [owner, safeAddress, executor, oracleAddress, cooldown, expiration],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n\nexport function deployDelayModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: DelayModuleParams,\n) {\n const { cooldown, expiration, executor } = args as unknown as DelayModuleParams\n const {\n transaction: delayModuleDeploymentTx,\n expectedModuleAddress: delayModuleExpectedAddress,\n } = deployAndSetUpModule(\n KnownContracts.DELAY,\n {\n types: [\"address\", \"address\", \"address\", \"uint256\", \"uint256\"],\n values: [safeAddress, safeAddress, executor, cooldown, expiration],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableDelayModuleTransaction = enableModule(\n safeAddress,\n delayModuleExpectedAddress,\n )\n\n return [\n {\n ...delayModuleDeploymentTx,\n value: delayModuleDeploymentTx.value.toString(),\n },\n enableDelayModuleTransaction,\n ]\n}\n\nexport function deployBridgeModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: AMBModuleParams,\n) {\n const { executor, controller, amb, chainId: ambChainId } = args\n\n const { transaction, expectedModuleAddress } = deployAndSetUpModule(\n KnownContracts.BRIDGE,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"address\", \"bytes32\"],\n values: [\n safeAddress,\n safeAddress,\n executor,\n amb,\n controller,\n ethers.utils.hexZeroPad(BigNumber.from(ambChainId).toHexString(), 32),\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const enableModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n\n return [\n {\n ...transaction,\n value: transaction.value.toString(),\n },\n enableModuleTransaction,\n ]\n}\n\nexport function deployCirculatingSupplyContract(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n token: string,\n saltNonce: string,\n isERC721?: boolean,\n) {\n const type: KnownContracts = isERC721\n ? KnownContracts.CIRCULATING_SUPPLY_ERC721\n : KnownContracts.CIRCULATING_SUPPLY_ERC20\n\n const { moduleFactory, moduleMastercopy: circulatingSupplyContract } =\n getModuleFactoryAndMasterCopy(type, provider, chainId)\n\n const encodedInitParams = new ethers.utils.AbiCoder().encode(\n [\"address\", \"address\", \"address[]\"],\n [safeAddress, token, [safeAddress]],\n )\n const moduleSetupData = circulatingSupplyContract.interface.encodeFunctionData(\n \"setUp\",\n [encodedInitParams],\n )\n\n const expectedAddress = calculateProxyAddress(\n moduleFactory as Contract,\n circulatingSupplyContract.address,\n moduleSetupData,\n saltNonce,\n )\n\n const deployData = moduleFactory.interface.encodeFunctionData(\"deployModule\", [\n circulatingSupplyContract.address,\n moduleSetupData,\n saltNonce,\n ])\n\n const transaction = {\n data: deployData,\n to: moduleFactory.address,\n value: \"0\",\n }\n return {\n transaction,\n expectedAddress,\n }\n}\n\nexport async function deployExitModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: ExitModuleParams,\n) {\n const txs: BaseTransaction[] = []\n const { executor, tokenContract } = args\n\n let isERC721 = false\n try {\n const ERC721Contract = new Contract(tokenContract, ERC721_CONTRACT_ABI, provider)\n isERC721 = await ERC721Contract.supportsInterface(\"0x80ac58cd\")\n } catch (err) {\n console.warn(\"deployExitModule: error determining token type\")\n }\n\n const {\n transaction: deployCirculationSupplyTx,\n expectedAddress: circulatingSupplyAddress,\n } = deployCirculatingSupplyContract(\n provider,\n safeAddress,\n chainId,\n tokenContract,\n Date.now().toString(),\n isERC721,\n )\n\n txs.push(deployCirculationSupplyTx)\n\n const type = isERC721 ? KnownContracts.EXIT_ERC721 : KnownContracts.EXIT_ERC20\n\n const { transaction, expectedModuleAddress } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"address\"],\n values: [\n safeAddress,\n safeAddress,\n executor,\n tokenContract,\n circulatingSupplyAddress,\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n txs.push({\n ...transaction,\n value: transaction.value.toString(),\n })\n\n const enableModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n txs.push(enableModuleTransaction)\n\n return txs\n}\n\nexport async function fetchSafeModulesAddress(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n) {\n const safe = new Contract(safeAddress, SafeAbi, provider)\n const [modules] = await safe.getModulesPaginated(AddressOne, 50)\n return modules as string[]\n}\n\nexport function enableModule(safeAddress: string, module: string) {\n return buildTransaction(new Interface(SafeAbi), safeAddress, \"enableModule\", [module])\n}\n\nexport async function disableModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n module: string,\n) {\n const modules = await fetchSafeModulesAddress(provider, safeAddress, chainId)\n if (!modules.length) throw new Error(\"Safe does not have enabled modules\")\n let prevModule = AddressOne\n if (modules.length > 1) {\n const moduleIndex = modules.findIndex((m) => m.toLowerCase() === module.toLowerCase())\n if (moduleIndex > 0) prevModule = modules[moduleIndex - 1]\n }\n const params = [prevModule, module]\n return {\n params,\n ...buildTransaction(new Interface(SafeAbi), safeAddress, \"disableModule\", params),\n }\n}\n\nexport const callContract = (\n provider: JsonRpcProvider,\n chainId: number,\n address: string,\n abi: ContractInterface,\n method: string,\n data: any[] = [],\n) => {\n const contract = new Contract(address, abi, provider)\n return contract.functions[method](...data)\n}\n\nexport async function fetchSafeBalanceInfo(chainId: number, safeAddress: string) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) return []\n\n const url = new URL(\n `api/v1/safes/${safeAddress}/balances/?trusted=false&exclude_spam=false`,\n network.safeTransactionApi,\n )\n\n const request = await fetch(url.toString())\n const response = await request.json()\n console.log(\"response\", response)\n return response.results\n}\n\nexport async function fetchSafeTransactions(\n chainId: number,\n safeAddress: string,\n params: Record,\n) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) return []\n\n const url = new URL(\n `api/v1/safes/${safeAddress}/transactions`,\n network.safeTransactionApi,\n )\n\n Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, value))\n\n const request = await fetch(url.toString())\n const response = await request.json()\n\n return response.results as SafeTransaction[]\n}\n\nexport async function fetchSafeStatusFromAPI(chainId: number, safeAddress: string) {\n const network = getNetworkExplorerInfo(chainId)\n if (!network) throw new Error(\"invalid network\")\n\n const url = new URL(`api/v1/safes/${safeAddress}`, network.safeTransactionApi)\n\n const request = await fetch(url.toString())\n const response = await request.json()\n return response as SafeStatusResponse\n}\n\nexport function deployRolesV1Modifier(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RolesModifierParams,\n) {\n const { target, multisend } = args\n const { transaction: deployAndSetupTx, expectedModuleAddress: expectedRolesAddress } =\n deployAndSetUpModule(\n KnownContracts.ROLES_V1,\n {\n types: [\"address\", \"address\", \"address\"],\n values: [safeAddress, safeAddress, target],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableModuleTx = enableModule(safeAddress, expectedRolesAddress)\n\n const rolesContract = getModuleInstance(\n KnownContracts.ROLES_V1,\n expectedRolesAddress,\n provider,\n )\n\n const setMultisendTx = buildTransaction(\n rolesContract.interface,\n rolesContract.address,\n \"setMultisend\",\n [multisend],\n )\n\n return [\n {\n ...deployAndSetupTx,\n value: deployAndSetupTx.value.toHexString(),\n },\n enableModuleTx,\n setMultisendTx,\n ]\n}\n\nexport function deployRolesV2Modifier(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RolesModifierParams,\n) {\n const { target, multisend } = args\n const { transaction: deployAndSetupTx, expectedModuleAddress: expectedRolesAddress } =\n deployAndSetUpModule(\n KnownContracts.ROLES_V2,\n {\n types: [\"address\", \"address\", \"address\"],\n values: [safeAddress, safeAddress, target],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n const enableModuleTx = enableModule(safeAddress, expectedRolesAddress)\n\n const rolesContract = getModuleInstance(\n KnownContracts.ROLES_V2,\n expectedRolesAddress,\n provider,\n )\n\n const MULTISEND_SELECTOR = \"0x8d80ff0a\"\n const MULTISEND_UNWRAPPER = \"0x93B7fCbc63ED8a3a24B59e1C3e6649D50B7427c0\"\n const setUnwrapperTx = {\n to: rolesContract.address,\n data: rolesContract.interface.encodeFunctionData(\"setTransactionUnwrapper\", [\n multisend,\n MULTISEND_SELECTOR,\n MULTISEND_UNWRAPPER,\n ]),\n value: \"0\",\n }\n\n return [\n {\n ...deployAndSetupTx,\n value: deployAndSetupTx.value.toHexString(),\n },\n enableModuleTx,\n setUnwrapperTx,\n ]\n}\n\nexport function deployOptimisticGovernorModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: OptimisticGovernorModuleParams,\n isWeth: boolean,\n) {\n const type = KnownContracts.OPTIMISTIC_GOVERNOR\n\n const { executor, collateral, bond, rules, identifier, liveness } = args\n\n const scaledBond = scaleBondDecimals(bond, isWeth).toString()\n\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"uint256\", \"string\", \"bytes32\", \"uint64\"],\n values: [executor, collateral, scaledBond, rules, identifier, liveness],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n\nexport function deployConnextModule(\n provider: JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: ConnextModuleParams,\n) {\n const type = KnownContracts.CONNEXT\n const { domainId, sender, owner, avatar, target } = args\n const connextAddress = getConnextAddress(chainId)\n const {\n transaction: connextModuleDeploymentTx,\n expectedModuleAddress: connextModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\"address\", \"address\", \"address\", \"address\", \"uint32\", \"address\"],\n values: [owner, avatar, target, sender, domainId, connextAddress],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const connextModuleTransactions: BaseTransaction[] = [\n {\n ...connextModuleDeploymentTx,\n value: connextModuleDeploymentTx.value.toString(),\n },\n ]\n\n const enableConnextModuleTransaction = enableModule(\n safeAddress,\n connextModuleExpectedAddress,\n )\n connextModuleTransactions.push(enableConnextModuleTransaction)\n\n return connextModuleTransactions\n}\n","import { ContractInterface } from \"@ethersproject/contracts\"\nimport { ContractAbis, KnownContracts } from \"@gnosis.pm/zodiac\"\n\nexport enum ModuleType {\n TELLOR = \"tellor\",\n OPTIMISTIC_GOVERNOR = \"optimisticGovernor\",\n REALITY_ETH = \"realityETH\",\n REALITY_ERC20 = \"realityERC20\",\n DELAY = \"delay\",\n BRIDGE = \"bridge\",\n EXIT = \"exit\",\n ROLES_V1 = \"roles_v1\",\n ROLES_V2 = \"roles_v2\",\n OZ_GOVERNOR = \"ozGovernor\",\n KLEROS_REALITY = \"klerosReality\",\n CONNEXT = \"connext\",\n UNKNOWN = \"unknown\",\n}\n\nexport const MODULE_NAMES: Record = {\n [ModuleType.TELLOR]: \"Tellor Module\",\n [ModuleType.OPTIMISTIC_GOVERNOR]: \"UMA oSnap Module\",\n [ModuleType.REALITY_ERC20]: \"Reality Module\",\n [ModuleType.REALITY_ETH]: \"Reality Module\",\n [ModuleType.KLEROS_REALITY]: \"Kleros Reality Module\",\n [ModuleType.UNKNOWN]: \"Unknown Module\",\n [ModuleType.BRIDGE]: \"Bridge Module\",\n [ModuleType.DELAY]: \"Delay Modifier\",\n [ModuleType.ROLES_V1]: \"Roles Modifier (v1)\",\n [ModuleType.ROLES_V2]: \"Roles Modifier (v2)\",\n [ModuleType.EXIT]: \"Exit Module\",\n [ModuleType.OZ_GOVERNOR]: \"Governor Module\",\n [ModuleType.CONNEXT]: \"Connext Module\",\n}\n\nexport const MODULE_ABIS: Record = {\n [ModuleType.TELLOR]: ContractAbis[KnownContracts.TELLOR],\n [ModuleType.OPTIMISTIC_GOVERNOR]: ContractAbis[KnownContracts.OPTIMISTIC_GOVERNOR],\n [ModuleType.REALITY_ERC20]: ContractAbis[KnownContracts.REALITY_ERC20],\n [ModuleType.REALITY_ETH]: ContractAbis[KnownContracts.REALITY_ETH],\n [ModuleType.KLEROS_REALITY]: ContractAbis[KnownContracts.REALITY_ETH],\n [ModuleType.UNKNOWN]: [],\n [ModuleType.BRIDGE]: ContractAbis[KnownContracts.BRIDGE],\n [ModuleType.DELAY]: ContractAbis[KnownContracts.DELAY],\n [ModuleType.ROLES_V1]: ContractAbis[KnownContracts.ROLES_V1],\n [ModuleType.ROLES_V2]: ContractAbis[KnownContracts.ROLES_V2],\n [ModuleType.EXIT]: ContractAbis[KnownContracts.EXIT_ERC20],\n [ModuleType.OZ_GOVERNOR]: ContractAbis[KnownContracts.OZ_GOVERNOR],\n [ModuleType.CONNEXT]: ContractAbis[KnownContracts.CONNEXT],\n}\n\nexport enum ModuleOperation {\n CREATE,\n REMOVE,\n}\n\nexport interface Module {\n id: string\n name?: string\n address: string\n type: ModuleType\n subModules: Module[]\n owner?: string\n parentModule: string\n}\n\nexport interface ModuleContract {\n address: string\n implAddress: string\n type: ModuleType\n name?: string\n abi?: ContractInterface\n}\n\nexport interface ModuleContractMetadata {\n type: ModuleType\n name?: string\n abi: ContractInterface\n}\n\nexport interface DelayModule extends Module {\n type: ModuleType.DELAY\n expiration: number\n cooldown: number\n}\n\nexport interface TellorModule extends Module {\n type: ModuleType.TELLOR\n owner: string\n executor: string\n oracle: string\n expiration: number\n cooldown: number\n}\n\nexport interface OptimisticGovernorModule extends Module {\n type: ModuleType.OPTIMISTIC_GOVERNOR\n finder: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n}\n\nexport interface RealityModule extends Module {\n type: ModuleType.REALITY_ETH\n executor: string\n oracle: string\n expiration: number\n bond: string\n templateId: string\n cooldown: number\n arbitrator: string\n}\n\nexport interface ConnextModule extends Module {\n type: ModuleType.CONNEXT\n domainId: string\n sender: string\n owner: string\n avatar: string\n target: string\n connext: string\n}\n\nexport interface ModulesState {\n operation: Operation\n current?: Module\n currentPendingModule?: PendingModule\n loadingModules: boolean\n list: Module[]\n reloadCount: number\n safeThreshold: number\n pendingModules: PendingModule[]\n moduleAdded: boolean\n realityModuleScreen: boolean\n OzGovernorModuleScreen: boolean\n}\n\nexport type Operation = \"read\" | \"write\"\n\nexport interface DataDecoded {\n method: string\n parameters: { name?: string; value?: string }[]\n}\n\nexport interface MultiSendDataDecoded extends DataDecoded {\n method: \"multiSend\"\n parameters: {\n name: \"transactions\"\n type: \"bytes\"\n value: string\n valueDecoded: DecodedTransaction[]\n }[]\n}\n\nexport interface RawTransaction {\n to: string\n data: string\n value: string\n nonce: number\n operation: 0 | 1\n}\n\nexport interface DecodedTransaction extends RawTransaction {\n dataDecoded: DataDecoded\n}\n\nexport interface SafeTransaction extends DecodedTransaction {\n safe: string\n gasToken: string\n}\n\nexport interface SafeStatusResponse {\n address: string\n nonce: number\n threshold: number\n owners: string[]\n masterCopy: string\n modules: string[]\n fallbackHandler: string\n guard: string\n version: string\n}\n\nexport interface PendingModule {\n operation: ModuleOperation\n module: ModuleType\n address: string\n executor: string\n}\n","import { Contract, ethers } from \"ethers\"\nimport {\n MODULE_ABIS,\n MODULE_NAMES,\n ModuleContractMetadata,\n ModuleType,\n} from \"../store/modules/models\"\nimport { NETWORK } from \"./networks\"\n\nconst GNOSIS_GENERIC_PROXY_CONTRACT_BYTECODE =\n \"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea265627a7a72315820d8a00dc4fe6bf675a9d7416fc2d00bb3433362aa8186b750f76c4027269667ff64736f6c634300050e0032\"\n\nconst GNOSIS_GENERIC_PROXY_CONTRACT_ABI = [\n \"function masterCopy() external view returns (address)\",\n]\n\nexport function getModuleType(type: string): ModuleType {\n const moduleType = Object.keys(ModuleType).find((moduleType) => moduleType === type)\n if (!moduleType) return ModuleType.UNKNOWN\n return moduleType as ModuleType\n}\n\nexport function getModuleContractMetadata(\n module: ModuleType,\n): ModuleContractMetadata | undefined {\n if (module === ModuleType.UNKNOWN) return\n return { type: module, name: MODULE_NAMES[module], abi: MODULE_ABIS[module] }\n}\n\nexport function isGnosisGenericProxy(bytecode: string) {\n return bytecode.toLowerCase() === GNOSIS_GENERIC_PROXY_CONTRACT_BYTECODE\n}\n\nexport function isGenericProxy(bytecode: string) {\n if (bytecode.length !== 92) return false\n return (\n bytecode.startsWith(\"0x363d3d373d3d3d363d73\") &&\n bytecode.endsWith(\"5af43d82803e903d91602b57fd5bf3\")\n )\n}\n\nexport function getGenericProxyMaster(bytecode: string) {\n return \"0x\" + bytecode.substr(22, 40)\n}\n\nexport async function getProxyMaster(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n chainId: NETWORK,\n) {\n const contract = new Contract(address, GNOSIS_GENERIC_PROXY_CONTRACT_ABI, provider)\n\n const [masterAddress] = await contract.functions.masterCopy()\n\n return masterAddress\n}\n","import {\n defaultAbiCoder,\n FunctionFragment,\n Interface,\n ParamType,\n} from \"@ethersproject/abi\"\nimport memoize from \"lodash.memoize\"\nimport { getNetworkExplorerInfo } from \"./explorers\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n getGenericProxyMaster,\n getModuleContractMetadata,\n getProxyMaster,\n isGenericProxy,\n isGnosisGenericProxy,\n} from \"./modulesValidation\"\nimport { ModuleContract, ModuleType } from \"../store/modules/models\"\nimport retry from \"async-retry\"\nimport { BigNumber, ethers } from \"ethers\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport { getContractsModuleType, getModuleName } from \"../store/modules/helpers\"\n\nexport function isWriteFunction(method: FunctionFragment) {\n if (!method.stateMutability) return true\n return ![\"view\", \"pure\"].includes(method.stateMutability)\n}\n\nexport function isReadFunction(method: FunctionFragment) {\n return !isWriteFunction(method)\n}\n\nexport function getReadFunction(abi: ContractInterface) {\n const inter = abi instanceof Interface ? abi : new Interface(abi as any)\n return inter.fragments\n .filter(FunctionFragment.isFunctionFragment)\n .map(FunctionFragment.from)\n .filter(isReadFunction)\n}\n\nexport function getWriteFunction(abi: ContractInterface) {\n const inter = abi instanceof Interface ? abi : new Interface(abi as any)\n return inter.fragments\n .filter(FunctionFragment.isFunctionFragment)\n .map(FunctionFragment.from)\n .filter(isWriteFunction)\n}\n\nexport const fetchContractSourceCode = memoize(\n (chainId: number, contractAddress: string) =>\n retry(\n async (bail) => {\n const network = getNetworkExplorerInfo(chainId)\n\n if (!network) throw new Error(\"Network data not found\")\n\n const { apiUrl, apiKey } = network\n\n const urlParams: Record = {\n module: \"contract\",\n action: \"getsourcecode\",\n address: contractAddress,\n }\n\n if (apiKey) {\n urlParams.apiKey = apiKey\n }\n\n const params = new URLSearchParams(urlParams)\n\n const response = await fetch(`${apiUrl}?${params}`)\n\n if (!response.ok) throw new Error(\"Could not fetch contract source code\")\n\n const { status, result } = await response.json()\n if (status === \"0\") throw new Error(\"Could not fetch contract source code\")\n\n const data = result[0] as { ABI: string; ContractName: string }\n\n if (!data.ContractName) bail(new Error(\"Contract is not verified\"))\n\n return data\n },\n { retries: 4, minTimeout: 1000 },\n ),\n (chainId: number, contractAddress: string) => `${chainId}_${contractAddress}`,\n)\n\nexport function isBasicFunction(func: FunctionFragment) {\n return !func.inputs.length\n}\n\nexport function isOneResult(func: FunctionFragment) {\n return (\n func.outputs?.length === 1 && func.outputs && func.outputs[0]?.baseType !== \"array\"\n )\n}\n\nexport function validateFunctionParamValue(param: ParamType, value: any): boolean {\n try {\n defaultAbiCoder.encode([param], [value])\n return true\n } catch (error) {\n return false\n }\n}\n\nexport function validateFunctionParams(func: FunctionFragment, params: any[]): boolean {\n try {\n defaultAbiCoder.encode(func.inputs, params)\n return true\n } catch (error) {\n return false\n }\n}\n\n/**\n * Formats and Validate a param value.\n * @param param - Contract Function Param.\n * @param value - Value.\n */\nexport function formatParamValue(param: ParamType, value: string): any {\n let _value = value\n if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n try {\n _value = JSON.parse(_value)\n } catch (e) {\n throw new Error(\"Input must be of type \" + param.baseType)\n }\n }\n\n if (!validateFunctionParamValue(param, _value)) {\n throw new Error(\"Input must be of type \" + param.type)\n }\n\n return _value\n}\n\n/**\n * Formats and Validate a param value.\n * @param param - Contract Function Param.\n * @param value - Value.\n */\nexport function formatDisplayParamValue(param: ParamType, value: any): string {\n if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n try {\n return JSON.stringify(value)\n } catch (e) {\n console.warn(\"formatDisplayParamValue: value is not an object\", value, e)\n }\n }\n return value.toString()\n}\n\nexport const getModuleData = memoize(\n async (\n provider: ethers.providers.JsonRpcProvider,\n safeSDK: SafeAppsSDK,\n chainId: number,\n address: string,\n ): Promise => {\n const bytecode = await safeSDK.eth.getCode([address])\n\n if (isGenericProxy(bytecode)) {\n const masterAddress = getGenericProxyMaster(bytecode)\n const module: ModuleContract = await getModuleData(\n provider,\n safeSDK,\n chainId,\n masterAddress,\n )\n return { ...module, address }\n }\n\n if (isGnosisGenericProxy(bytecode)) {\n const masterAddress = await getProxyMaster(provider, address, chainId)\n const module: ModuleContract = await getModuleData(\n provider,\n safeSDK,\n chainId,\n masterAddress,\n )\n return { ...module, address }\n }\n\n const type = getContractsModuleType(chainId, address)\n if (type !== ModuleType.UNKNOWN) {\n return {\n type,\n address,\n implAddress: address,\n name: getModuleName(type),\n ...getModuleContractMetadata(type),\n }\n }\n\n try {\n const { ABI, ContractName } = await fetchContractSourceCode(chainId, address)\n\n return {\n address,\n implAddress: address,\n name: ContractName,\n abi: ABI,\n type: ModuleType.UNKNOWN,\n }\n } catch (error) {\n return { address, implAddress: address, type: ModuleType.UNKNOWN }\n }\n },\n (sdk, chainId, address, provider) => `${chainId}_${address}_${provider}`,\n)\n\nexport function formatValue(\n baseType: string,\n value: string | BigNumber | boolean,\n): string {\n if (baseType === \"array\" || baseType === \"tuple\") {\n value = JSON.stringify(value)\n }\n\n return value.toString()\n}\n","import { Contract as MultiCallContract, Provider as MultiCallProvider } from \"ethcall\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n ContractAddresses,\n ContractVersions,\n getModuleInstance,\n KnownContracts,\n SupportedNetworks,\n} from \"@gnosis.pm/zodiac\"\nimport { getModuleData } from \"../../utils/contracts\"\nimport {\n DataDecoded,\n DecodedTransaction,\n DelayModule,\n Module,\n MODULE_NAMES,\n ModuleContract,\n ModuleOperation,\n ModuleType,\n MultiSendDataDecoded,\n PendingModule,\n RealityModule,\n SafeTransaction,\n} from \"./models\"\nimport { Contract, ethers } from \"ethers\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const AddressOne = \"0x0000000000000000000000000000000000000001\"\n\nexport function isDelayModule(module: Module): module is DelayModule {\n return module.type === ModuleType.DELAY\n}\n\nexport function isRealityModule(module: Module): module is RealityModule {\n return (\n module.type === ModuleType.REALITY_ETH || module.type === ModuleType.REALITY_ERC20\n )\n}\n\nexport const sanitizeModule = async (\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n sdk: SafeAppsSDK,\n chainId: number,\n parentModule: string,\n parentModulesList: string[] = [moduleAddress],\n): Promise => {\n const module = await getModuleData(provider, sdk, chainId, moduleAddress)\n\n if (module.type === ModuleType.DELAY) {\n return await fetchDelayModule(provider, moduleAddress, sdk, chainId, parentModule)\n }\n\n const subModules = await fetchSubModules(\n provider,\n moduleAddress,\n module.abi,\n sdk,\n chainId,\n parentModulesList,\n )\n\n const owner = await fetchModuleOwner(provider, moduleAddress, module.abi, chainId)\n\n return {\n owner,\n subModules,\n id: moduleAddress,\n name: module.name,\n type: module.type,\n address: moduleAddress,\n parentModule: parentModule,\n }\n}\n\nexport async function fetchDelayModule(\n provider: ethers.providers.JsonRpcProvider,\n address: string,\n sdk: SafeAppsSDK,\n chainId: NETWORK,\n parentModule: string,\n): Promise {\n const delayModule = await getModuleInstance(KnownContracts.DELAY, address, provider)\n const abi = delayModule.interface.fragments.map((frag) => frag)\n\n try {\n const moduleContract = new MultiCallContract(delayModule.address, abi)\n\n const ethCallProvider = new MultiCallProvider()\n await ethCallProvider.init(provider as any)\n\n const txCooldown = moduleContract.txCooldown()\n const txExpiration = moduleContract.txExpiration()\n const modules = moduleContract.getModulesPaginated(AddressOne, 50)\n\n let [cooldown, expiration, [subModules]] = await ethCallProvider.all([\n txCooldown,\n txExpiration,\n modules,\n ])\n\n if (subModules) {\n const requests = (subModules as string[]).map(\n async (moduleAddress, index): Promise => {\n const subModule = await sanitizeModule(\n provider,\n moduleAddress,\n sdk,\n chainId,\n parentModule,\n )\n return {\n ...subModule,\n id: `${address}_${moduleAddress}_${index}`,\n parentModule: address,\n }\n },\n )\n requests.reverse()\n subModules = await Promise.all(requests)\n }\n\n const owner = await fetchModuleOwner(provider, address, abi, chainId)\n\n return {\n owner,\n address,\n parentModule,\n id: address,\n name: \"Delay Module\",\n type: ModuleType.DELAY,\n subModules: subModules || [],\n expiration: expiration.toString(),\n cooldown: cooldown.toString(),\n }\n } catch (error) {\n console.warn(\"Error fetching delay module\", error)\n return {\n address,\n parentModule,\n id: address,\n name: \"Delay Module\",\n type: ModuleType.UNKNOWN,\n subModules: [],\n }\n }\n}\n\nexport async function fetchSubModules(\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n abi: ModuleContract[\"abi\"],\n sdk: SafeAppsSDK,\n chainId: number,\n parentModulesList: string[] = [],\n): Promise {\n try {\n if (!abi) return []\n const contract = new Contract(moduleAddress, abi, provider)\n contract.interface.getFunction(\"getModulesPaginated(address,uint256)\")\n const [subModules] = await contract.getModulesPaginated(AddressOne, 50)\n const modulesList = [...parentModulesList, ...subModules]\n return await Promise.all(\n subModules\n .filter((module: string) => !parentModulesList.includes(module))\n .map(async (subModuleAddress: string, index: number) => {\n const subModule = await sanitizeModule(\n provider,\n subModuleAddress,\n sdk,\n chainId,\n moduleAddress,\n modulesList,\n )\n return {\n ...subModule,\n id: `${moduleAddress}_${subModuleAddress}_${index}`,\n parentModule: moduleAddress,\n }\n }),\n )\n } catch (e) {\n return []\n }\n}\n\nexport async function fetchModuleOwner(\n provider: ethers.providers.JsonRpcProvider,\n moduleAddress: string,\n abi: ModuleContract[\"abi\"],\n chainId: NETWORK,\n): Promise {\n try {\n if (!abi) return undefined\n const contract = new Contract(moduleAddress, abi, provider)\n contract.interface.getFunction(\"owner()\")\n return await contract.owner()\n } catch (e) {\n return undefined\n }\n}\n\nexport function isMultiSendDataEncoded(\n dataEncoded: DataDecoded,\n): dataEncoded is MultiSendDataDecoded {\n return dataEncoded.method === \"multiSend\"\n}\n\nexport function getTransactionsFromSafeTransaction(\n safeTransaction: SafeTransaction,\n): DecodedTransaction[] {\n if (\n safeTransaction.dataDecoded &&\n isMultiSendDataEncoded(safeTransaction.dataDecoded)\n ) {\n return safeTransaction.dataDecoded.parameters[0].valueDecoded\n }\n return [safeTransaction]\n}\n\nconst ZODIAC_CONTRACTS_TO_MODULE_TYPE: { [key: string]: ModuleType } = {\n [KnownContracts.TELLOR]: ModuleType.TELLOR,\n [KnownContracts.OPTIMISTIC_GOVERNOR]: ModuleType.OPTIMISTIC_GOVERNOR,\n [KnownContracts.REALITY_ETH]: ModuleType.REALITY_ETH,\n [KnownContracts.REALITY_ERC20]: ModuleType.REALITY_ERC20,\n [KnownContracts.DELAY]: ModuleType.DELAY,\n [KnownContracts.BRIDGE]: ModuleType.BRIDGE,\n [KnownContracts.EXIT_ERC20]: ModuleType.EXIT,\n [KnownContracts.ROLES]: ModuleType.ROLES_V1,\n [KnownContracts.ROLES_V1]: ModuleType.ROLES_V1,\n [KnownContracts.ROLES_V2]: ModuleType.ROLES_V2,\n [KnownContracts.OZ_GOVERNOR]: ModuleType.OZ_GOVERNOR,\n}\n\nexport function getContractsModuleType(\n chainId: number,\n masterCopyAddress: string,\n): ModuleType {\n const contractVersions = ContractVersions[chainId as SupportedNetworks]\n if (!contractVersions) return ModuleType.UNKNOWN\n\n const entry = Object.entries(contractVersions).find(([, addresses]) => {\n return Object.values(addresses).some(\n (address) => address.toLowerCase() === masterCopyAddress.toLowerCase(),\n )\n })\n if (!entry) return ModuleType.UNKNOWN\n return ZODIAC_CONTRACTS_TO_MODULE_TYPE[entry[0]] || ModuleType.UNKNOWN\n}\n\n/**\n * Determine if the safe transaction is a pending add module transaction.\n *\n * @param {object} safeTransaction - Safe Transaction.\n * @param {number} chainId - Chain Id.\n */\nexport function getAddModuleTransactionModuleType(\n safeTransaction: SafeTransaction,\n chainId: number,\n): ModuleType | undefined {\n const factoryAddress = ContractAddresses[chainId as SupportedNetworks]?.factory || \"\"\n const transactions = getTransactionsFromSafeTransaction(safeTransaction)\n\n const masterCopyAddress = transactions\n .map((transaction): string | undefined => {\n if (transaction.to.toLowerCase() === factoryAddress.toLowerCase()) {\n if (!transaction.dataDecoded) {\n // Decode Proxy Factory data locally\n try {\n const result = decodeProxyFactoryTransaction(transaction.data)\n return result[0] // return first parameter (masterCopy)\n } catch (err) {\n console.warn(\"failed to decode proxy factory transaction: \", transaction.data)\n return undefined\n }\n }\n\n if (transaction.dataDecoded.method === \"deployModule\") {\n const param = transaction.dataDecoded.parameters?.find(\n (param) => param.name === \"masterCopy\",\n )\n if (param) return param.value\n }\n }\n return undefined\n })\n .find((x) => x)\n\n return getContractsModuleType(chainId, masterCopyAddress || \"\")\n}\n\nconst MODULE_PROXY_FACTORY_ABI = [\n \"function deployModule(address masterCopy, bytes initializer, uint256 saltNonce) returns (address proxy)\",\n]\n\nfunction decodeProxyFactoryTransaction(data: string) {\n return new ethers.utils.Interface(MODULE_PROXY_FACTORY_ABI).decodeFunctionData(\n \"deployModule\",\n data,\n )\n}\n\nexport function isSafeEnableModuleTransactionPending(transaction: DecodedTransaction) {\n return transaction.dataDecoded && transaction.dataDecoded.method === \"enableModule\"\n}\n\n/**\n * Determine if the safe transaction is a pending remove module transaction.\n *\n * @param {object} transaction - Transaction.\n */\nexport function isRemoveModuleTransactionPending(\n transaction: DecodedTransaction,\n): boolean {\n return transaction.dataDecoded && transaction.dataDecoded.method === \"disableModule\"\n}\n\nexport function getModulesToBeRemoved(\n modules: Module[],\n transactions: SafeTransaction[],\n): PendingModule[] {\n return transactions\n .flatMap(getTransactionsFromSafeTransaction)\n .filter(isRemoveModuleTransactionPending)\n .map((transaction) => {\n const param = transaction.dataDecoded.parameters.find(\n (param) => param.name === \"module\",\n )\n const moduleAddress = param && param.value ? param.value : \"\"\n const current = modules.find((module) => module.address === moduleAddress)\n return {\n address: moduleAddress,\n executor: transaction.to,\n operation: ModuleOperation.REMOVE,\n module: current ? current.type : ModuleType.UNKNOWN,\n }\n })\n}\n\nfunction getModuleTypeForAddTransactions(\n transactions: SafeTransaction[],\n chainId: number,\n): Record {\n return transactions\n .map((safeTransaction) => {\n const enableModuleTx = getTransactionsFromSafeTransaction(safeTransaction)\n .reverse()\n .find(isSafeEnableModuleTransactionPending)\n\n if (!enableModuleTx) return undefined\n\n const type = getAddModuleTransactionModuleType(safeTransaction, chainId)\n const param = enableModuleTx.dataDecoded.parameters?.find(\n (param) => param.name === \"module\",\n )\n const moduleExpectedAddress = param?.value\n if (!type || !moduleExpectedAddress) return undefined\n return { address: moduleExpectedAddress, type }\n })\n .reduce((obj, value): Record => {\n if (value)\n return {\n ...obj,\n [value.address]: value.type,\n }\n return obj\n }, {})\n}\n\nexport function getPendingModulesToEnable(\n transactions: SafeTransaction[],\n chainId: number,\n): PendingModule[] {\n const modulesTypesByContractAddress = getModuleTypeForAddTransactions(\n transactions,\n chainId,\n )\n\n return transactions\n .flatMap(getTransactionsFromSafeTransaction)\n .filter((transaction) => isSafeEnableModuleTransactionPending(transaction))\n .map((transaction): PendingModule => {\n const moduleAddress: string = transaction.dataDecoded.parameters[0].value || \"\"\n const moduleType =\n modulesTypesByContractAddress[moduleAddress] || ModuleType.UNKNOWN\n return {\n address: moduleAddress,\n executor: transaction.to,\n module: moduleType,\n operation: ModuleOperation.CREATE,\n }\n })\n}\n\nexport function isModule(module: PendingModule | Module): module is Module {\n return \"subModules\" in module\n}\n\nexport function flatAllModules(modules: Module[]): Module[] {\n const subModules = modules.flatMap((module) => flatAllModules(module.subModules))\n return [...modules, ...subModules]\n}\n\nexport function isPendingModule(module: Module, pendingModule: PendingModule) {\n return (\n pendingModule.address === module.address &&\n pendingModule.executor === module.parentModule\n )\n}\n\nexport function getModuleName(type?: ModuleType): string {\n return MODULE_NAMES[type || ModuleType.UNKNOWN]\n}\n","import { RootState } from \"../index\";\nimport { isRealityModule, isDelayModule } from \"./helpers\";\nimport { ModuleOperation } from \"./models\";\n\nexport function getCurrentModule(state: RootState) {\n return state.modules.current;\n}\n\nexport function getModulesList(state: RootState) {\n return state.modules.list;\n}\n\nexport function getReloadCount(state: RootState) {\n return state.modules.reloadCount;\n}\n\nexport function getIsLoadingModules(state: RootState) {\n return state.modules.loadingModules;\n}\n\nexport function getDelayModules(state: RootState) {\n return getModulesList(state).filter(isDelayModule);\n}\n\nexport function getRealityModules(state: RootState) {\n return getModulesList(state).filter(isRealityModule);\n}\n\nexport function getOperation(state: RootState) {\n return state.modules.operation;\n}\n\nexport function getPendingModules(state: RootState) {\n return state.modules.pendingModules;\n}\n\nexport function getPendingCreateModuleTransactions(state: RootState) {\n return getPendingModules(state).filter(\n (tx) => tx.operation === ModuleOperation.CREATE\n );\n}\n\nexport function getPendingRemoveModuleTransactions(state: RootState) {\n return getPendingModules(state).filter(\n (tx) => tx.operation === ModuleOperation.REMOVE\n );\n}\n\nexport function getSafeThreshold(state: RootState) {\n return state.modules.safeThreshold;\n}\n\nexport function getCurrentPendingModule(state: RootState) {\n return state.modules.currentPendingModule;\n}\n\nexport function getModuleAdded(state: RootState) {\n return state.modules.moduleAdded;\n}\n\nexport function getRealityModuleScreen(state: RootState) {\n return state.modules.realityModuleScreen;\n}\n","import { createAsyncThunk, createSlice, PayloadAction } from \"@reduxjs/toolkit\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\nimport { Module, ModulesState, Operation, PendingModule } from \"./models\"\nimport {\n fetchSafeStatusFromAPI,\n fetchSafeModulesAddress,\n fetchSafeTransactions,\n} from \"../../services\"\nimport {\n getModulesToBeRemoved,\n getPendingModulesToEnable,\n sanitizeModule,\n} from \"./helpers\"\nimport { getModulesList } from \"./selectors\"\nimport { RootState } from \"../index\"\nimport { ethers } from \"ethers\"\n\nconst initialModulesState: ModulesState = {\n operation: \"read\",\n reloadCount: 0,\n safeThreshold: 1,\n loadingModules: true,\n list: [],\n current: undefined,\n pendingModules: [],\n moduleAdded: false,\n realityModuleScreen: false,\n OzGovernorModuleScreen: false,\n}\n\nexport const fetchModulesList = createAsyncThunk(\n \"modules/fetchModulesList\",\n async (\n params: {\n provider: ethers.providers.JsonRpcProvider\n safeSDK: SafeAppsSDK\n chainId: number\n safeAddress: string\n },\n store,\n ): Promise => {\n const { provider, safeSDK, safeAddress, chainId } = params\n await provider.ready\n const moduleAddresses = await fetchSafeModulesAddress(provider, safeAddress, chainId)\n\n const requests = moduleAddresses.map(async (moduleAddress) => {\n try {\n return await sanitizeModule(\n provider,\n moduleAddress,\n safeSDK,\n chainId,\n safeAddress,\n )\n } catch (error) {\n throw new Error(`Error sanitizing module ${moduleAddress}: ${error}`)\n }\n })\n requests.reverse()\n try {\n const responses = await Promise.all(requests)\n return responses.filter((module): module is Module => module !== undefined)\n } catch (error) {\n console.error(\"Cant fetch modules\", error)\n throw error\n }\n },\n)\n\nexport const fetchPendingModules = createAsyncThunk(\n \"modules/fetchPendingModules\",\n async (\n {\n safeAddress,\n chainId,\n retry = true,\n }: {\n chainId: number\n safeAddress: string\n retry?: boolean\n },\n store,\n ) => {\n const safeStatusFromAPI = await fetchSafeStatusFromAPI(chainId, safeAddress)\n const transactions = await fetchSafeTransactions(chainId, safeAddress, {\n nonce__gte: safeStatusFromAPI.nonce.toString(),\n })\n\n const state = store.getState() as RootState\n const modules = getModulesList(state)\n\n const pendingEnableModules = getPendingModulesToEnable(transactions, chainId)\n\n const pendingRemoveModules = getModulesToBeRemoved(modules, transactions)\n\n const pendingModules: PendingModule[] = [\n ...pendingEnableModules,\n ...pendingRemoveModules,\n ]\n\n if (retry) {\n setTimeout(() => {\n store.dispatch(fetchPendingModules({ safeAddress, chainId, retry: false }))\n }, 4000)\n }\n\n return { safeInfo: safeStatusFromAPI, pendingModules }\n },\n)\n\nexport const modulesSlice = createSlice({\n name: \"modules\",\n initialState: initialModulesState,\n reducers: {\n increaseReloadCount: (state) => {\n state.reloadCount += 1\n },\n setCurrentModule(state, action: PayloadAction) {\n state.current = action.payload\n state.operation = \"read\"\n state.currentPendingModule = undefined\n },\n unsetCurrentModule(state) {\n state.current = undefined\n state.currentPendingModule = undefined\n },\n setOperation(state, action: PayloadAction) {\n state.operation = action.payload\n },\n setCurrentPendingModule(state, action: PayloadAction) {\n state.currentPendingModule = action.payload\n state.current = undefined\n },\n setModuleAdded(state, action: PayloadAction) {\n state.moduleAdded = action.payload\n },\n setRealityModuleScreen(state, action: PayloadAction) {\n state.realityModuleScreen = action.payload\n },\n setOzGovernorModuleScreen(state, action: PayloadAction) {\n state.OzGovernorModuleScreen = action.payload\n },\n },\n extraReducers: (builder) => {\n builder.addCase(fetchModulesList.rejected, (state) => {\n state.loadingModules = false\n })\n builder.addCase(fetchModulesList.fulfilled, (state, action) => {\n state.loadingModules = false\n state.list = action.payload\n const current = state.current\n if (current) {\n // Check if current module got removed\n const isPresent = action.payload.some(\n (module) => module.address === current.address,\n )\n if (!isPresent) {\n state.current = undefined\n }\n }\n })\n builder.addCase(fetchPendingModules.fulfilled, (state, action) => {\n const { safeInfo, pendingModules } = action.payload\n state.safeThreshold = safeInfo.threshold\n state.pendingModules = pendingModules\n })\n },\n})\n\nexport const {\n increaseReloadCount,\n setCurrentModule,\n unsetCurrentModule,\n setOperation,\n setCurrentPendingModule,\n setModuleAdded,\n setRealityModuleScreen,\n setOzGovernorModuleScreen,\n} = modulesSlice.actions\n","var _path, _path2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAvatarEmpty = function SvgAvatarEmpty(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 40,\n height: 40,\n viewBox: \"0 0 40 40\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M39 20H34M20 39V34M1 20H6M20 1V6\",\n stroke: \"#B2B5B2\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.435 33.435L29.8995 29.8995M6.56497 33.435L10.1005 29.8995M6.56497 6.56497L10.1005 10.1005M33.435 6.56497L29.8995 10.1005\",\n stroke: \"#B2B5B2\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAvatarEmpty, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/avatar-empty.8424ad03.svg\";\nexport { ForwardRef as ReactComponent };","import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\nimport {\n AddTransaction,\n SerializedTransaction,\n TransactionBuilderState,\n} from \"./models\";\n\nconst initialModulesState: TransactionBuilderState = {\n open: false,\n addTransaction: {},\n transactions: [],\n};\n\nexport const transactionBuilderSlice = createSlice({\n name: \"transactionBuilder\",\n initialState: initialModulesState,\n reducers: {\n openTransactionBuilder(state) {\n state.open = true;\n },\n closeTransactionBuilder(state) {\n state.open = false;\n },\n setTransactions(state, action: PayloadAction) {\n state.transactions = action.payload;\n },\n addTransaction(state, action: PayloadAction) {\n state.transactions.push(action.payload);\n },\n resetTransactions(state) {\n state.transactions = [];\n },\n setNewTransaction(state, action: PayloadAction) {\n state.addTransaction = action.payload;\n },\n resetNewTransaction(state) {\n state.addTransaction = {};\n },\n },\n});\n\nexport const {\n openTransactionBuilder,\n closeTransactionBuilder,\n setNewTransaction,\n resetNewTransaction,\n resetTransactions,\n addTransaction,\n setTransactions,\n} = transactionBuilderSlice.actions;\n","import { Middleware } from \"@reduxjs/toolkit\";\nimport {\n fetchModulesList,\n fetchPendingModules,\n setCurrentModule,\n setCurrentPendingModule,\n setModuleAdded,\n} from \"./index\";\nimport {\n getCurrentPendingModule,\n getModuleAdded,\n getModulesList,\n getPendingCreateModuleTransactions,\n} from \"./selectors\";\nimport { flatAllModules } from \"./helpers\";\n\nexport const modulesMiddleware: Middleware = (store) => (next) => (action) => {\n if (action.type === fetchModulesList.fulfilled.type) {\n const oldState = store.getState();\n const currentPending = getCurrentPendingModule(oldState);\n const result = next(action);\n if (currentPending) {\n const modulesList = getModulesList(store.getState());\n const allModules = flatAllModules(modulesList);\n const currentModule = allModules.find(\n (module) => module.address === currentPending.address\n );\n if (currentModule) {\n store.dispatch(setCurrentModule(currentModule));\n }\n }\n return result;\n }\n\n if (action.type === fetchPendingModules.fulfilled.type) {\n const oldState = store.getState();\n const result = next(action);\n if (getModuleAdded(oldState)) {\n const oldPendingModules = getPendingCreateModuleTransactions(oldState);\n const newPendingModules = getPendingCreateModuleTransactions(\n store.getState()\n );\n if (\n (!oldPendingModules.length && newPendingModules.length) ||\n (oldPendingModules.length &&\n newPendingModules.length &&\n newPendingModules[0].address !== oldPendingModules[0].address)\n ) {\n store.dispatch(setCurrentPendingModule(newPendingModules[0]));\n store.dispatch(setModuleAdded(false));\n }\n }\n return result;\n }\n\n return next(action);\n};\n","import { Middleware } from \"@reduxjs/toolkit\";\nimport { setCurrentModule } from \"../modules\";\nimport { closeTransactionBuilder } from \"./index\";\n\nexport const transactionBuilderMiddleware: Middleware =\n (store) => (next) => (action) => {\n if (action.type === setCurrentModule.type) {\n store.dispatch(closeTransactionBuilder());\n }\n return next(action);\n };\n","import { configureStore } from \"@reduxjs/toolkit\";\nimport { modulesSlice } from \"./modules\";\nimport { TypedUseSelectorHook, useDispatch, useSelector } from \"react-redux\";\nimport { transactionBuilderSlice } from \"./transactionBuilder\";\nimport { modulesMiddleware } from \"./modules/middleware\";\nimport { transactionBuilderMiddleware } from \"./transactionBuilder/middleware\";\n\nexport const REDUX_STORE = configureStore({\n reducer: {\n modules: modulesSlice.reducer,\n transactionBuilder: transactionBuilderSlice.reducer,\n },\n middleware: (getDefaultMiddleware) =>\n getDefaultMiddleware().concat(\n modulesMiddleware,\n transactionBuilderMiddleware\n ),\n});\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof REDUX_STORE.dispatch;\n\nexport const useRootDispatch = () => useDispatch();\nexport const useRootSelector: TypedUseSelectorHook = useSelector;\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\ntype ColumnProps = HTMLProps;\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n}));\n\nexport const Column = ({ className, ...props }: ColumnProps) => {\n const classes = useStyles();\n return
;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport classNames from \"classnames\";\nimport { Column } from \"../../../components/layout/Column\";\n\nexport interface PanelItemProps {\n active?: boolean;\n sub?: boolean;\n image?: React.ReactElement | null;\n\n onClick?(): void;\n}\n\nexport const PANEL_ITEM_CONTENT_HEIGHT = 56;\nexport const PANEL_ITEM_PADDING = 8;\nexport const PANEL_ITEM_HEIGHT =\n PANEL_ITEM_CONTENT_HEIGHT + PANEL_ITEM_PADDING * 2 + 2;\nexport const PANEL_ITEM_MARGIN = 12;\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: PANEL_ITEM_PADDING,\n transition: \"0.2s ease all\",\n cursor: \"pointer\",\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n active: {\n borderColor: theme.palette.common.white,\n background: \"none\",\n cursor: \"initial\",\n \"&::before\": {\n borderColor: theme.palette.common.white,\n },\n \"&:hover\": {\n background: \"none\",\n },\n },\n spacing: {\n \"& + &, &.sub\": {\n marginTop: PANEL_ITEM_MARGIN,\n },\n },\n moduleItem: {\n display: \"grid\",\n gridTemplateColumns: \"48px 1fr\",\n gridGap: theme.spacing(2),\n\n backgroundColor: \"transparent\",\n\n \"&.sub\": {\n zIndex: 2,\n },\n },\n content: {\n width: \"100%\",\n justifyContent: \"center\",\n },\n image: {\n paddingTop: 2,\n },\n}));\n\nexport const PanelItem: React.FC = ({\n active,\n sub,\n image = null,\n children,\n onClick,\n}) => {\n const classes = useStyles();\n return (\n \n \n
{image}
\n {children}\n
\n \n );\n};\n","import { EthHashInfo } from \"@gnosis.pm/safe-react-components\";\nimport React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => {\n return {\n hashInfo: {\n display: \"inline-flex !important\",\n width: 50,\n height: 50,\n padding: theme.spacing(0.5),\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"50%\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n background: \"rgba(224, 197, 173, 0.1)\",\n\n \"& p\": {\n fontSize: 12,\n color: theme.palette.text.primary + \" !important\",\n },\n \"& .jLVlPg\": {\n margin: 0,\n },\n \"& .jLVlPg > p\": {\n fontWeight: \"bold\",\n fontSize: 14,\n },\n },\n };\n});\n\nexport const HashInfo = (props: Parameters[0]) => {\n const classes = useStyles();\n return ;\n};\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\ntype RowProps = HTMLProps;\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n}));\n\nexport const Row = ({ className, ...props }: RowProps) => {\n const classes = useStyles();\n return
;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { alpha } from \"@material-ui/core/styles\";\nimport classNames from \"classnames\";\nimport { Row } from \"../layout/Row\";\n\nconst useStyles = makeStyles((theme) => ({\n badge: {\n display: \"inline-block\",\n padding: theme.spacing(0.25, 0.5),\n lineHeight: 1,\n whiteSpace: \"nowrap\",\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n },\n primary: {\n backgroundColor: \"rgba(224, 197, 173, 0.1)\",\n },\n secondary: {\n backgroundColor: alpha(theme.palette.primary.light, 0.4),\n },\n}));\n\ninterface BadgeProps extends React.HTMLProps {\n secondary?: string;\n}\n\nexport const Badge: React.FC = ({\n secondary,\n children,\n className,\n ...props\n}) => {\n const classes = useStyles();\n\n if (secondary) {\n return (\n \n \n {children}\n
\n \n {secondary}\n
\n \n );\n }\n\n return (\n \n {children}\n \n );\n};\n","import React from \"react\";\nimport { ExplorerButton } from \"@gnosis.pm/safe-react-components\";\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\";\nimport { getExplorerInfo } from \"../../utils/explorers\";\n\ninterface AddressExplorerButtonProps {\n className?: string;\n address: string;\n}\n\nexport const AddressExplorerButton = ({\n address,\n className,\n}: AddressExplorerButtonProps) => {\n const { safe } = useSafeAppsSDK();\n const safeExplorer = getExplorerInfo(safe.chainId, address);\n if (!safeExplorer) return null;\n return ;\n};\n","export function shortAddress(address: string) {\n return address.substr(0, 6) + \"...\" + address.substr(-4);\n}\n\nexport function formatDuration(duration: number) {\n if (duration < 60) {\n if (duration === 1) return `1 second`;\n return `${duration} second`;\n }\n\n if (duration < 3600) {\n const minutes = Math.floor(duration / 60);\n if (minutes === 1) return `1 minute`;\n return `${minutes} minute`;\n }\n\n // Display until 47 hours\n if (duration < 172800) {\n const hours = Math.floor(duration / 3600);\n if (hours === 1) return `1 hour`;\n return `${hours} hour`;\n }\n\n const days = Math.floor(duration / 86400);\n return `${days} day`;\n}\n","import React from \"react\";\nimport { makeStyles, Typography, TypographyProps } from \"@material-ui/core\";\nimport { CopyToClipboardBtn } from \"@gnosis.pm/safe-react-components\";\nimport { AddressExplorerButton } from \"./AddressExplorerButton\";\nimport { shortAddress } from \"../../utils/string\";\nimport classNames from \"classnames\";\n\ninterface AddressProps {\n address: string;\n short?: boolean;\n hideCopyBtn?: boolean;\n hideExplorerBtn?: boolean;\n showOnHover?: boolean;\n gutterBottom?: boolean;\n classes?: {\n icon?: string;\n container?: string;\n };\n TypographyProps?: TypographyProps;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.5),\n justifyContent: \"start\",\n alignItems: \"center\",\n minWidth: 0,\n \"& > *\": {\n gridRow: 1,\n },\n },\n gutterBottom: {\n marginBottom: theme.spacing(1),\n },\n showOnHover: {\n \"& .btn\": {\n visibility: \"hidden\",\n },\n \"&:hover .btn\": {\n visibility: \"initial\",\n },\n },\n}));\n\nexport const Address = ({\n address,\n short = false,\n hideCopyBtn = false,\n hideExplorerBtn = false,\n showOnHover = false,\n gutterBottom = false,\n classes: { icon, container } = {},\n TypographyProps,\n}: AddressProps) => {\n const classes = useStyles();\n\n return (\n \n \n {short ? shortAddress(address) : address}\n \n {hideCopyBtn ? null : (\n \n )}\n {hideExplorerBtn ? null : (\n \n )}\n \n );\n};\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgLoadingCircle = function SvgLoadingCircle(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 34,\n height: 34,\n viewBox: \"0 0 34 34\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M2 17C2 16.4477 1.55228 16 1 16C0.447715 16 0 16.4477 0 17H2ZM10.6248 1.2361C10.1129 1.44332 9.86584 2.02632 10.0731 2.53825C10.2803 3.05018 10.8633 3.2972 11.3752 3.08997L10.6248 1.2361ZM32 17C32 25.2843 25.2843 32 17 32V34C26.3888 34 34 26.3888 34 17H32ZM17 32C8.71573 32 2 25.2843 2 17H0C0 26.3888 7.61116 34 17 34V32ZM17 2C25.2843 2 32 8.71573 32 17H34C34 7.61116 26.3888 0 17 0V2ZM11.3752 3.08997C13.1109 2.38739 15.009 2 17 2V0C14.7474 0 12.5948 0.438641 10.6248 1.2361L11.3752 3.08997Z\",\n fill: \"#FFFFFF\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgLoadingCircle, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/loading-circle.c90af9bb.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { Link, makeStyles, Typography } from \"@material-ui/core\";\nimport { PanelItemProps } from \"./PanelItem\";\nimport { DelayModule } from \"../../../store/modules/models\";\nimport { Badge } from \"../../../components/text/Badge\";\nimport { Address } from \"../../../components/ethereum/Address\";\nimport { formatDuration } from \"../../../utils/string\";\nimport { useRootDispatch } from \"../../../store\";\nimport { setNewTransaction } from \"../../../store/transactionBuilder\";\nimport { setCurrentModule, setOperation } from \"../../../store/modules\";\nimport { Row } from \"../../../components/layout/Row\";\n\ninterface DelayModuleItemProps extends PanelItemProps {\n module: DelayModule;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n },\n}));\n\nexport const DelayModuleItem = ({ module }: DelayModuleItemProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n\n const handleClick = (evt: React.MouseEvent) => {\n evt.stopPropagation(); // Avoid triggering ModuleItem click event.\n\n dispatch(setCurrentModule(module));\n dispatch(setOperation(\"write\"));\n dispatch(\n setNewTransaction({\n func: \"setTxCooldown(uint256)\",\n params: [module.cooldown],\n })\n );\n };\n\n return (\n
\n \n {module.name}\n \n \n \n {formatDuration(module.cooldown)} delay\n \n Change Delay\n \n \n
\n );\n};\n","import { withStyles, Link as MUILink } from \"@material-ui/core\";\n\nexport const Link = withStyles((theme) => ({\n root: {\n color: theme.palette.text.primary,\n textDecoration: \"underline\",\n transition: \"opacity 0.25s ease-in-out\",\n \"&:hover\": {\n opacity: 0.6,\n }\n },\n}))(MUILink);\n","import React from \"react\";\nimport { PanelItem, PanelItemProps } from \"./PanelItem\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Link } from \"../../../components/text/Link\";\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\";\nimport { getNetworkExplorerInfo } from \"../../../utils/explorers\";\n\ninterface ModulePendingItemProps extends PanelItemProps {\n title: string;\n linkText: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n title: {\n marginBottom: theme.spacing(0.5),\n textTransform: \"uppercase\",\n },\n image: {\n width: 50,\n height: 50,\n display: \"inline-flex !important\",\n padding: theme.spacing(0.5),\n alignItems: \"center\",\n justifyContent: \"center\",\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"50%\",\n borderColor: \"rgba(255, 255, 255, 0.2)\",\n background: \"rgba(224, 197, 173, 0.1)\",\n },\n}));\n\nexport const ModulePendingItem = ({\n image = null,\n linkText,\n title,\n ...props\n}: ModulePendingItemProps) => {\n const classes = useStyles();\n const { safe } = useSafeAppsSDK();\n\n const network = getNetworkExplorerInfo(safe.chainId);\n const link = network\n ? `${network.safeUrl}${safe.safeAddress}/transactions`\n : \"\";\n\n return (\n {image}} {...props}>\n \n {title}\n \n
\n \n {linkText}\n \n
\n
\n );\n};\n","var _path, _path2, _path3;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgDeleteIcon = function SvgDeleteIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 16,\n height: 16,\n viewBox: \"0 0 16 16\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M6.66667 12.0064C7.03533 12.0064 7.33333 11.7084 7.33333 11.3398V7.33976C7.33333 6.9711 7.03533 6.6731 6.66667 6.6731C6.298 6.6731 6 6.9711 6 7.33976V11.3398C6 11.7084 6.298 12.0064 6.66667 12.0064Z\",\n fill: \"#B2B5B2\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M9.33415 12.0064C9.70281 12.0064 10.0008 11.7084 10.0008 11.3398V7.33976C10.0008 6.9711 9.70281 6.6731 9.33415 6.6731C8.96548 6.6731 8.66748 6.9711 8.66748 7.33976V11.3398C8.66748 11.7084 8.96548 12.0064 9.33415 12.0064Z\",\n fill: \"#B2B5B2\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M11.0085 13.034C10.9998 13.2033 10.8365 13.336 10.6771 13.3346H5.31245C5.15912 13.3173 5.00512 13.204 4.99645 13.0293L4.56445 5.33329H11.4225L11.0085 13.034ZM6.66439 3.07729C6.66439 2.85463 6.85306 2.66663 7.07572 2.66663H8.92105C9.14772 2.66663 9.33239 2.85129 9.33239 3.07729V3.99996H6.66439V3.07729ZM13.3328 3.99992H12.1742C12.1702 3.99992 12.1662 3.99659 12.1615 3.99659C12.1535 3.99592 12.1468 3.99992 12.1382 3.99992H10.6655V3.07725C10.6655 2.11592 9.88351 1.33325 8.92085 1.33325H7.07551C6.11351 1.33325 5.33085 2.11592 5.33085 3.07725V3.99992H2.66618C2.29818 3.99992 1.99951 4.29792 1.99951 4.66659C1.99951 5.03525 2.29818 5.33325 2.66618 5.33325H3.22951L3.66484 13.0979C3.70685 13.9713 4.43885 14.6686 5.29151 14.6686C5.30351 14.6686 5.31551 14.6679 5.32751 14.6679H10.6608H10.6988C11.5655 14.6679 12.2982 13.9719 12.3402 13.1026L12.7575 5.33325H13.3328C13.7015 5.33325 13.9995 5.03525 13.9995 4.66659C13.9995 4.29792 13.7015 3.99992 13.3328 3.99992Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgDeleteIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/delete-icon.f2b9a941.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ReactComponent as LoadingCircleImg } from \"../../assets/images/loading-circle.svg\";\n\ninterface LoadingIconProps {\n icon?: React.ReactNode;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n width: 34,\n height: 34,\n },\n floating: {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n icon: {},\n rotate: {\n animationName: \"$rotate\",\n animationDuration: \"2000ms\",\n animationTimingFunction: \"linear\",\n animationIterationCount: \"infinite\",\n },\n \"@keyframes rotate\": {\n \"0%\": {\n transform: \"rotate(0deg)\",\n },\n \"100%\": {\n transform: \"rotate(360deg)\",\n },\n },\n}));\n\nexport const LoadingIcon = ({ icon }: LoadingIconProps) => {\n const classes = useStyles();\n return (\n
\n
\n \n
\n
{icon}
\n
\n );\n};\n","var _circle, _circle2, _circle3, _path, _path2, _path3, _path4, _path5, _path6;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgRemovePendingState = function SvgRemovePendingState(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 37,\n height: 36,\n viewBox: \"0 0 37 36\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 29,\n cy: 4.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 4,\n cy: 17.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 27,\n cy: 31.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path4 || (_path4 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M18.6667 22.0064C19.0353 22.0064 19.3333 21.7084 19.3333 21.3398V17.3398C19.3333 16.9711 19.0353 16.6731 18.6667 16.6731C18.298 16.6731 18 16.9711 18 17.3398V21.3398C18 21.7084 18.298 22.0064 18.6667 22.0064Z\",\n fill: \"#B2B5B2\"\n })), _path5 || (_path5 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M21.3341 22.0064C21.7028 22.0064 22.0008 21.7084 22.0008 21.3398V17.3398C22.0008 16.9711 21.7028 16.6731 21.3341 16.6731C20.9655 16.6731 20.6675 16.9711 20.6675 17.3398V21.3398C20.6675 21.7084 20.9655 22.0064 21.3341 22.0064Z\",\n fill: \"#B2B5B2\"\n })), _path6 || (_path6 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M23.0085 23.0338C22.9998 23.2032 22.8365 23.3358 22.6771 23.3345H17.3125C17.1591 23.3172 17.0051 23.2038 16.9965 23.0292L16.5645 15.3332H23.4225L23.0085 23.0338ZM18.6644 13.0772C18.6644 12.8545 18.8531 12.6665 19.0757 12.6665H20.9211C21.1477 12.6665 21.3324 12.8512 21.3324 13.0772V13.9998H18.6644V13.0772ZM25.3328 13.9998H24.1742C24.1702 13.9998 24.1662 13.9965 24.1615 13.9965C24.1535 13.9958 24.1468 13.9998 24.1382 13.9998H22.6655V13.0771C22.6655 12.1158 21.8835 11.3331 20.9208 11.3331H19.0755C18.1135 11.3331 17.3308 12.1158 17.3308 13.0771V13.9998H14.6662C14.2982 13.9998 13.9995 14.2978 13.9995 14.6665C13.9995 15.0351 14.2982 15.3331 14.6662 15.3331H15.2295L15.6648 23.0978C15.7068 23.9711 16.4388 24.6685 17.2915 24.6685C17.3035 24.6685 17.3155 24.6678 17.3275 24.6678H22.6608H22.6988C23.5655 24.6678 24.2982 23.9718 24.3402 23.1025L24.7575 15.3331H25.3328C25.7015 15.3331 25.9995 15.0351 25.9995 14.6665C25.9995 14.2978 25.7015 13.9998 25.3328 13.9998Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgRemovePendingState, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/remove-pending-state.f6da023c.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { PanelItemProps } from \"./PanelItem\";\nimport { Module } from \"../../../store/modules/models\";\nimport { ModulePendingItem } from \"./ModulePendingItem\";\nimport { LoadingIcon } from \"../../../components/icons/LoadingIcon\";\nimport { ReactComponent as TrashIcon } from \"../../../assets/icons/delete-icon.svg\";\nimport { ReactComponent as RemovePendingStateImg } from \"../../../assets/images/remove-pending-state.svg\";\n\ninterface ModulePendingRemovalProps extends PanelItemProps {\n module: Module;\n instant?: boolean;\n}\n\nexport const ModulePendingRemoval = ({\n instant,\n module,\n ...props\n}: ModulePendingRemovalProps) => {\n if (instant) {\n return (\n } />}\n {...props}\n />\n );\n }\n\n return (\n }\n {...props}\n />\n );\n};\n","import { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport { NETWORK, NETWORKS } from \"./networks\"\n\nexport function safeAppUrl(safeInfo: SafeInfo, appUrl: string) {\n const base = \"https://gnosis-safe.io\"\n const prefix = chainPrefix(safeInfo)\n const pathname = `/app/${prefix}:${safeInfo.safeAddress}/apps`\n const params = new URLSearchParams({ appUrl })\n\n return new URL(`${base}${pathname}?${params}`).href\n}\n\nexport function rolesV1AppUrl(safeInfo: SafeInfo, rolesAddress: string) {\n const base = \"https://roles-v1.gnosisguild.org\"\n const prefix = chainPrefix(safeInfo)\n\n return new URL(`${base}/#/${prefix}:${rolesAddress}`).href\n}\n\nexport function rolesV2AppUrl(safeInfo: SafeInfo, rolesAddress: string) {\n const base = \"https://roles.gnosisguild.org\"\n const prefix = chainPrefix(safeInfo)\n\n return new URL(`${base}/${prefix}:${rolesAddress}`).href\n}\n\nfunction chainPrefix(safeInfo: SafeInfo): string {\n return NETWORKS[safeInfo.chainId as NETWORK].shortName\n}\n","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Address } from \"components/ethereum/Address\"\nimport { Row } from \"components/layout/Row\"\n\nimport React from \"react\"\nimport { Module } from \"store/modules/models\"\nimport { PanelItemProps } from \"./PanelItem\"\nimport { rolesV1AppUrl } from \"utils/url\"\n\ninterface RoleModuleItemProps extends PanelItemProps {\n module: Module\n chainId: number\n}\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n textUnderlineOffset: \"2px\",\n \"&:hover\": {\n opacity: 0.5,\n },\n },\n}))\n\nexport const RolesV1ModuleItem: React.FC = ({ module }) => {\n const classes = useStyles()\n const { safe: safeInfo } = useSafeAppsSDK()\n\n return (\n
\n \n {module.name}\n \n\n \n \n {\n window.location.href = rolesV1AppUrl(safeInfo, module.address)\n }}\n underline=\"always\"\n >\n Edit Roles\n \n \n
\n )\n}\n","var _path, _path2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAddCircleIcon = function SvgAddCircleIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 16,\n height: 17,\n viewBox: \"0 0 16 17\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M14.6668 8.49992C14.6668 12.1818 11.6821 15.1666 8.00016 15.1666C4.31826 15.1666 1.3335 12.1818 1.3335 8.49992C1.3335 4.81802 4.31826 1.83325 8.00016 1.83325C11.6821 1.83325 14.6668 4.81802 14.6668 8.49992ZM2.66667 8.49988C2.66667 11.4454 5.05448 13.8332 8 13.8332C10.9455 13.8332 13.3333 11.4454 13.3333 8.49988C13.3333 5.55436 10.9455 3.16654 8 3.16654C5.05448 3.16654 2.66667 5.55436 2.66667 8.49988Z\",\n fill: \"#B2B5B2\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M8.6665 7.83341H10.6665C11.0347 7.83341 11.3332 8.13189 11.3332 8.50008C11.3332 8.86827 11.0347 9.16675 10.6665 9.16675H8.6665V11.1667C8.6665 11.5349 8.36803 11.8334 7.99984 11.8334C7.63165 11.8334 7.33317 11.5349 7.33317 11.1667V9.16675H5.33317C4.96498 9.16675 4.6665 8.86827 4.6665 8.50008C4.6665 8.13189 4.96498 7.83341 5.33317 7.83341H7.33317V5.83341C7.33317 5.46522 7.63165 5.16675 7.99984 5.16675C8.36803 5.16675 8.6665 5.46522 8.6665 5.83341V7.83341Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAddCircleIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/add-circle-icon.42a49a22.svg\";\nexport { ForwardRef as ReactComponent };","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Address } from \"components/ethereum/Address\"\nimport { Row } from \"components/layout/Row\"\n\nimport React from \"react\"\nimport { Module } from \"store/modules/models\"\nimport { PanelItemProps } from \"./PanelItem\"\nimport { rolesV2AppUrl } from \"utils/url\"\n\ninterface RoleModuleItemProps extends PanelItemProps {\n module: Module\n chainId: number\n}\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"grid\",\n gridGap: theme.spacing(0.25),\n \"& > *\": {\n gridColumn: 1,\n },\n },\n text: {\n lineHeight: 1,\n letterSpacing: 1,\n },\n moduleName: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n link: {\n marginLeft: theme.spacing(1),\n lineHeight: 1,\n cursor: \"pointer\",\n textUnderlineOffset: \"2px\",\n \"&:hover\": {\n opacity: 0.5,\n },\n },\n}))\n\nexport const RolesV2ModuleItem: React.FC = ({ module }) => {\n const classes = useStyles()\n const { safe: safeInfo } = useSafeAppsSDK()\n\n return (\n
\n \n {module.name}\n \n\n \n \n {\n window.location.href = rolesV2AppUrl(safeInfo, module.address)\n }}\n underline=\"always\"\n >\n View Roles\n \n \n
\n )\n}\n","import { HashInfo } from \"../../../components/ethereum/HashInfo\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { PANEL_ITEM_CONTENT_HEIGHT, PanelItem, PanelItemProps } from \"./PanelItem\"\nimport React from \"react\"\nimport { Module, ModuleType } from \"../../../store/modules/models\"\nimport { DelayModuleItem } from \"./DelayModuleItem\"\nimport { isDelayModule } from \"../../../store/modules/helpers\"\nimport { ModuleList } from \"../ModuleList\"\nimport { Address } from \"../../../components/ethereum/Address\"\nimport { ModulePendingRemoval } from \"./ModulePendingRemovalItem\"\nimport { Badge } from \"../../../components/text/Badge\"\nimport { shortAddress } from \"../../../utils/string\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { RolesV1ModuleItem } from \"./RolesV1ModuleItem\"\nimport { RolesV2ModuleItem } from \"./RolesV2ModuleItem\"\n\ninterface ModuleItemProps extends PanelItemProps {\n remove?: boolean\n instant?: boolean\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n text: {\n lineHeight: 1,\n letterSpacing: \"1px\",\n },\n name: {\n textTransform: \"uppercase\",\n },\n address: {\n fontFamily: \"Roboto Mono\",\n },\n badge: {\n marginTop: theme.spacing(1),\n },\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n height: PANEL_ITEM_CONTENT_HEIGHT,\n },\n}))\n\ninterface ModuleItemContentProps extends ModuleItemProps {\n classes: Record\n}\n\nexport const ModuleItemContent = (props: ModuleItemContentProps) => {\n const { module, classes, ...panelItemProps } = props\n const { safe } = useSafeAppsSDK()\n if (isDelayModule(module)) {\n return \n }\n\n if (module.type === ModuleType.ROLES_V1) {\n return (\n \n )\n }\n if (module.type === ModuleType.ROLES_V2) {\n return (\n \n )\n }\n\n const ownerBadge =\n module.owner && module.owner !== safe.safeAddress ? (\n \n External Owner\n \n ) : null\n\n return (\n <>\n {module.name ? (\n \n {module.name}\n \n ) : null}\n \n {ownerBadge}\n \n )\n}\n\nexport const ModuleItem = (props: ModuleItemProps) => {\n const { module, remove = false, instant = false, onClick, ...panelItemProps } = props\n\n const classes = useStyles()\n\n if (remove) {\n return (\n \n )\n }\n\n return (\n \n }\n {...panelItemProps}\n >\n
\n \n
\n\n {module.subModules.length ? : null}\n \n )\n}\n","var _circle, _circle2, _circle3, _path, _path2, _path3, _path4, _path5;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgDaoModulePending = function SvgDaoModulePending(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 37,\n height: 36,\n viewBox: \"0 0 37 36\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 29,\n cy: 4.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 4,\n cy: 17.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 27,\n cy: 31.5,\n r: 3,\n stroke: \"#B2B5B2\",\n strokeWidth: 2\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M33.558 9C35.1052 11.4627 36 14.3769 36 17.5C36 21.5578 34.4895 25.2628 32 28.0833\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 11.5C7.53664 5.63634 13.2853 1.5 20.0001 1.5C21.2023 1.5 22.3736 1.6326 23.5001 1.88397\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.16309 23.5001C7.53667 29.3637 13.2853 33.5 20 33.5C20.3784 33.5 20.7537 33.4868 21.1255 33.461\",\n stroke: \"#B2B5B2\",\n strokeOpacity: 0.3,\n strokeWidth: 2,\n strokeLinecap: \"round\"\n })), _path4 || (_path4 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M26.6668 17.5C26.6668 21.1819 23.6821 24.1667 20.0002 24.1667C16.3183 24.1667 13.3335 21.1819 13.3335 17.5C13.3335 13.8181 16.3183 10.8334 20.0002 10.8334C23.6821 10.8334 26.6668 13.8181 26.6668 17.5ZM14.6667 17.5C14.6667 20.4455 17.0545 22.8333 20 22.8333C22.9455 22.8333 25.3333 20.4455 25.3333 17.5C25.3333 14.5545 22.9455 12.1667 20 12.1667C17.0545 12.1667 14.6667 14.5545 14.6667 17.5Z\",\n fill: \"#B2B5B2\"\n })), _path5 || (_path5 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M20.6665 16.8333H22.6665C23.0347 16.8333 23.3332 17.1318 23.3332 17.5C23.3332 17.8681 23.0347 18.1666 22.6665 18.1666H20.6665V20.1666C20.6665 20.5348 20.368 20.8333 19.9998 20.8333C19.6316 20.8333 19.3332 20.5348 19.3332 20.1666V18.1666H17.3332C16.965 18.1666 16.6665 17.8681 16.6665 17.5C16.6665 17.1318 16.965 16.8333 17.3332 16.8333H19.3332V14.8333C19.3332 14.4651 19.6316 14.1666 19.9998 14.1666C20.368 14.1666 20.6665 14.4651 20.6665 14.8333V16.8333Z\",\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgDaoModulePending, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/dao-module-pending.3803c565.svg\";\nexport { ForwardRef as ReactComponent };","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgModuleInherit = function SvgModuleInherit(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 30,\n height: 7,\n viewBox: \"0 0 30 7\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1.28906 1.69727C5.32916 3.95696 10.0897 5.26087 15.1864 5.26087C20.283 5.26087 25.0436 3.95696 29.0837 1.69727\",\n strokeWidth: 2\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgModuleInherit, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/module-inherit.3008886e.svg\";\nexport { ForwardRef as ReactComponent };","import { useMemo } from \"react\"\nimport { SafeAppProvider } from \"@gnosis.pm/safe-apps-provider\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { ethers } from \"ethers\"\n\nconst useSafeAppsSDKWithProvider = () => {\n const { sdk, safe } = useSafeAppsSDK()\n const provider = useMemo(\n () => new ethers.providers.Web3Provider(new SafeAppProvider(safe, sdk)),\n [sdk, safe],\n )\n return { sdk, safe, provider }\n}\n\nexport default useSafeAppsSDKWithProvider\n","import React, { useEffect } from \"react\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getCurrentPendingModule,\n getPendingCreateModuleTransactions,\n getPendingModules,\n getSafeThreshold,\n} from \"../../store/modules/selectors\"\nimport {\n fetchModulesList,\n fetchPendingModules,\n setCurrentPendingModule,\n} from \"../../store/modules\"\nimport { ModulePendingItem } from \"./item/ModulePendingItem\"\nimport { LoadingIcon } from \"../../components/icons/LoadingIcon\"\nimport { ReactComponent as AddIcon } from \"../../assets/icons/add-circle-icon.svg\"\nimport { ReactComponent as ModulePendingImg } from \"../../assets/images/dao-module-pending.svg\"\nimport { getModuleContractMetadata } from \"../../utils/modulesValidation\"\nimport { getModuleName } from \"../../store/modules/helpers\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nexport const PendingModuleStates = () => {\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const dispatch = useRootDispatch()\n const currentPending = useRootSelector(getCurrentPendingModule)\n const pendingModuleTransactions = useRootSelector(getPendingModules)\n const pendingCreateModuleTransactions = useRootSelector(\n getPendingCreateModuleTransactions,\n )\n const safeThreshold = useRootSelector(getSafeThreshold)\n const isInstantExecution = safeThreshold === 1\n\n useEffect(() => {\n dispatch(fetchPendingModules(safe))\n }, [dispatch, safe])\n\n useEffect(() => {\n if (isInstantExecution && pendingModuleTransactions.length) {\n const interval = setInterval(() => dispatch(fetchPendingModules(safe)), 3000)\n return () => {\n clearInterval(interval)\n dispatch(\n fetchModulesList({\n provider,\n safeSDK: sdk,\n chainId: safe.chainId,\n safeAddress: safe.safeAddress,\n }),\n )\n }\n }\n }, [\n dispatch,\n isInstantExecution,\n sdk,\n safe,\n pendingModuleTransactions.length,\n provider,\n ])\n\n const image = isInstantExecution ? (\n } />\n ) : (\n \n )\n const linkText = isInstantExecution ? \"Transaction confirming...\" : \"Awaiting approval\"\n\n return (\n <>\n {pendingCreateModuleTransactions.map((pendingModule, index) => {\n const props = {\n key: index,\n instant: isInstantExecution,\n onClick: () => dispatch(setCurrentPendingModule(pendingModule)),\n active: currentPending?.address === pendingModule.address,\n }\n const metadata = getModuleContractMetadata(pendingModule.module)\n const name = getModuleName(metadata?.type)\n return (\n \n )\n })}\n \n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgAddIcon = function SvgAddIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 13,\n height: 12,\n viewBox: \"0 0 13 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M7.22344 4.8H10.8234C11.4862 4.8 12.0234 5.33726 12.0234 6C12.0234 6.66274 11.4862 7.2 10.8234 7.2H7.22344V10.8C7.22344 11.4627 6.68618 12 6.02344 12C5.3607 12 4.82344 11.4627 4.82344 10.8V7.2H1.22344C0.560696 7.2 0.0234375 6.66274 0.0234375 6C0.0234375 5.33726 0.560696 4.8 1.22344 4.8H4.82344V1.2C4.82344 0.537258 5.3607 0 6.02344 0C6.68618 0 7.22344 0.537258 7.22344 1.2V4.8Z\",\n fill: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgAddIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/add-icon.7ae47d81.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles, Typography } from \"@material-ui/core\"\nimport React, { useEffect } from \"react\"\nimport { Module } from \"../../store/modules/models\"\nimport { fetchModulesList, setCurrentModule } from \"../../store/modules\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getCurrentModule,\n getIsLoadingModules,\n getPendingModules,\n getPendingRemoveModuleTransactions,\n getSafeThreshold,\n} from \"../../store/modules/selectors\"\nimport { ReactComponent as AvatarEmptyIcon } from \"../../assets/icons/avatar-empty.svg\"\nimport { Skeleton } from \"@material-ui/lab\"\nimport { PANEL_ITEM_HEIGHT, PANEL_ITEM_MARGIN, PanelItem } from \"./item/PanelItem\"\nimport { ModuleItem } from \"./item/ModuleItem\"\nimport { resetNewTransaction } from \"../../store/transactionBuilder\"\nimport { PendingModuleStates } from \"./PendingModuleStates\"\nimport { Column } from \"../../components/layout/Column\"\nimport { isPendingModule } from \"../../store/modules/helpers\"\nimport { ReactComponent as ModuleStackIcon } from \"../../assets/icons/module-inherit.svg\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleListProps {\n modules: Module[]\n sub?: boolean\n}\n\nconst useStyles = makeStyles((theme) => ({\n subModules: {\n position: \"relative\",\n },\n line: {\n position: \"absolute\",\n borderColor: \"#6d6b5a\",\n borderStyle: \"solid\",\n borderBottomWidth: 2,\n borderLeftWidth: 2,\n borderTopWidth: 0,\n borderRightWidth: 0,\n borderBottomLeftRadius: 16,\n top: PANEL_ITEM_MARGIN - 6,\n left: -40,\n width: 32,\n },\n moduleStackIcon: {\n position: \"absolute\",\n top: 0,\n left: -54,\n zIndex: 100,\n stroke: \"#6d6b5a\",\n },\n emptyModulesText: {\n maxWidth: 200,\n },\n emptyImage: {\n border: \"1px solid rgba(255,255,255,0.2)\",\n borderRadius: \"50%\",\n padding: theme.spacing(0.5),\n },\n}))\n\nexport const ModuleList = ({ modules, sub = false }: ModuleListProps) => {\n const classes = useStyles()\n const { safe, sdk, provider } = useSafeAppsSDKWithProvider()\n\n const dispatch = useRootDispatch()\n const currentModule = useRootSelector(getCurrentModule)\n const modulesLoading = useRootSelector(getIsLoadingModules)\n const pendingModules = useRootSelector(getPendingModules)\n const safeThreshold = useRootSelector(getSafeThreshold)\n const pendingRemoveTxs = useRootSelector(getPendingRemoveModuleTransactions)\n\n const handleClick = (module: Module) => {\n dispatch(setCurrentModule(module))\n dispatch(resetNewTransaction())\n }\n\n const [intervalId, setIntervalId] = React.useState(null)\n\n useEffect(() => {\n if (intervalId == null) {\n const exec = () => {\n dispatch(\n fetchModulesList({\n provider,\n safeSDK: sdk,\n chainId: safe.chainId,\n safeAddress: safe.safeAddress,\n }),\n )\n }\n\n const intervalId = setInterval(exec, 10000)\n\n setIntervalId(intervalId)\n exec()\n }\n return () => {\n if (intervalId != null) {\n clearInterval(intervalId)\n }\n }\n }, [sdk, dispatch, safe, intervalId, provider])\n\n if (modulesLoading) {\n return (\n }>\n \n \n \n )\n }\n\n if (!modules.length && !pendingModules.length) {\n return (\n }\n >\n \n Modules will appear here once added\n \n \n )\n }\n\n const content = modules.map((module) => {\n const active = module.id === currentModule?.id\n const remove = pendingRemoveTxs.some((tx) => isPendingModule(module, tx))\n return (\n handleClick(module)}\n />\n )\n })\n\n if (sub) {\n const lines = modules.map((_, index) => {\n const previous = index && modules[index - 1]\n const subModulesCount = previous && previous.subModules.length\n const subModulesHeight = subModulesCount * PANEL_ITEM_HEIGHT\n\n const height =\n 1 +\n subModulesHeight +\n PANEL_ITEM_HEIGHT * (index + 1) +\n PANEL_ITEM_MARGIN * index -\n PANEL_ITEM_HEIGHT / 2 +\n 6\n return
\n })\n const arrow = modules.length ? (\n \n ) : null\n return (\n
\n {content}\n {arrow}\n {lines}\n
\n )\n }\n\n return (\n \n \n {content}\n \n )\n}\n","import React from \"react\";\n\nexport const Grow = () => {\n return
;\n};\n","import React from \"react\"\nimport { Button, makeStyles, Typography } from \"@material-ui/core\"\nimport { ModuleList } from \"./ModuleList\"\nimport { Row } from \"../../components/layout/Row\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getCurrentModule, getCurrentPendingModule, getModulesList } from \"../../store/modules/selectors\"\nimport { unsetCurrentModule } from \"../../store/modules\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport { ReactComponent as AddIcon } from \"../../assets/icons/add-icon.svg\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n hashInfo: {\n \"& p\": {\n color: theme.palette.text.primary + \" !important\",\n },\n },\n header: {\n padding: theme.spacing(0, 1, 2, 1),\n boxSizing: \"content-box\",\n minHeight: 40,\n alignItems: \"center\",\n },\n moduleList: {\n marginTop: theme.spacing(3),\n },\n}))\n\nexport const Panel = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const modulesList = useRootSelector(getModulesList)\n const currentModule = useRootSelector(getCurrentModule)\n const currentPending = useRootSelector(getCurrentPendingModule)\n\n const handleAddModule = () => {\n dispatch(unsetCurrentModule())\n }\n\n return (\n
\n \n Modules and Modifiers\n \n {currentModule || currentPending ? (\n }\n >\n Add\n \n ) : null}\n \n\n \n
\n )\n}\n\nexport default Panel\n","import { Button, ButtonProps, makeStyles } from \"@material-ui/core\";\nimport React from \"react\";\nimport classNames from \"classnames\";\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n color: theme.palette.secondary.main,\n },\n queryButton: {\n textTransform: \"none\",\n fontSize: 16,\n \"&.MuiButton-contained.Mui-disabled\": {\n backgroundColor: theme.palette.secondary.main,\n color: theme.palette.common.white,\n },\n \"&.MuiButton-outlinedSecondary.Mui-disabled\": {\n color: theme.palette.common.white,\n borderColor: theme.palette.common.white,\n },\n },\n buttonDisabled: {\n opacity: 0.5,\n },\n outlined: {\n color: theme.palette.common.white,\n padding: theme.spacing(0.75, 2),\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n transition: \"0.2s ease all\",\n \"&::before\": {\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n },\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n borderColor: \"rgba(217, 212, 173, 0.3)\",\n },\n },\n}));\n\nexport const ActionButton = ({ classes, className, ...props }: ButtonProps) => {\n const _classes = useStyles();\n return (\n \n );\n};\n","import { Transaction, SerializedTransaction } from \"./models\";\nimport { FunctionFragment, Interface } from \"@ethersproject/abi\";\nimport { Module } from \"../modules/models\";\n\nexport function serializeTransaction(\n moduleTransaction: Transaction\n): SerializedTransaction {\n return {\n ...moduleTransaction,\n func: moduleTransaction.func.format(\"full\"),\n };\n}\n\nexport function deserializeTransaction(\n moduleTransaction: SerializedTransaction\n): Transaction {\n const interf = new Interface([moduleTransaction.func]);\n return {\n ...moduleTransaction,\n func: FunctionFragment.from(interf.fragments[0]),\n };\n}\n\nexport function getRemoveModuleTxId(module: Module) {\n return `remove_${module.address}_${module.parentModule}`;\n}\n","import { RootState } from \"../index\";\nimport { deserializeTransaction } from \"./helpers\";\n\nexport function getAddTransaction(state: RootState) {\n return state.transactionBuilder.addTransaction;\n}\n\nexport function getTransactions(state: RootState) {\n return state.transactionBuilder.transactions.map(deserializeTransaction);\n}\n\nexport function getTransactionBuilderOpen(state: RootState) {\n return state.transactionBuilder.open;\n}\n","import React from \"react\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { HashInfo } from \"../../components/ethereum/HashInfo\"\nimport { ActionButton } from \"../../components/ActionButton\"\nimport { Address } from \"../../components/ethereum/Address\"\nimport { Module } from \"../../store/modules/models\"\nimport { disableModule } from \"services\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getPendingRemoveModuleTransactions } from \"../../store/modules/selectors\"\nimport { addTransaction, openTransactionBuilder } from \"../../store/transactionBuilder\"\nimport {\n getRemoveModuleTxId,\n serializeTransaction,\n} from \"../../store/transactionBuilder/helpers\"\nimport { Transaction } from \"../../store/transactionBuilder/models\"\nimport { SafeAbi } from \"../../services/helpers\"\nimport { ReactComponent as RemoveIcon } from \"../../assets/icons/delete-icon.svg\"\nimport { Interface } from \"@ethersproject/abi\"\nimport { getTransactions } from \"../../store/transactionBuilder/selectors\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleDetailHeaderProps {\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n header: {\n minHeight: 88,\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n padding: theme.spacing(3),\n },\n text: {\n marginLeft: \"16px !important\",\n color: theme.palette.text.primary + \" !important\",\n },\n addressType: {\n fontSize: \".75rem\",\n fontFamily: \"Roboto Mono\",\n },\n spacing: {\n marginLeft: theme.spacing(2),\n },\n removeButton: {},\n}))\n\nexport const ModuleDetailHeader = ({ module }: ModuleDetailHeaderProps) => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const { safe, provider } = useSafeAppsSDKWithProvider()\n const pendingRemoveModuleTransactions = useRootSelector(\n getPendingRemoveModuleTransactions,\n )\n const txBuildersTransaction = useRootSelector(getTransactions)\n\n const isRemoveTxOnQueue = txBuildersTransaction.some(\n (tx) => tx.id === getRemoveModuleTxId(module),\n )\n const isModuleToBeRemoved = pendingRemoveModuleTransactions\n .map((pending) => pending.address)\n .includes(module.address)\n const disabledRemoveButton = isRemoveTxOnQueue || isModuleToBeRemoved\n\n const removeModule = async () => {\n try {\n const { params } = await disableModule(\n provider,\n module.parentModule,\n safe.chainId,\n module.address,\n )\n const safeInterface = new Interface(SafeAbi)\n const disableModuleFunc = safeInterface.getFunction(\"disableModule\")\n const transaction: Transaction = {\n module,\n params,\n id: getRemoveModuleTxId(module),\n func: disableModuleFunc,\n to: module.parentModule,\n }\n dispatch(addTransaction(serializeTransaction(transaction)))\n dispatch(openTransactionBuilder())\n } catch (error) {\n console.warn(\"could not remove module\", error)\n }\n }\n\n return (\n
\n \n \n\n \n }\n >\n Remove\n \n
\n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgPlayIcon = function SvgPlayIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 21,\n height: 20,\n viewBox: \"0 0 21 20\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M15.2111 9.10557L8.44721 5.72361C7.78231 5.39116 7 5.87465 7 6.61803L7 13.382C7 14.1253 7.78231 14.6088 8.44722 14.2764L15.2111 10.8944C15.9482 10.5259 15.9482 9.4741 15.2111 9.10557Z\",\n fill: \"#FFFFFF\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgPlayIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/play-icon.aae3f5f2.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport { makeStyles, PaperProps } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport classNames from \"classnames\";\n\ninterface CollapsableProps extends PaperProps {\n open?: boolean;\n content?: React.ReactElement;\n containerClassName?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(2),\n transition: \"0.2s ease all\",\n \"& + &\": {\n marginTop: theme.spacing(2),\n },\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n content: {\n marginTop: theme.spacing(2),\n },\n hide: {\n display: \"none\",\n },\n}));\n\nexport const Collapsable: React.FC = ({\n open = false,\n content,\n children,\n className,\n containerClassName,\n ...props\n}) => {\n const classes = useStyles();\n return (\n \n {children}\n {content ? (\n \n {content}\n
\n ) : null}\n \n );\n};\n","import React, { useRef, useState } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { validateFunctionParams } from \"../../utils/contracts\";\nimport { ParamInputProps } from \"./ParamInput\";\n\ntype ParamValue = { value: any; valid: boolean };\n\ninterface ContractQueryFormProps {\n func: FunctionFragment;\n defaultParams?: any[];\n\n children(props: {\n paramInputProps: ParamInputProps[];\n getParams: () => any[];\n areParamsValid: boolean;\n }): React.ReactElement;\n}\n\nexport const ContractQueryForm = ({\n defaultParams,\n func,\n children,\n}: ContractQueryFormProps) => {\n const params = useRef(\n func.inputs.map((_, index) => ({\n value:\n defaultParams && defaultParams[index] !== undefined\n ? defaultParams[index]\n : \"\",\n valid: true,\n }))\n );\n\n const validate = () => {\n return validateFunctionParams(\n func,\n params.current.map((_param) => _param.value)\n );\n };\n\n const [areParamsValid, setParamsValid] = useState(validate());\n\n const handleParamChange = (index: number, value: any, valid: boolean) => {\n params.current[index] = { value, valid };\n const _areParamsValid = params.current.every((param) => param.valid);\n setParamsValid(_areParamsValid && validate());\n };\n\n const paramInputProps: ParamInputProps[] = func.inputs.map((param, index) => {\n return {\n param: param,\n value: params.current[index].value,\n onChange: (value: any, valid: boolean) => {\n handleParamChange(index, value, valid);\n },\n };\n });\n\n const getParams = () => params.current.map((param) => param.value);\n\n return children({ paramInputProps, getParams, areParamsValid });\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { FunctionOutputs } from \"../../../hooks/useContractQuery\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { formatValue } from \"../../../utils/contracts\";\n\ninterface ContractFunctionResultProps {\n func: FunctionFragment;\n loading?: boolean;\n result?: FunctionOutputs;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n color: theme.palette.common.white,\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n padding: theme.spacing(2),\n },\n item: {\n \"& + &\": {\n marginTop: theme.spacing(1),\n },\n },\n label: {\n color: \"rgba(217, 212, 173, 0.9)\",\n },\n value: {\n overflowWrap: \"break-word\",\n },\n}));\n\nexport const ContractFunctionResult = ({\n func,\n loading = false,\n result,\n}: ContractFunctionResultProps) => {\n const classes = useStyles();\n if (loading) return ;\n if (!result) return null;\n return (\n \n {func.outputs?.map((param, index) => (\n
\n \n {param.name ? `${param.name} (${param.type})` : param.type}:{\" \"}\n \n \n {formatValue(param.baseType, result[index])}\n \n
\n ))}\n
\n );\n};\n","import React from \"react\";\nimport { Address } from \"../../../components/ethereum/Address\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport TimeAgo from \"timeago-react\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { FunctionOutputs } from \"../../../hooks/useContractQuery\";\nimport { CopyToClipboardBtn } from \"@gnosis.pm/safe-react-components\";\nimport { formatValue } from \"../../../utils/contracts\";\nimport classNames from \"classnames\";\n\ninterface ContractFunctionHeaderProps {\n date?: Date;\n func: FunctionFragment;\n loading?: boolean;\n showResult?: boolean;\n result?: FunctionOutputs;\n}\n\nconst useStyles = makeStyles((theme) => ({\n spaceLeft: {\n marginLeft: theme.spacing(1),\n },\n type: {\n fontFamily: \"Roboto Mono\",\n fontSize: \".75rem\",\n },\n queryType: {\n fontSize: \".75rem\",\n },\n}));\n\nexport const ContractFunctionHeader = ({\n date,\n func,\n result,\n showResult,\n loading = false,\n}: ContractFunctionHeaderProps) => {\n const classes = useStyles();\n\n if (loading) {\n return ;\n }\n\n if (showResult && result && result.length && func.outputs) {\n const { baseType, type } = func.outputs[0];\n const value = formatValue(baseType, result[0]);\n\n if (baseType === \"address\") {\n return (\n \n );\n }\n return (\n <>\n \n ({type})\n \n \n {value}\n \n \n \n );\n }\n\n if (date) {\n return (\n \n Queried \n \n );\n }\n\n return Query;\n};\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\n\ninterface ContractFunctionErrorProps {\n error?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n fontSize: 12,\n padding: theme.spacing(2),\n marginBottom: theme.spacing(2),\n color: theme.palette.error.main,\n borderRadius: theme.shape.borderRadius,\n borderColor: theme.palette.error.main,\n borderStyle: \"solid\",\n borderWidth: 2,\n wordWrap: \"break-word\",\n },\n}));\n\nexport const ContractFunctionError = ({\n error,\n}: ContractFunctionErrorProps) => {\n const classes = useStyles();\n if (!error) return null;\n return
{error}
;\n};\n","import React, { useState } from \"react\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ZodiacTextField } from \"zodiac-ui-components\"\nimport { TextFieldProps } from \"../input/TextField\"\nimport { formatParamValue } from \"../../utils/contracts\"\nimport { MenuItem } from \"@material-ui/core\"\nimport { BigNumber } from \"ethers\"\n\nexport interface ParamInputProps\n extends Omit {\n param: ParamType\n value?: string | boolean | BigNumber\n label?: string\n\n onChange(value: any, valid: boolean): void\n}\n\nfunction getLabel(param: ParamType) {\n if (param.name) {\n return `${param.name} (${param.type})`\n }\n return `(${param.type})`\n}\n\nfunction getDefaultValue(\n param: ParamType,\n defaultValue: ParamInputProps[\"value\"],\n): string {\n if (defaultValue !== undefined) {\n if (typeof defaultValue === \"object\") return JSON.stringify(defaultValue)\n return defaultValue.toString()\n }\n return param.baseType === \"boolean\" ? \"false\" : \"\"\n}\n\nexport const ParamInput = ({\n param,\n value: defaultValue,\n onChange,\n ...props\n}: ParamInputProps) => {\n if (props.defaultValue != null) {\n throw new Error(\n \"This is a controlled component, `defaultValue` should not be used. Use `value` instead.\",\n )\n }\n const [value, setValue] = useState(getDefaultValue(param, defaultValue))\n const [error, setError] = useState()\n\n const handleChange = (evt: React.ChangeEvent) => {\n const _value = evt.target.value\n setValue(_value)\n\n if (param.baseType === \"boolean\") {\n onChange(_value === \"true\", true)\n return\n }\n\n if (!_value.length) {\n onChange(_value, false)\n setError(undefined)\n return\n }\n\n try {\n const paramValue = formatParamValue(param, _value)\n onChange(paramValue, true)\n setError(undefined)\n } catch (error: any) {\n onChange(_value, false)\n setError(error?.message)\n }\n }\n\n if (param.baseType === \"boolean\") {\n return (\n \n True\n False\n \n )\n }\n\n return (\n \n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgChevronDown = function SvgChevronDown(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 18,\n height: 10,\n viewBox: \"0 0 18 10\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M10.0651 9.58417C9.77258 9.86274 9.38708 10.0013 9.00008 9.99992C8.61458 10.0013 8.22908 9.86274 7.93658 9.58417C7.93058 9.57846 7.87208 9.51846 7.86608 9.51274L0.439578 2.43703C-0.143922 1.88132 -0.143922 0.972744 0.439578 0.41703C1.02308 -0.138684 1.97708 -0.138684 2.56058 0.41703L9.00008 6.55132L15.4411 0.41703C16.0246 -0.138684 16.9786 -0.138684 17.5621 0.41703C18.1456 0.972744 18.1456 1.88132 17.5621 2.43703L10.1461 9.49846C10.1401 9.50417 10.0711 9.57846 10.0651 9.58417Z\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgChevronDown, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/chevron-down.0df60caa.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\nimport { ReactComponent as ChevronDownIcon } from \"../../assets/icons/chevron-down.svg\";\nimport React from \"react\";\n\nconst useStyles = makeStyles((theme) => ({\n arrowIcon: {\n cursor: \"pointer\",\n color: theme.palette.primary.main,\n fill: \"#B2B5B2\",\n width: 18,\n height: 10,\n \"&.rotate\": {\n transform: \"rotate(180deg)\",\n },\n },\n}));\n\ninterface ArrowIconProps extends React.SVGProps {\n up?: boolean;\n}\n\nexport const ArrowIcon = ({\n up = false,\n className,\n ...props\n}: ArrowIconProps) => {\n const classes = useStyles();\n return (\n \n );\n};\n","import React, { useCallback, useEffect, useState } from \"react\"\nimport { FunctionFragment } from \"@ethersproject/abi\"\nimport { Box, makeStyles, Typography } from \"@material-ui/core\"\nimport { Collapsable } from \"../../../components/Collapsable\"\nimport classNames from \"classnames\"\nimport { useContractQuery } from \"../../../hooks/useContractQuery\"\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\"\nimport { ContractFunctionResult } from \"./ContractFunctionResult\"\nimport { ContractFunctionHeader } from \"./ContractFunctionHeader\"\nimport { formatValue, isBasicFunction, isOneResult } from \"../../../utils/contracts\"\nimport { Row } from \"../../../components/layout/Row\"\nimport { ContractFunctionError } from \"./ContractFunctionError\"\nimport { ReactComponent as PlayIcon } from \"../../../assets/icons/play-icon.svg\"\nimport { ActionButton } from \"../../../components/ActionButton\"\nimport { ParamInput } from \"../../../components/ethereum/ParamInput\"\nimport { useRootSelector } from \"../../../store\"\nimport { getReloadCount } from \"../../../store/modules/selectors\"\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\"\nimport { Grow } from \"../../../components/layout/Grow\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ContractFunctionBlockProps {\n address: string\n func: FunctionFragment\n}\n\nconst useStyles = makeStyles((theme) => ({\n clickable: {\n cursor: \"pointer\",\n },\n expandIcon: {\n marginLeft: theme.spacing(2),\n },\n icon: {\n color: theme.palette.common.white,\n },\n queryButton: {\n marginTop: theme.spacing(2),\n },\n title: {\n marginRight: theme.spacing(1),\n },\n}))\n\nexport const ContractFunctionQueryBlock = ({\n address,\n func,\n}: ContractFunctionBlockProps) => {\n const classes = useStyles()\n const reloadCount = useRootSelector(getReloadCount)\n const { safe, provider } = useSafeAppsSDKWithProvider()\n\n const [open, setOpen] = useState(false)\n const [lastQueryDate, setLastQueryDate] = useState()\n\n const { loading, result, fetch, error } = useContractQuery()\n\n const isBasic = isBasicFunction(func)\n const oneResult = isOneResult(func)\n\n const baseType = oneResult && func.outputs ? func.outputs[0].baseType : \"\"\n const resultLength =\n result === undefined || !oneResult ? 0 : formatValue(baseType, result[0]).length\n\n const execQuery = useCallback(\n (params?: any[]) => {\n setLastQueryDate(undefined)\n fetch(provider, safe.chainId, address, [func], func.name, params)\n },\n [address, fetch, func, safe.chainId, provider],\n )\n\n useEffect(() => {\n if (!loading && result) {\n setLastQueryDate(new Date())\n }\n }, [loading, result])\n\n useEffect(() => {\n if (isBasic) {\n execQuery()\n }\n }, [execQuery, isBasic, reloadCount])\n\n const maxResultLength = 60\n const showResultOnHeader = oneResult && resultLength < maxResultLength && !error\n const collapsable = !showResultOnHeader || !isBasic\n\n const content = (\n <>\n \n {!showResultOnHeader ? (\n \n ) : null}\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n <>\n {paramInputProps.map((props, index) => (\n \n \n \n ))}\n {paramInputProps.length ? (\n execQuery(getParams())}\n startIcon={}\n >\n Run Query\n \n ) : null}\n \n )}\n \n \n )\n\n return (\n \n setOpen(!open)}\n >\n {func.name}\n \n \n {collapsable ? : null}\n \n \n )\n}\n","import { useCallback, useState } from \"react\";\nimport { callContract } from \"../services\";\nimport { BigNumber } from \"ethers\";\n\nexport type FunctionOutputs = (string | BigNumber)[];\n\nexport const useContractQuery = () => {\n const [loading, setLoading] = useState(false);\n const [result, setResult] = useState();\n const [error, setError] = useState();\n\n const fetch = useCallback((...params: Parameters) => {\n setLoading(true);\n setResult(undefined);\n callContract(...params)\n .then((response) => {\n setResult(response);\n setError(undefined);\n })\n .catch((error) => {\n setError(error.message);\n setResult(undefined);\n })\n .finally(() => setLoading(false));\n }, []);\n\n return { loading, error, result, fetch };\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Collapsable } from \"../../../components/Collapsable\";\nimport { ContractFunctionHeader } from \"./ContractFunctionHeader\";\nimport { isBasicFunction, isOneResult } from \"../../../utils/contracts\";\nimport { Row } from \"../../../components/layout/Row\";\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\";\nimport { Grow } from \"../../../components/layout/Grow\";\n\ninterface ContractFunctionPreviewBlockProps {\n func: FunctionFragment;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n opacity: 0.5,\n },\n expandIcon: {\n marginLeft: theme.spacing(2),\n },\n icon: {\n color: theme.palette.secondary.main,\n },\n title: {\n marginRight: theme.spacing(1),\n },\n}));\n\nfunction getPlaceholderValue(func: FunctionFragment): string {\n if (!isOneResult(func) || !func.outputs) return \"\";\n const { baseType } = func.outputs[0];\n\n if (baseType.includes(\"int\")) return \"0\";\n if (baseType === \"bool\") return \"true\";\n return \"0x0000000000000000000000000000000000000000\";\n}\n\nexport const ContractFunctionPreviewBlock = ({\n func,\n}: ContractFunctionPreviewBlockProps) => {\n const classes = useStyles();\n\n const isBasic = isBasicFunction(func);\n const oneResult = isOneResult(func);\n\n const shrink = isBasic && oneResult;\n\n return (\n \n \n {func.name}\n \n \n {!shrink ? : null}\n \n \n );\n};\n","import React, { useMemo } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { ContractFunctionQueryBlock } from \"./ContractFunctionQueryBlock\";\nimport { getReadFunction } from \"../../../utils/contracts\";\nimport { ContractFunctionPreviewBlock } from \"./ContractFunctionPreviewBlock\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ntype ModuleListFunctionsProps = {\n address: string;\n abi: ContractInterface;\n preview?: boolean;\n};\n\nexport const ContractReadFunctionsList = ({\n abi,\n address,\n preview,\n}: ModuleListFunctionsProps) => {\n const readFunctions: FunctionFragment[] = useMemo(\n () => getReadFunction(abi),\n [abi]\n );\n\n return (\n <>\n {readFunctions.map((func) => {\n if (preview) {\n return ;\n }\n\n return (\n \n );\n })}\n \n );\n};\n","import React from \"react\"\nimport {\n Grid,\n GridProps,\n InputBase,\n InputLabel,\n makeStyles,\n StandardTextFieldProps,\n TextField as MUITextField,\n Tooltip,\n withStyles,\n} from \"@material-ui/core\"\nimport classNames from \"classnames\"\nimport { colors } from \"zodiac-ui-components\"\nimport HelpOutline from \"@material-ui/icons/HelpOutline\"\n\nconst StyledTextField = withStyles((theme) => ({\n root: {\n \"& label.Mui-focused\": {\n position: \"relative\",\n transform: \"none\",\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n \"& .MuiInputBase-root\": {\n marginTop: 0,\n minHeight: \"37px\",\n },\n \"& .MuiSelect-select:focus\": {\n backgroundColor: \"transparent\",\n },\n },\n}))(MUITextField)\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: \"4px\",\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n icon: {\n fontSize: \"1rem\",\n },\n append: {\n display: \"flex\",\n alignItems: \"center\",\n padding: theme.spacing(1),\n borderWidth: 1,\n borderStyle: \"solid\",\n borderLeftWidth: 0,\n },\n primary: {\n borderColor: theme.palette.primary.light,\n },\n secondary: {\n borderColor: colors.tan[300],\n },\n error: {\n background: \"rgba(244, 67, 54, 0.1)\",\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n },\n}))\n\nexport interface TextFieldProps\n extends Omit {\n label?: string\n append?: React.ReactElement | string\n AppendProps?: GridProps\n variantAppend?: \"primary\" | \"secondary\" | \"error\"\n tooltipMsg?: string\n}\n\nexport const TextField = ({\n InputProps,\n InputLabelProps,\n label,\n append,\n variantAppend,\n AppendProps,\n tooltipMsg,\n ...props\n}: TextFieldProps) => {\n const classes = useStyles()\n\n const handleRoot = () => {\n switch (variantAppend) {\n case \"primary\":\n return classes.primary\n\n case \"secondary\":\n return classes.secondary\n\n case \"error\":\n return classes.error\n }\n }\n\n if (props.select || !append) {\n return (\n \n )\n }\n\n return (\n
\n \n \n \n {label}\n \n \n {tooltipMsg && (\n \n \n \n \n \n )}\n \n \n \n \n \n \n {append}\n \n \n
\n )\n}\n","import { useEffect, useState } from \"react\"\n\nconst useKeyPress = (targetKey: string) => {\n const [keyPressed, setKeyPressed] = useState(false)\n // If pressed key is our target key then set to true\n function downHandler({ key }: { key: string }) {\n if (key === targetKey) {\n setKeyPressed(true)\n }\n }\n // If released key is our target key then set to false\n const upHandler = ({ key }: { key: string }) => {\n if (key === targetKey) {\n setKeyPressed(false)\n }\n }\n\n useEffect(() => {\n window.addEventListener(\"keydown\", downHandler)\n window.addEventListener(\"keyup\", upHandler)\n return () => {\n window.removeEventListener(\"keydown\", downHandler)\n window.removeEventListener(\"keyup\", upHandler)\n }\n // eslint-disable-next-line\n }, [])\n\n return keyPressed\n}\n\nexport default useKeyPress\n","import React, { useEffect, useState } from \"react\"\nimport { Box, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { BigNumber, BigNumberish } from \"ethers\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { TextField } from \"./TextField\"\nimport { colors } from \"zodiac-ui-components\"\nimport useKeyPress from \"hooks/useKeyPress\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport ReportProblemOutlinedIcon from \"@material-ui/icons/ReportProblemOutlined\"\n\nexport const unitConversion = {\n seconds: 1,\n minutes: 60,\n hours: 3600,\n days: 86400,\n months: 2592000, // 30 Days\n}\ntype Unit = keyof typeof unitConversion\n\ninterface TimeSelectProps {\n tooltipMsg?: string\n defaultValue?: BigNumberish\n defaultUnit?: Unit\n value?: string\n valueUnit?: Unit\n label: string\n variant?: \"primary\" | \"secondary\" | \"error\"\n alertType?: \"error\" | \"warning\"\n onChange(time: string, unit: Unit): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n select: {\n padding: 0,\n border: 0,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"120px\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n primary: {\n borderColor: theme.palette.primary.light,\n },\n secondary: {\n borderColor: colors.tan[300],\n },\n error: {\n background: \"rgba(244, 67, 54, 0.1)\",\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n },\n}))\n\nfunction calculateTime(amount: string, unit: Unit): BigNumber {\n return BigNumber.from(amount).mul(unitConversion[unit])\n}\n\nexport const TimeSelect = ({\n onChange,\n defaultUnit = \"hours\",\n defaultValue = \"0\",\n value,\n valueUnit,\n label,\n variant = \"primary\",\n tooltipMsg,\n alertType,\n}: TimeSelectProps) => {\n const classes = useStyles()\n const tabPress = useKeyPress(\"Tab\")\n const [unit, setUnit] = useState(defaultUnit)\n const [amount, setAmount] = useState(\n BigNumber.from(defaultValue).div(unitConversion[unit]).toString(),\n )\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleAmountChange = (_amount: string) => {\n try {\n const newAmount = calculateTime(_amount || \"0\", unit)\n setAmount(_amount)\n onChange(newAmount.toString(), unit)\n } catch (err) {\n console.warn(\"invalid time\")\n }\n }\n\n const handleAdornment = () => {\n if (alertType) {\n switch (alertType) {\n case \"error\":\n return \n\n case \"warning\":\n return \n }\n }\n return null\n }\n\n const handleRoot = () => {\n switch (variant) {\n case \"primary\":\n return classes.primary\n\n case \"secondary\":\n return classes.secondary\n\n case \"error\":\n return classes.error\n }\n }\n\n const handleUnitChange = (newUnit: Unit) => {\n handleClose()\n setUnit(newUnit)\n if (amount) onChange(calculateTime(amount, newUnit).toString(), newUnit)\n }\n\n useEffect(() => {\n if (tabPress && open) {\n handleClose()\n }\n }, [tabPress, open])\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n useEffect(() => {\n if (value && valueUnit) {\n const parsedValue = BigNumber.from(value).div(unitConversion[valueUnit]).toString()\n if (parsedValue !== amount) {\n setAmount(parsedValue)\n }\n if ([\"hours\", \"days\"].includes(unit) && valueUnit !== unit) {\n setUnit(valueUnit)\n }\n }\n }, [value, valueUnit, amount, unit])\n\n return (\n handleAmountChange(evt.target.value),\n startAdornment: handleAdornment(),\n }}\n AppendProps={{\n className: classes.dropdownContainer,\n }}\n append={\n value as string}\n onChange={(evt) => handleUnitChange(evt.target.value as Unit)}\n >\n {Object.keys(unitConversion).map((unit) => (\n \n {unit}\n \n \n \n ))}\n \n }\n />\n )\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgArrowUpIcon = function SvgArrowUpIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 11,\n height: 13,\n viewBox: \"0 0 11 13\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M8.79066 6.19787L6.50066 3.90787V11.4949C6.50066 12.0449 6.05066 12.4949 5.50066 12.4949C4.94966 12.4949 4.50066 12.0449 4.50066 11.4949V3.90787L2.20966 6.19787C1.82066 6.58687 1.18466 6.58687 0.795656 6.19787C0.406656 5.80887 0.406656 5.17287 0.795656 4.78387L4.79366 0.786873C4.85166 0.726872 4.92566 0.694874 4.99366 0.653873C5.03566 0.628874 5.06966 0.592874 5.11566 0.572873C5.15666 0.554873 5.20266 0.554873 5.24566 0.544873C5.45766 0.487873 5.68166 0.488873 5.88566 0.572873C5.92966 0.591873 5.96266 0.626873 6.00366 0.651873C6.07366 0.692873 6.14666 0.725873 6.20766 0.786873L10.2047 4.78387C10.5937 5.17287 10.5937 5.80887 10.2047 6.19787C9.81566 6.58787 9.17966 6.58787 8.79066 6.19787Z\",\n fill: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgArrowUpIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/arrow-up-icon.7e5a12da.svg\";\nexport { ForwardRef as ReactComponent };","import {\n ParamInput,\n ParamInputProps,\n} from \"../../../components/ethereum/ParamInput\";\nimport React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { TimeSelect } from \"../../../components/input/TimeSelect\";\nimport { BigNumberish } from \"ethers\";\n\ninterface TransactionFieldProps {\n param: ParamInputProps;\n func: FunctionFragment;\n}\n\nexport const TransactionField = ({ param, func }: TransactionFieldProps) => {\n if (func.inputs.length === 1) {\n const [input] = func.inputs;\n const isTimeField = [\"setTxCooldown\", \"setTxExpiration\"].includes(\n func.name\n );\n const isTime = isTimeField && input.type.includes(\"int\");\n if (isTime) return ;\n }\n\n return ;\n};\n\nexport const TransactionTimeField = ({\n label,\n value,\n onChange,\n ...props\n}: ParamInputProps) => {\n const defaultValue = value || \"0\";\n return (\n onChange(time, true)}\n />\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { makeStyles, MenuItem, Typography } from \"@material-ui/core\";\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\";\nimport { ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\";\nimport { getWriteFunction } from \"../../../utils/contracts\";\nimport classNames from \"classnames\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { ActionButton } from \"../../../components/ActionButton\";\nimport { useRootDispatch, useRootSelector } from \"../../../store\";\nimport { getAddTransaction } from \"../../../store/transactionBuilder/selectors\";\nimport { resetNewTransaction } from \"../../../store/transactionBuilder\";\nimport { getCurrentModule } from \"../../../store/modules/selectors\";\nimport { TransactionField } from \"./TransactionField\";\nimport { ReactComponent as AddIcon } from \"../../../assets/icons/add-icon.svg\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface AddTransactionBlockProps {\n abi: ContractInterface;\n\n onAdd(transaction: Transaction): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n greyText: {\n \"& select\": {\n color: theme.palette.primary.main,\n },\n },\n icon: {\n color: theme.palette.common.white,\n },\n addButton: {\n marginTop: theme.spacing(2),\n },\n header: {\n padding: theme.spacing(1),\n marginBottom: theme.spacing(1.5),\n },\n text: {\n maxWidth: 366,\n },\n content: {\n padding: theme.spacing(1.5),\n },\n field: {\n marginTop: theme.spacing(2.5),\n },\n}));\n\ntype TransactionFieldsProps = {\n func?: FunctionFragment;\n defaultParams?: any[];\n} & Pick;\n\nconst TransactionFields = ({\n func,\n onAdd,\n defaultParams,\n}: TransactionFieldsProps) => {\n const classes = useStyles();\n const module = useRootSelector(getCurrentModule);\n\n if (!func) {\n return (\n }\n >\n Add this transaction\n \n );\n }\n\n const handleAdd = (params: any[]) => {\n if (!module) return;\n onAdd({\n func,\n params,\n module,\n to: module.address,\n id: `${func.name}_${new Date().getTime()}`,\n });\n };\n\n return (\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n <>\n {paramInputProps.map((props, index) => (\n
\n \n
\n ))}\n handleAdd(getParams())}\n disabled={!areParamsValid}\n className={classes.addButton}\n startIcon={}\n >\n Add this transaction\n \n \n )}\n
\n );\n};\n\nconst getSelectedFunction = (\n writeFunctions: FunctionFragment[],\n selectedFunc?: string\n): number => {\n if (selectedFunc) {\n const index = writeFunctions.findIndex(\n (func) => func.format() === selectedFunc\n );\n if (index >= 0) return index;\n }\n return -1;\n};\n\nexport const AddTransactionBlock = ({\n abi,\n onAdd,\n}: AddTransactionBlockProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n const writeFunctions = useMemo(() => getWriteFunction(abi), [abi]);\n const { func: selectedFunc, params: defaultParams } =\n useRootSelector(getAddTransaction);\n\n const [funcIndex, setFuncIndex] = useState(() =>\n getSelectedFunction(writeFunctions, selectedFunc)\n );\n\n useEffect(() => {\n if (selectedFunc)\n setFuncIndex(getSelectedFunction(writeFunctions, selectedFunc));\n }, [selectedFunc, writeFunctions]);\n\n const handleAdd = (transaction: Transaction) => {\n setFuncIndex(-1);\n onAdd(transaction);\n };\n\n const handleFuncChange = (event: React.ChangeEvent) => {\n setFuncIndex(parseInt(event.target.value));\n dispatch(resetNewTransaction());\n };\n\n return (\n <>\n \n \n Add Transaction\n \n \n Add multiple transactions here, and we will bundle them together into\n a single transaction, to save you gas.\n \n \n\n \n \n Select function\n {writeFunctions.map((func, index) => (\n \n {func.name}\n \n ))}\n \n \n \n \n );\n};\n","import React from \"react\";\nimport {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupProps,\n} from \"@material-ui/lab\";\nimport { withStyles } from \"@material-ui/core\";\n\nconst StyledToggleButton = withStyles((theme) => ({\n root: {\n width: \"50%\",\n padding: theme.spacing(1, 2.5),\n \"& span\": {\n fontSize: 16,\n textTransform: \"none\",\n color: theme.palette.text.primary + \" !important\",\n },\n },\n selected: {\n backgroundColor: theme.palette.secondary.main + \" !important\",\n },\n}))(ToggleButton);\n\ninterface ContractOperationToggleButtonsProps extends ToggleButtonGroupProps {\n disabled?: boolean;\n}\n\nexport const ContractOperationToggleButtons = ({\n disabled = false,\n ...props\n}: ContractOperationToggleButtonsProps) => {\n return (\n \n \n Read Contract\n \n \n Write Contract\n \n \n );\n};","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\";\nimport { ContractReadFunctionsList } from \"./ContractReadFunctionsList\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { setOperation } from \"../../../store/modules\";\nimport { useRootDispatch, useRootSelector } from \"../../../store\";\nimport classNames from \"classnames\";\nimport { Operation } from \"../../../store/modules/models\";\nimport { getOperation } from \"../../../store/modules/selectors\";\nimport { AddTransactionBlock } from \"../transaction/AddTransactionBlock\";\nimport { addTransaction } from \"../../../store/transactionBuilder\";\nimport { serializeTransaction } from \"../../../store/transactionBuilder/helpers\";\nimport { ContractOperationToggleButtons } from \"../ContractOperationToggleButtons\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface ContractInteractionsProps {\n address: string;\n abi: ContractInterface;\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(2),\n marginTop: theme.spacing(3),\n background: colors.tan[100],\n },\n hide: {\n display: \"none\",\n },\n}));\n\nexport const ContractInteractions = ({\n address,\n abi,\n}: ContractInteractionsProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n const operation = useRootSelector(getOperation);\n\n const handleOperationChange = (operation?: Operation) => {\n if (operation) dispatch(setOperation(operation));\n };\n\n const handleAddTransaction = (transaction: Transaction) => {\n dispatch(addTransaction(serializeTransaction(transaction)));\n };\n\n return (\n <>\n handleOperationChange(value)}\n />\n\n \n
\n \n
\n
\n \n
\n
\n \n );\n};\n","import React from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { Link } from \"../../components/text/Link\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { getNetworkExplorerInfo } from \"../../utils/explorers\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(2.5),\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n link: {\n fontSize: 16,\n },\n}))\n\nexport const ModuleNoAvailable = () => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const { verifyUrl } = getNetworkExplorerInfo(safe.chainId) || {}\n\n return (\n \n \n No Read or Write functions available\n \n \n We couldn't find an ABI and didn't recognize it as one of the known Zodiac\n contracts.\n \n \n Verify this contract on Etherscan to fix this.\n \n \n )\n}\n","import React, { useEffect, useState } from \"react\"\nimport { ContractInteractions } from \"./contract/ContractInteractions\"\nimport { getModuleData } from \"../../utils/contracts\"\nimport { Module } from \"../../store/modules/models\"\nimport { ModuleNoAvailable } from \"./ModuleNoAvailable\"\nimport { Skeleton } from \"@material-ui/lab\"\nimport { ContractInterface } from \"@ethersproject/contracts\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ModuleInteractionsProps {\n module: Module\n}\n\nexport const ModuleInteractions = ({ module }: ModuleInteractionsProps) => {\n const { safe, sdk, provider } = useSafeAppsSDKWithProvider()\n const [loading, setLoading] = useState(true)\n const [abi, setABI] = useState()\n\n useEffect(() => {\n setLoading(true)\n setABI(undefined)\n getModuleData(provider, sdk, safe.chainId, module.address)\n .then(({ abi }) => setABI(abi))\n .catch((error) => console.warn(\"getModuleABI\", error))\n .finally(() => setLoading(false))\n }, [module, safe, sdk, provider])\n\n if (loading) return \n\n if (!abi) return \n\n return \n}\n","import React from \"react\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { ModuleDetailHeader } from \"./ModuleDetailHeader\"\nimport { ModuleInteractions } from \"./ModuleInteractions\"\nimport { Module } from \"../../store/modules/models\"\n\ninterface ModuleDetailsProps {\n module: Module\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(0, 2, 2, 2),\n },\n}))\n\nexport const ModuleDetails = ({ module }: ModuleDetailsProps) => {\n const classes = useStyles()\n\n return (\n <>\n \n
\n \n
\n \n )\n}\n\nexport default ModuleDetails\n","import React, { HTMLProps } from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport classNames from \"classnames\";\n\nconst useStyles = makeStyles((theme) => ({\n tag: {\n display: \"inline-block\",\n borderRadius: 8,\n lineHeight: 1,\n padding: theme.spacing(0.75, 0.5),\n margin: theme.spacing(0, 1, 1, 0),\n backgroundColor: \"rgba(0,20,40,0.5)\",\n color: theme.palette.common.white,\n },\n}));\n\nexport const Tag: React.FC> = ({\n children,\n className,\n ...props\n}) => {\n const classes = useStyles();\n return (\n
\n {children}\n
\n );\n};\n","import React from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport { BadgeIconProps } from \"zodiac-ui-components/lib/components/Icons/BadgeIcon/BadgeIcon\"\nimport classNames from \"classnames\"\nimport { Tag } from \"components/text/Tag\"\n\ninterface ModuleButtonProps extends BadgeIconProps {\n title: string\n description: string\n available: boolean\n deprecated?: boolean\n className?: string\n onClick(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n userSelect: \"none\",\n padding: theme.spacing(2),\n cursor: \"pointer\",\n transition: \"0.2s ease all\",\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n badgeIcon: {\n background: colors.sepia[100],\n marginBottom: theme.spacing(1),\n },\n title: {\n marginBottom: theme.spacing(0.5),\n },\n}))\n\nexport const ModuleButton = ({\n title,\n description,\n icon,\n available,\n deprecated,\n className,\n onClick,\n}: ModuleButtonProps) => {\n const classes = useStyles()\n\n if (!available) return null\n\n return (\n \n \n \n {title}\n \n {deprecated && Deprecated}\n \n {description}\n \n \n )\n}\n","import React from \"react\";\nimport { Tag } from \"../text/Tag\";\n\ninterface TagListProps {\n tags: string[];\n style?: React.CSSProperties;\n className?: string;\n}\n\nexport const TagList = ({ tags, className, style }: TagListProps) => {\n return (\n
\n {tags.map((tag) => (\n \n {tag}\n \n ))}\n
\n );\n};\n","var _rect, _path, _rect2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckboxChecked = function SvgCheckboxChecked(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 32,\n height: 32,\n viewBox: \"0 0 32 32\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _rect || (_rect = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n fill: \"#E0C5AD\",\n fillOpacity: 0.1\n })), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M10 17L14 21L23 11\",\n stroke: \"white\",\n strokeWidth: 2,\n strokeLinejoin: \"round\"\n })), _rect2 || (_rect2 = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n stroke: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckboxChecked, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkbox-checked.6146c37e.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\"\nimport { ButtonProps as MuiButtonProps, Fade, makeStyles, Modal, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, ZodiacPaper } from \"zodiac-ui-components\"\nimport { BadgeIconProps } from \"zodiac-ui-components/lib/components/Icons/BadgeIcon/BadgeIcon\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { Icon } from \"@gnosis.pm/safe-react-components\"\nimport classNames from \"classnames\"\nimport { Link } from \"../../../../components/text/Link\"\nimport { TagList } from \"../../../../components/list/TagList\"\nimport { Row } from \"../../../../components/layout/Row\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\n\ninterface AddModuleModalProps extends BadgeIconProps {\n open: boolean\n title: string\n description?: string\n tags?: string[]\n readMoreLink?: string\n ButtonProps?: MuiButtonProps\n warning?: React.ReactNode\n hideButton?: boolean\n\n onAdd?(): void\n\n onClose?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n outline: \"none\",\n maxWidth: 380,\n margin: theme.spacing(14, 1, 1, 1),\n padding: theme.spacing(2),\n backgroundColor: \"rgba(78, 72, 87, 0.8)\",\n },\n modal: {\n position: \"absolute !important\" as \"absolute\",\n paddingBottom: theme.spacing(2),\n overflow: \"auto\",\n alignItems: \"flex-start\",\n },\n backdrop: {\n backdropFilter: \"blur(4px)\",\n },\n description: {\n marginTop: theme.spacing(1),\n },\n gutterBottom: {\n marginBottom: theme.spacing(3),\n },\n row: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n center: {\n justifyContent: \"center\",\n },\n imageContainer: {\n marginRight: theme.spacing(2),\n minWidth: 68,\n },\n infoContainer: {\n flexGrow: 1,\n },\n readMore: {\n display: \"block\",\n marginTop: theme.spacing(1.5),\n fontSize: 16,\n },\n loader: {\n display: \"block\",\n margin: \"0 auto\",\n },\n warningIcon: {\n marginRight: theme.spacing(1),\n \"& .icon-color\": {\n fill: \"#E0B325 !important\",\n },\n },\n warningText: {\n color: \"#E0B325\",\n },\n}))\n\nexport const AddModuleModal: React.FC = ({\n open,\n title,\n description,\n onAdd,\n tags = [],\n icon,\n readMoreLink,\n onClose,\n children,\n ButtonProps,\n warning,\n hideButton = false,\n}) => {\n const classes = useStyles()\n return (\n \n \n \n
\n \n
\n \n {title}\n \n\n \n\n {description ? (\n \n {description}\n \n ) : null}\n\n {warning ? (\n \n \n \n {warning}\n \n \n ) : null}\n\n {readMoreLink ? (\n \n Read more here\n \n ) : null}\n
\n
\n\n {children ?
{children}
: null}\n\n {hideButton ? null : (\n } onClick={onAdd} {...ButtonProps}>\n Add Module\n \n )}\n
\n
\n \n )\n}\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport { Radio as MUIRadio, RadioProps } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n color: theme.palette.text.secondary,\n \"&:hover\": {\n background: \"none\",\n },\n },\n}));\n\nexport const Radio = ({ ...props }: RadioProps) => {\n const classes = useStyles();\n\n return (\n \n );\n};\n","var _rect, _rect2;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckboxUnchecked = function SvgCheckboxUnchecked(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 32,\n height: 32,\n viewBox: \"0 0 32 32\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _rect || (_rect = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n fill: \"#E0C5AD\",\n fillOpacity: 0.1\n })), _rect2 || (_rect2 = /*#__PURE__*/React.createElement(\"rect\", {\n x: 0.5,\n y: 0.5,\n width: 31,\n height: 31,\n rx: 3.5,\n stroke: \"white\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckboxUnchecked, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkbox-unchecked.5c1a7eb5.svg\";\nexport { ForwardRef as ReactComponent };","import React from \"react\";\nimport {\n Checkbox as MUICheckbox,\n CheckboxProps,\n makeStyles,\n} from \"@material-ui/core\";\nimport { ReactComponent as CheckMarkCheckedIcon } from \"../../assets/icons/checkbox-checked.svg\";\nimport { ReactComponent as CheckMarkUncheckedIcon } from \"../../assets/icons/checkbox-unchecked.svg\";\n\nconst useStyles = makeStyles(() => ({\n root: {\n padding: 0,\n backgroundColor: \"transparent !important\",\n borderRadius: 0,\n },\n}));\n\nexport const Checkbox = ({ ...props }: CheckboxProps) => {\n const classes = useStyles();\n\n return (\n }\n checkedIcon={}\n classes={{ root: classes.root }}\n {...props}\n />\n );\n};\n","import React, { useState } from \"react\"\nimport { Row } from \"../../../../components/layout/Row\"\nimport { Radio } from \"../../../../components/input/Radio\"\nimport { Checkbox } from \"../../../../components/input/Checkbox\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { Badge } from \"../../../../components/text/Badge\"\nimport { Address } from \"../../../../components/ethereum/Address\"\nimport classNames from \"classnames\"\nimport { formatDuration } from \"../../../../utils/string\"\nimport { Column } from \"../../../../components/layout/Column\"\nimport { Module, ModuleType } from \"../../../../store/modules/models\"\nimport { isDelayModule } from \"../../../../store/modules/helpers\"\n\ninterface AttachModuleFormProps {\n modules: Module[]\n value?: string\n description?: React.ReactNode\n type: ModuleType\n\n onChange(address?: string): void\n}\n\nconst defaultDescription = (\n This will add a timedelay to any transactions created by this module.\n)\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n marginLeft: theme.spacing(1.5),\n },\n item: {\n marginTop: theme.spacing(2),\n },\n text: {\n fontSize: 12,\n },\n delayText: {\n marginBottom: theme.spacing(0.5),\n },\n}))\n\nexport const AttachModuleForm = ({\n modules,\n value,\n description = defaultDescription,\n type,\n onChange,\n}: AttachModuleFormProps) => {\n const classes = useStyles()\n const [checked, setChecked] = useState(false)\n\n const handleCheck = () => {\n if (checked) onChange(undefined)\n setChecked(!checked)\n }\n\n return (\n \n \n
\n Attach to {type.replace(/^\\w/, (c) => c.toUpperCase())} Module\n {description}\n\n {checked\n ? modules.map((module) => (\n \n onChange(module.address)} />\n \n {isDelayModule(module) ? (\n \n {formatDuration(module.expiration)} delay\n \n ) : null}\n \n \n \n ))\n : null}\n
\n
\n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployTellorModule, getTellorOracle } from \"../../../../services\"\nimport { useRootSelector } from \"../../../../store\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { getDelayModules } from \"../../../../store/modules/selectors\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { ModuleType } from \"../../../../store/modules/models\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface TellorModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface TellorModuleParams {\n owner: string\n oracle: string\n cooldown: string\n expiration: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const TellorModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: TellorModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const delayModules = useRootSelector(getDelayModules)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [params, setParams] = useState({\n owner: safe.safeAddress,\n oracle: getTellorOracle(safe.chainId),\n cooldown: \"86400\",\n expiration: \"604800\",\n })\n const [validFields, setValidFields] = useState({\n oracle: !!params.oracle,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: TellorModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddTellorModule = async () => {\n try {\n const args = {\n ...params,\n executor: delayModule || safe.safeAddress,\n }\n const txs = deployTellorModule(provider, safe.safeAddress, safe.chainId, args)\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"owner\", value, valid)}\n />\n \n \n onParamChange(\"oracle\", value, valid)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport {\n deployOptimisticGovernorModule,\n getFinder,\n getCollateral,\n} from \"../../../../services\"\nimport { useRootSelector } from \"../../../../store\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { getDelayModules } from \"../../../../store/modules/selectors\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { ModuleType } from \"../../../../store/modules/models\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport {\n collateralOptions,\n CollateralSelect,\n} from \"../../../../components/input/CollateralSelect\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface OptimisticGovernorModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface OptimisticGovernorModuleParams {\n finder: string\n owner: string\n collateral: string\n bond: string\n rules: string\n identifier: string\n liveness: string\n snapshotURL: string\n votingQuorum: string\n votingPeriod: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n errorMessage: {\n color: \"red\",\n },\n}))\n\nexport const OptimisticGovernorModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: OptimisticGovernorModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const delayModules = useRootSelector(getDelayModules)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [isWeth, setIsWeth] = useState(true)\n const [params, setParams] = useState({\n finder: getFinder(safe.chainId),\n owner: safe.safeAddress,\n collateral: getCollateral(safe.chainId, isWeth),\n bond: \"2\",\n rules: \"\",\n identifier: \"0x4153534552545f54525554480000000000000000000000000000000000000000\",\n liveness: \"86400\",\n snapshotURL: \"https://snapshot.org/#/\",\n votingQuorum: \"5\",\n votingPeriod: \"24\",\n })\n const [validFields, setValidFields] = useState({\n finder: !!params.finder,\n bond: !!params.bond,\n snapshotURL: !!params.snapshotURL,\n votingPeriod: !!params.votingPeriod,\n votingQuorum: !!params.votingQuorum,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: OptimisticGovernorModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddOptimisticGovernorModule = async () => {\n try {\n const args = {\n ...params,\n owner: safe.safeAddress,\n executor: delayModule || safe.safeAddress,\n }\n const txs = deployOptimisticGovernorModule(\n provider,\n safe.safeAddress,\n safe.chainId,\n args,\n isWeth,\n )\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n params.rules = `I assert that this transaction proposal is valid according to the following rules: Proposals approved on Snapshot, as verified at ${params.snapshotURL}, are valid as long as there is a minimum quorum of ${params.votingQuorum} and a minimum voting period of ${params.votingPeriod} hours and it does not appear that the Snapshot voting system is being exploited or is otherwise unavailable. The quorum and voting period are minimum requirements for a proposal to be valid. Quorum and voting period values set for a specific proposal in Snapshot should be used if they are more strict than the rules parameter. The explanation included with the on-chain proposal must be the unique IPFS identifier for the specific Snapshot proposal that was approved or a unique identifier for a proposal in an alternative voting system approved by DAO social consensus if Snapshot is being exploited or is otherwise unavailable.`\n\n return (\n \n Parameters\n\n \n \n {\n onParamChange(\"collateral\", value)\n setIsWeth(!isWeth)\n }}\n chainId={safe.chainId}\n />\n \n \n onParamChange(\"bond\", value, valid)}\n />\n \n {Number(params.bond) < 1500 && !isWeth\n ? \"Warning: A minimum bond of 1,500 is recommended for USDC\"\n : Number(params.bond) < 2 && isWeth\n ? \"Warning: A bond of 2 is recommended for WETH\"\n : null}\n \n \n \n onParamChange(\"liveness\", value)}\n />\n \n {Number(params.liveness) < 86400\n ? \"Warning: The minimum recommended liveness period is 24 hours.\"\n : null}\n \n \n \n onParamChange(\"snapshotURL\", value, valid)}\n />\n \n \n onParamChange(\"votingQuorum\", value, valid)}\n />\n \n \n onParamChange(\"votingPeriod\", value, valid)}\n />\n \n \n Rules Parameter:\n {params.rules}\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { TimeSelect } from \"../../../../components/input/TimeSelect\"\nimport { deployDelayModule } from \"services\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface DelayModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface DelayModuleParams {\n expiration: string\n cooldown: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const DelayModuleModal = ({ open, onClose, onSubmit }: DelayModuleModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [params, setParams] = useState({\n expiration: \"86400\",\n cooldown: \"86400\",\n })\n\n const onParamChange = (\n field: Field,\n value: DelayModuleParams[Field],\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddDelayModule = async () => {\n try {\n const txs = deployDelayModule(provider, safe.safeAddress, safe.chainId, {\n executor: safe.safeAddress,\n cooldown: params.cooldown,\n expiration: params.expiration,\n })\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { Interface, ParamType } from \"@ethersproject/abi\"\nimport { enableModule } from \"services\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { ReactComponent as AddIcon } from \"../../../../assets/icons/add-icon.svg\"\nimport { makeStyles } from \"@material-ui/core\"\nimport { useRootDispatch } from \"../../../../store\"\nimport { addTransaction } from \"../../../../store/transactionBuilder\"\nimport { SafeAbi } from \"../../../../services/helpers\"\nimport { serializeTransaction } from \"../../../../store/transactionBuilder/helpers\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\n\ninterface AddCustomModuleProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n addButton: {\n marginTop: theme.spacing(2),\n },\n addTransactionButton: {\n marginTop: theme.spacing(1),\n },\n addIcon: {\n stroke: theme.palette.common.white,\n width: 20,\n height: 20,\n },\n}))\n\nexport const CustomModuleModal = ({ onSubmit, open, onClose }: AddCustomModuleProps) => {\n const { sdk, safe } = useSafeAppsSDK()\n const dispatch = useRootDispatch()\n const classes = useStyles()\n\n const [moduleAddress, setModuleAddress] = useState(\"\")\n const [isAddressValid, setAddressValid] = useState(false)\n\n const handleAddressChange = (address: string, isValid: boolean) => {\n setModuleAddress(address)\n setAddressValid(!!address.length && isValid)\n }\n\n const resetState = () => {\n if (onClose) onClose()\n setModuleAddress(\"\")\n setAddressValid(false)\n }\n\n const addModule = async () => {\n const tx = enableModule(safe.safeAddress, moduleAddress)\n\n try {\n await sdk.txs.send({ txs: [tx] })\n resetState()\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.warn(\"error adding custom module\", error)\n }\n }\n\n const addTransactionModule = () => {\n const inter = new Interface(SafeAbi)\n const func = inter.getFunction(\"enableModule\")\n const tx = {\n func,\n to: safe.safeAddress,\n params: [moduleAddress],\n id: \"add_module_\" + new Date().getTime(),\n }\n\n dispatch(addTransaction(serializeTransaction(tx)))\n resetState()\n if (onClose) onClose()\n }\n\n return (\n \n \n\n }\n onClick={addModule}\n >\n Add Module\n \n\n }\n onClick={addTransactionModule}\n variant=\"outlined\"\n >\n Add to Transaction Bundle\n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { AMBModuleParams, deployBridgeModule } from \"../../../../services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface AMBModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ntype AMBModuleParamsInput = Omit\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const AMBModuleModal = ({ open, onClose, onSubmit }: AMBModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n amb: false,\n controller: false,\n chainId: false,\n })\n const [params, setParams] = useState({\n amb: \"\",\n chainId: \"\",\n controller: \"\",\n })\n const isValid = Object.values(errors).every((x) => x)\n\n const onParamChange = (\n field: Field,\n value: AMBModuleParamsInput[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddAMBModule = async () => {\n try {\n const txs = deployBridgeModule(provider, safe.safeAddress, safe.chainId, {\n ...params,\n executor: safe.safeAddress,\n })\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"amb\", value, valid)}\n />\n \n \n onParamChange(\"controller\", value, valid)}\n />\n \n \n onParamChange(\"chainId\", value, valid)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployExitModule, ExitModuleParams } from \"../../../../services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\ninterface ExitModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ntype ExitModuleParamsInput = Omit\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n textLink: {\n cursor: \"pointer\",\n },\n}))\n\nexport const ExitModuleModal = ({ open, onClose, onSubmit }: ExitModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n tokenContract: false,\n })\n const [params, setParams] = useState({\n tokenContract: \"\",\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: ExitModuleParamsInput[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddExitModule = async () => {\n try {\n const txs = await deployExitModule(provider, safe.safeAddress, safe.chainId, {\n ...params,\n executor: safe.safeAddress,\n })\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"tokenContract\", value, valid)}\n />\n \n \n \n )\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployRolesV1Modifier, RolesModifierParams } from \"services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n networkAddresses as multisendNetworkAddresses,\n defaultAddress as defaultMultisendAddress,\n} from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/multi_send.json\"\n\ninterface RolesModifierModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RolesV1ModifierModal = ({\n open,\n onClose,\n onSubmit,\n}: RolesModifierModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n target: true,\n multisend: true,\n })\n const [params, setParams] = useState({\n target: safe.safeAddress,\n multisend: defaultMultisend(safe),\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: RolesModifierParams[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRolesModifier = async () => {\n try {\n const txs = deployRolesV1Modifier(provider, safe.safeAddress, safe.chainId, params)\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"target\", value, valid)}\n />\n \n \n onParamChange(\"multisend\", value, valid)}\n />\n \n \n \n )\n}\n\nfunction defaultMultisend(safeInfo: SafeInfo) {\n const address = (multisendNetworkAddresses as Record)[safeInfo.chainId]\n\n return address || defaultMultisendAddress\n}\n","import React, { useState } from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { deployRolesV2Modifier, RolesModifierParams } from \"services\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport {\n networkAddresses as multisendNetworkAddresses,\n defaultAddress as defaultMultisendAddress,\n} from \"@gnosis.pm/safe-deployments/dist/assets/v1.3.0/multi_send.json\"\n\ninterface RolesModifierModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RolesV2ModifierModal = ({\n open,\n onClose,\n onSubmit,\n}: RolesModifierModalProps) => {\n const classes = useStyles()\n\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n\n const [errors, setErrors] = useState>({\n target: true,\n multisend: true,\n })\n const [params, setParams] = useState({\n target: safe.safeAddress,\n multisend: defaultMultisend(safe),\n })\n\n const isValid = Object.values(errors).every((field) => field)\n\n const onParamChange = (\n field: Field,\n value: RolesModifierParams[Field],\n valid: boolean,\n ) => {\n setErrors({ ...errors, [field]: valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRolesModifier = async () => {\n try {\n const txs = deployRolesV2Modifier(provider, safe.safeAddress, safe.chainId, params)\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(error)\n }\n }\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"target\", value, valid)}\n />\n \n \n onParamChange(\"multisend\", value, valid)}\n />\n \n \n \n )\n}\n\nfunction defaultMultisend(safeInfo: SafeInfo) {\n const address = (multisendNetworkAddresses as Record)[safeInfo.chainId]\n\n return address || defaultMultisendAddress\n}\n","import React, { useEffect, useState } from \"react\"\nimport { Box, Grid, InputLabel, makeStyles, MenuItem, Select } from \"@material-ui/core\"\nimport { ParamInput } from \"../../components/ethereum/ParamInput\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ReactComponent as CheckmarkIcon } from \"../../assets/icons/checkmark.svg\"\nimport { getArbitrator, ARBITRATOR_OPTIONS } from \"../../services\"\nimport { NETWORK } from \"../../utils/networks\"\n\nexport const arbitratorOptions = {\n NO_ARBITRATOR: \"No arbitration (highest bond wins)\",\n KLEROS: \"Kleros\",\n OTHER: \"Other (custom address)\",\n}\n\n// List of chain IDs where Kleros is available.\nexport const klerosAvailability: number[] = [\n NETWORK.MAINNET,\n NETWORK.GOERLI,\n NETWORK.GNOSIS_CHAIN,\n NETWORK.POLYGON,\n]\n\ntype Option = keyof typeof arbitratorOptions\n\ninterface ArbitratorSelectProps {\n defaultAddress?: string\n defaultOption?: string\n label: string\n chainId: number\n\n onChange(arbitrator: string): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n flexWrap: \"nowrap\",\n justifyContent: \"flex-end\",\n },\n label: {\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(1),\n },\n inputContainer: {\n flexGrow: 1,\n },\n input: {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n \"& input\": {\n textAlign: \"right\",\n },\n },\n select: {\n marginBottom: -1,\n textIndent: theme.spacing(1),\n },\n itemList: {\n padding: 0,\n },\n item: {\n display: \"flex\",\n flexDirection: \"row\",\n padding: theme.spacing(1.5, 1),\n \"&:not(:last-child)\": {\n borderBottomWidth: 1,\n borderBottomStyle: \"solid\",\n borderBottomColor: theme.palette.primary.light,\n },\n \"& .show-if-selected\": {\n display: \"none\",\n },\n \"&.Mui-selected .show-if-selected\": {\n display: \"block\",\n },\n \"&.Mui-selected::after\": {\n content: '\"\"',\n right: 0,\n top: 0,\n },\n },\n dropdownContainer: {\n maxWidth: \"100%\",\n },\n dropdown: {\n borderRadius: 8,\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderTopWidth: 2,\n borderTopColor: theme.palette.primary.light,\n borderTopStyle: \"solid\",\n marginTop: -1,\n },\n}))\n\nexport const ArbitratorSelect = ({\n onChange,\n defaultOption = arbitratorOptions.NO_ARBITRATOR,\n defaultAddress = \"\",\n label,\n chainId,\n}: ArbitratorSelectProps) => {\n const classes = useStyles()\n const [option, setOption] = useState(defaultOption)\n const [arbitrator, setArbitrator] = useState(defaultAddress)\n\n const [open, setOpen] = useState(false)\n\n const handleClose = () => setOpen(false)\n const handleOpen = () => setOpen(true)\n\n const selectRef = React.useRef(null)\n\n const handleArbitratorChange = (_arbitrator: string, valid?: boolean) => {\n try {\n if (valid === true) {\n setArbitrator(_arbitrator)\n onChange(_arbitrator)\n }\n } catch (err) {\n console.warn(\"invalid arbitrator option\")\n }\n }\n\n const handleArbitratorOptionChange = (newOption: string) => {\n handleClose()\n const newOptionKey = Object.keys(arbitratorOptions).find(\n (k) => arbitratorOptions[`${k}` as Option] === newOption,\n ) as Option\n setOption(newOption)\n if (newOptionKey === \"OTHER\") {\n setArbitrator(\"\")\n onChange(\"\")\n } else {\n const newArbitrator = getArbitrator(chainId, ARBITRATOR_OPTIONS[newOptionKey])\n setArbitrator(newArbitrator)\n onChange(newArbitrator)\n }\n }\n\n useEffect(() => {\n if (selectRef.current) {\n selectRef.current.addEventListener(\"keyup\", (event) => {\n if (event.code === \"Tab\") handleOpen()\n })\n }\n }, [selectRef])\n\n return (\n
\n {label}\n \n \n value as string}\n onChange={(evt) => handleArbitratorOptionChange(evt.target.value as string)}\n >\n {Object.keys(arbitratorOptions).map((optionKey) => {\n if (!klerosAvailability.includes(chainId) && optionKey === \"KLEROS\") {\n return null\n }\n return (\n \n {arbitratorOptions[`${optionKey}` as Option]}\n \n \n \n )\n })}\n \n \n \n {option === arbitratorOptions.OTHER && (\n \n \n handleArbitratorChange(value, valid)}\n />\n \n \n )}\n
\n )\n}\n","import {\n deployAndSetUpModule,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { enableModule, getDefaultOracle } from \"services\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { buildTransaction } from \"services/helpers\"\nimport { ethers } from \"ethers\"\n\ninterface RealityModuleParams {\n executor: string\n oracle?: string\n bond: string\n templateId: string\n timeout: string\n cooldown: string\n expiration: string\n arbitrator: string\n}\n\nexport function deployRealityModule(\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n chainId: number,\n args: RealityModuleParams,\n isERC20?: boolean,\n) {\n const type: KnownContracts = isERC20\n ? KnownContracts.REALITY_ERC20\n : KnownContracts.REALITY_ETH\n const {\n timeout,\n cooldown,\n expiration,\n bond,\n templateId,\n oracle,\n executor,\n arbitrator,\n } = args\n const oracleAddress = oracle || getDefaultOracle(chainId)\n const {\n transaction: daoModuleDeploymentTx,\n expectedModuleAddress: daoModuleExpectedAddress,\n } = deployAndSetUpModule(\n type,\n {\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"uint32\",\n \"uint32\",\n \"uint32\",\n \"uint256\",\n \"uint256\",\n \"address\",\n ],\n values: [\n safeAddress,\n safeAddress,\n executor,\n oracleAddress,\n timeout,\n cooldown,\n expiration,\n bond,\n templateId,\n arbitrator,\n ],\n },\n provider,\n chainId,\n Date.now().toString(),\n )\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [daoModuleExpectedAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, daoModuleExpectedAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n return daoModuleTransactions\n}\n","import React, { useEffect, useState } from \"react\"\nimport { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Grow } from \"../../../../components/layout/Grow\"\nimport { ethers } from \"ethers\"\nimport { useRootSelector } from \"store\"\nimport { getDelayModules } from \"store/modules/selectors\"\nimport { NETWORK, NETWORKS } from \"utils/networks\"\nimport { ARBITRATOR_OPTIONS, getArbitrator, getDefaultOracle } from \"services\"\nimport { getArbitratorBondToken } from \"services/reality-eth\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { ParamInput } from \"components/ethereum/ParamInput\"\nimport { ParamType } from \"ethers/lib/utils\"\nimport { Row } from \"components/layout/Row\"\nimport { TimeSelect } from \"components/input/TimeSelect\"\nimport { ZodiacTextField } from \"zodiac-ui-components\"\nimport { arbitratorOptions, ArbitratorSelect } from \"components/input/ArbitratorSelect\"\nimport { AttachModuleForm } from \"../components/AttachModuleForm\"\nimport { ModuleType } from \"store/modules/models\"\nimport { deployRealityModule } from \"./services/moduleDeploymentOld\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nconst SECONDS_IN_DAY = 86400\n\n// TODO: delete this when the new flow is done\n\ninterface RealityModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface RealityModuleParams {\n oracle: string\n templateId: string\n timeout: string\n cooldown: string\n expiration: string\n bond: string\n arbitrator: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n}))\n\nexport const RealityModuleOldModal = ({\n open,\n onClose,\n onSubmit,\n}: RealityModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n const delayModules = useRootSelector(getDelayModules)\n const [isERC20, setERC20] = useState(false)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const [bondToken, setBondToken] = useState(\n NETWORKS[safe.chainId as NETWORK].nativeAsset,\n )\n const [params, setParams] = useState({\n oracle: getDefaultOracle(safe.chainId),\n templateId: \"\",\n timeout: (SECONDS_IN_DAY * 2).toString(),\n cooldown: (SECONDS_IN_DAY * 2).toString(),\n expiration: (SECONDS_IN_DAY * 7).toString(),\n bond: \"0.1\",\n arbitrator: getArbitrator(safe.chainId, ARBITRATOR_OPTIONS.NO_ARBITRATOR),\n })\n const [validFields, setValidFields] = useState({\n oracle: !!params.oracle,\n templateId: !!params.templateId,\n bond: !!params.bond,\n })\n const isValid = Object.values(validFields).every((field) => field)\n\n useEffect(() => {\n if (params.oracle && ethers.utils.isAddress(params.oracle)) {\n getArbitratorBondToken(provider, params.oracle, safe.chainId)\n .then((response) => {\n setBondToken(response.coin)\n setERC20(response.isERC20)\n })\n .catch(() => {\n setBondToken(NETWORKS[safe.chainId as NETWORK].nativeAsset)\n setERC20(false)\n })\n }\n }, [params.oracle, safe.chainId, provider])\n\n const onParamChange = (\n field: Field,\n value: RealityModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n if (valid !== undefined)\n setValidFields({\n ...validFields,\n [field]: valid,\n })\n }\n\n const handleAddRealityModule = async () => {\n try {\n const minimumBond = ethers.utils.parseUnits(params.bond, bondToken.decimals)\n const args = {\n ...params,\n executor: delayModule || safe.safeAddress,\n bond: minimumBond.toString(),\n }\n const txs = await deployRealityModule(\n provider,\n safe.safeAddress,\n safe.chainId,\n args,\n isERC20,\n )\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n }\n\n const handleBondChange = (event: React.ChangeEvent) => {\n const value = event.target.value || \"0\"\n const leftZero = value.startsWith(\"0\") && value.length > 1\n let bond = leftZero ? value.substr(1) : value\n bond = bond.startsWith(\".\") ? \"0\" + bond : bond\n\n try {\n ethers.utils.parseUnits(bond, bondToken.decimals)\n onParamChange(\"bond\", bond)\n } catch (error) {\n console.warn(\"invalid bond\", value, error)\n }\n }\n\n const description = (\n \n This will add a timedelay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed\n will be 48 hours).\n \n )\n\n return (\n \n Parameters\n\n \n \n onParamChange(\"oracle\", value, valid)}\n />\n \n \n \n TemplateId\n \n \n Get a template here\n \n \n onParamChange(\"templateId\", value, valid)}\n />\n \n \n onParamChange(\"timeout\", value)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n \n \n onParamChange(\"arbitrator\", value)}\n chainId={safe.chainId}\n />\n \n \n {delayModules.length ? (\n <>\n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n ) : null}\n \n )\n}\n","import { ethers } from \"ethers\"\nimport { enableModule, getDefaultOracle, TxWitMeta } from \"../../../../../services\"\nimport {\n deployAndSetUpModule,\n getModuleInstance,\n KnownContracts,\n} from \"@gnosis.pm/zodiac\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { buildTransaction } from \"services/helpers\"\nimport { Data as OracleTemplateData } from \"../sections/Oracle/components/OracleTemplate\"\nimport DETERMINISTIC_DEPLOYMENT_HELPER_META from \"../../../../../contracts/DeterministicDeploymentHelper.json\"\nexport interface RealityModuleParams {\n executor: string\n oracle?: string\n bond: string\n timeout: string\n cooldown: string\n expiration: string\n arbitrator: string\n}\n\n// TODO: Add support for Reality.ETH oracles that is not known (for instance deployed by the caller)\n// using `deployAndSetUpCustomModule` instead of `deployAndSetUpModule`\nexport async function deployRealityModule(\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n deterministicDeploymentHelperAddress: string,\n chainId: number,\n args: RealityModuleParams,\n template: OracleTemplateData,\n isERC20?: boolean,\n): Promise {\n const oracleType: KnownContracts = isERC20\n ? KnownContracts.REALITY_ERC20\n : KnownContracts.REALITY_ETH\n const { timeout, cooldown, expiration, bond, oracle, executor, arbitrator } = args\n const oracleAddress =\n oracle != null && ethers.utils.isAddress(oracle) ? oracle : getDefaultOracle(chainId)\n if (oracleAddress == null) {\n throw new Error(\n `No oracle address provided and no default oracle available for this chain (chainID: ${chainId})`,\n )\n }\n const saltNonce = Date.now().toString()\n const initData = {\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"uint32\",\n \"uint32\",\n \"uint32\",\n \"uint256\",\n \"uint256\",\n \"address\",\n ],\n values: [\n deterministicDeploymentHelperAddress,\n safeAddress,\n executor,\n oracleAddress,\n timeout,\n cooldown,\n expiration,\n bond,\n 0, // templateId - must use 0 here, will be set up later\n arbitrator,\n ],\n }\n\n const { transaction: daoModuleDeploymentTx, expectedModuleAddress } =\n deployAndSetUpModule(oracleType, initData, provider, chainId, saltNonce)\n\n const daoModuleTransactions: BaseTransaction[] = [\n {\n ...daoModuleDeploymentTx,\n value: daoModuleDeploymentTx.value.toString(),\n },\n ]\n\n if (executor !== safeAddress) {\n const delayModule = getModuleInstance(KnownContracts.DELAY, executor, provider)\n const addModuleTransaction = buildTransaction(\n delayModule.interface,\n delayModule.address,\n \"enableModule\",\n [expectedModuleAddress],\n )\n\n daoModuleTransactions.push(addModuleTransaction)\n } else {\n const enableDaoModuleTransaction = enableModule(safeAddress, expectedModuleAddress)\n daoModuleTransactions.push(enableDaoModuleTransaction)\n }\n\n const deterministicSetupHelper = new ethers.Contract(\n deterministicDeploymentHelperAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_META.abi,\n provider,\n )\n\n const populatedTemplateConfigurationTx =\n await deterministicSetupHelper.populateTransaction.createTemplateAndChangeOwner(\n expectedModuleAddress,\n oracleAddress,\n JSON.stringify({\n type: \"bool\",\n title: template.templateQuestion,\n category: \"DAO proposal\",\n lang: \"en\",\n }),\n safeAddress,\n )\n\n if (populatedTemplateConfigurationTx.to == null) {\n throw new Error(\"Missing to address\")\n }\n if (populatedTemplateConfigurationTx.data == null) {\n throw new Error(\"Missing data\")\n }\n\n daoModuleTransactions.push({\n to: populatedTemplateConfigurationTx.to,\n data: populatedTemplateConfigurationTx.data,\n value: \"0\",\n })\n\n return {\n txs: daoModuleTransactions,\n meta: { expectedModuleAddress },\n }\n}\n","import * as IPFS from \"ipfs-core\"\n\nlet node: IPFS.IPFS\nconst textDecoder = new TextDecoder()\n\nconst getNode = async () => {\n if (node == null) {\n node = await IPFS.create()\n }\n return node\n}\nexport const getJsonData = async (path: string) => {\n const node = await getNode()\n\n if (path.startsWith(\"ipns\")) {\n path = await node.resolve(path, { recursive: true })\n }\n\n path = path.replace(\"ipfs://\", \"\")\n\n const chunks: string[] = []\n for await (const chunk of node.cat(path)) {\n chunks.push(textDecoder.decode(chunk))\n }\n const rawContent = chunks.join(\"\")\n return JSON.parse(rawContent)\n}\n\nexport const add = async (content: any) => {\n const node = await getNode()\n const { cid } = await node.add(content)\n return cid\n}\n","import { ethers } from \"ethers\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\n\n/**\n * This only works for domains using a resolver that conforms to the `abiPublicResolver` (like the PublicResolver).\n */\n\nconst ensRegistry = \"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e\" // ENS: Registry with Fallback (singleton same address on different chains)\nconst ensImplementation = \"0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85\" // ENS: Base Registrar Implementation (singleton same address on different chains)\n\nconst abiPublicResolver = [\n \"function setText(bytes32 node, string calldata key, string calldata value) external\",\n \"function text(bytes32 node, string calldata key) external view returns (string memory)\",\n]\n\nconst abiRegistry = [\n \"function owner(bytes32 node) external view returns (address)\",\n \"function resolver(bytes32 node) external view returns (address)\",\n]\n\nconst abiImplementation = [\n \"function ownerOf(uint256 tokenId) public view returns (address owner)\",\n]\n\nexport const setTextRecordTx = async (\n provider: ethers.providers.Provider,\n ensName: string,\n key: string,\n content: string,\n): Promise => {\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const nameHash = ethers.utils.namehash(ensName)\n const ensResolver = await ensRegistryContract.resolver(nameHash)\n const ensResolverContract = new ethers.Contract(\n ensResolver,\n abiPublicResolver,\n provider,\n )\n const populatedTx = await ensResolverContract.populateTransaction.setText(\n nameHash,\n key,\n content,\n )\n if (populatedTx.to == null) {\n throw new Error(\"Missing to address\")\n }\n if (populatedTx.data == null) {\n throw new Error(\"Missing data\")\n }\n\n return {\n to: populatedTx.to,\n data: populatedTx.data,\n value: \"0\",\n }\n}\n\n// the owner of the NFT\nexport const checkIfIsOwner = async (\n provider: ethers.providers.Provider,\n ensName: string,\n address: string,\n) => {\n const BigNumber = ethers.BigNumber\n const name = ensName.split(\".\")[0] // only supports toplevel\n const labelHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(name))\n const tokenId = BigNumber.from(labelHash).toString()\n const ensImplementationContract = new ethers.Contract(\n ensImplementation,\n abiImplementation,\n provider,\n )\n const nftOwner = await ensImplementationContract.ownerOf(tokenId)\n return ethers.utils.getAddress(nftOwner) === ethers.utils.getAddress(address)\n}\n\nexport const getEnsTextRecord = async (\n ensName: string,\n recordId: string,\n provider: ethers.providers.Provider,\n) => {\n const nameHash = ethers.utils.namehash(ensName)\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const ensResolverAddress = await ensRegistryContract.resolver(nameHash)\n const ensResolverContract = new ethers.Contract(ensResolverAddress, abiPublicResolver, provider)\n const record = ensResolverContract.functions.text(nameHash, recordId)\n return record\n}\n\nexport const checkIfIsController = async (\n provider: ethers.providers.Provider,\n ensName: string,\n address: string,\n) => {\n const ensRegistryContract = new ethers.Contract(ensRegistry, abiRegistry, provider)\n const nameHash = ethers.utils.namehash(ensName)\n const owner = await ensRegistryContract.owner(nameHash)\n\n return ethers.utils.getAddress(address) === ethers.utils.getAddress(owner)\n}\n","import snapshot from \"@snapshot-labs/snapshot.js\"\nimport * as R from \"ramda\"\nimport { NETWORK } from \"utils/networks\"\n\nconst SNAPSHOT_HUB = \"https://hub.snapshot.org\"\nconst SNAPSHOT_HUB_GOERLI = \"https://testnet.hub.snapshot.org\"\nconst SNAPSHOT_SPACE = \"https://snapshot.org\"\nconst SNAPSHOT_SPACE_GOERLI = \"https://testnet.snapshot.org\"\n\n// Returns snapshot space settings, or undefined if no space was found for the ENS name.\nexport const getSnapshotSpaceSettings = async (ensName: string, chainId: number) => {\n await updateSnapshotCache(ensName, chainId) // make sure that the returned snapshot space settings is the newest version\n const res = await fetch(`${getHubUrl(chainId)}/api/spaces/${ensName}`)\n if (res.ok) {\n try {\n return await res.json().then((res) => {\n // Remove flagged, verified, hibernated, and turbo properties from res, as they are not part of the space config, but rater extra info from the server.\n const { flagged, verified, hibernated, turbo, ...filteredRes } = res\n return filteredRes\n })\n } catch (error) {\n return undefined // there is not snapshot space for this ENS\n }\n } else {\n throw res\n }\n}\n\nexport const validateSchema = (spaceSettings: any) =>\n snapshot.utils.validateSchema(snapshot.schemas.space, spaceSettings)\n\nexport const updateSnapshotCache = (ensName: string, chainId: number) =>\n fetch(`${getHubUrl(chainId)}/api/spaces/${ensName}/poke`)\n\nexport const verifyNewSnapshotSettings = (originalSettings: any, newSettings: any) =>\n R.and(\n // check that there are no unintended changes to the new Snapshot Space settings\n R.equals(\n R.omit([\"plugins\", \"safeSnap\"], originalSettings),\n R.omit([\"plugins\", \"safeSnap\"], newSettings),\n ),\n // validate the schema\n // we must be strict here, if not a truthy error value can be returned\n validateSchema(newSettings) === true,\n )\n\nconst getHubUrl = (chainId: number) =>\n chainId === NETWORK.GOERLI ? SNAPSHOT_HUB_GOERLI : SNAPSHOT_HUB\n\nexport const getSnapshotSpaceUrl = (chainId: number, ensName: string) =>\n (chainId === NETWORK.GOERLI ? SNAPSHOT_SPACE_GOERLI : SNAPSHOT_SPACE) + `/#/${ensName}`\n","import { NETWORK } from \"utils/networks\"\nimport { MonitoringSectionData } from \"../sections/Monitoring\"\n\nconst BACKEND_API_URL = process.env.REACT_APP_BACKEND_API_URL\n\nif (BACKEND_API_URL == null) {\n throw new Error(\"BACKEND_API_URL not set\")\n}\n\ninterface MonitoringCredentials {\n apiKey: string\n apiSecret: string\n}\n\ninterface NotificationChannels {\n channel: string\n config: any\n}\ninterface RequestType extends MonitoringCredentials {\n network: string\n realityModuleAddress: string\n oracleAddress: string\n notificationChannels: NotificationChannels[]\n}\n\nexport const setUpMonitoring = async (\n chainId: NETWORK,\n realityModuleAddress: string,\n oracleAddress: string,\n data: MonitoringSectionData,\n) => {\n console.log()\n if ((data.apiKey ?? \"\") === \"\" || (data.secretKey ?? \"\") === \"\") {\n throw new Error(\n \"API keys for monitoring service missing. Monitoring will NOT be set up.\",\n )\n }\n if (\n (data.discordKey ?? \"\") === \"\" &&\n (data.slackKey ?? \"\") === \"\" &&\n data.email.length === 0 &&\n (data.telegram.botToken ?? \"\") === \"\" &&\n (data.telegram.chatId ?? \"\")\n ) {\n throw new Error(\n \"No notification channel(s) specified. Monitoring will NOT be set up.\",\n )\n }\n\n const notificationChannels: NotificationChannels[] = []\n\n if (data.email.length > 0) {\n notificationChannels.push({\n channel: \"email\",\n config: {\n emails: data.email,\n },\n })\n }\n\n if (data.discordKey.length > 0) {\n notificationChannels.push({\n channel: \"discord\",\n config: {\n url: data.discordKey,\n },\n })\n }\n\n if (data.slackKey.length > 0) {\n notificationChannels.push({\n channel: \"slack\",\n config: {\n url: data.slackKey,\n },\n })\n }\n\n if (data.telegram.botToken.length > 0) {\n notificationChannels.push({\n channel: \"telegram\",\n config: data.telegram,\n })\n }\n\n const requestBody: RequestType = {\n apiKey: data.apiKey,\n apiSecret: data.secretKey,\n network: networkToOzDefenderNetworkName(chainId),\n oracleAddress,\n realityModuleAddress,\n notificationChannels,\n }\n\n return fetch(BACKEND_API_URL + \"/monitoring/notification\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(requestBody),\n })\n}\n\nexport const validationCredentials = async (query: MonitoringCredentials) => {\n const { apiKey, apiSecret } = query\n return fetch(\n `${BACKEND_API_URL}/monitoring/validation?apiKey=${apiKey}&apiSecret=${apiSecret}`,\n {\n method: \"GET\",\n mode: \"cors\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n },\n )\n}\n\nconst networkToOzDefenderNetworkName = (network: NETWORK) => {\n switch (network) {\n case NETWORK.MAINNET:\n return \"mainnet\"\n case NETWORK.GOERLI:\n return \"goerli\"\n case NETWORK.OPTIMISM:\n return \"optimism\"\n case NETWORK.BSC:\n return \"bsc\"\n case NETWORK.GNOSIS_CHAIN:\n return \"xdai\"\n case NETWORK.POLYGON:\n return \"matic\"\n case NETWORK.ARBITRUM:\n return \"arbitrum\"\n case NETWORK.AVALANCHE:\n return \"avalanche\"\n default:\n throw new Error(\"Unsupported network\")\n }\n}\n","const BACKEND_API_URL = process.env.REACT_APP_BACKEND_API_URL\n\nif (BACKEND_API_URL == null) {\n throw new Error(\"BACKEND_API_URL not set\")\n}\n\ninterface RequestType {\n snapshotSpaceEnsName: string\n snapshotSpaceSettings: any\n chainId: number\n}\n\ninterface Responds {\n cidV0: string\n}\n\nexport const pinSnapshotSpace: (request: RequestType) => Promise = async (\n request,\n) => {\n const res = await fetch(BACKEND_API_URL + \"/ipfs-pinning/snapshot-settings\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(request),\n })\n return res.json()\n}\n","var _path;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgCheckmarkNofill = function SvgCheckmarkNofill(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 15,\n height: 12,\n viewBox: \"0 0 15 12\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M5.21872 9.38208L1.96402 6.12739L0.549805 7.5416L4.5498 11.5416C4.74379 11.7356 5.00896 11.8414 5.2832 11.8341C5.55744 11.8269 5.81668 11.7074 6.00021 11.5035L15.0002 1.50346L13.5136 0.165527L5.21872 9.38208Z\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgCheckmarkNofill, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/checkmark-nofill.855acc91.svg\";\nexport { ForwardRef as ReactComponent };","import { ethers } from \"ethers\"\nimport { getArbitrator, TxWitMeta as TxsWitMeta } from \"../../../../../services\"\nimport { NETWORK, NETWORKS } from \"../../../../../utils/networks\"\nimport * as ipfs from \"../../../../../services/ipfs\"\nimport * as R from \"ramda\"\nimport { setTextRecordTx } from \"services/ens\"\nimport { SetupData } from \"..\"\nimport SafeAppsSDK, { SafeInfo } from \"@gnosis.pm/safe-apps-sdk\"\nimport * as snapshot from \"../../../../../services/snapshot\"\nimport { deployRealityModule, RealityModuleParams } from \"./moduleDeployment\"\nimport { setUpMonitoring } from \"./monitoring\"\nimport { pinSnapshotSpace } from \"./snapshot-space-pinning\"\n\nconst MULTI_SEND_CONTRACT = process.env.REACT_APP_MULTI_SEND_CONTRACT\nexport const DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS =\n \"0x0961F418E0B6efaA073004989EF1B2fd1bc4a41c\" // needs to be deployed on all networks supported by the Reality Module\n\n/**\n * Sets up the Reality Module.\n *\n * @notice The input variables are not checked for validity here, as this happens in the UI.\n */\nexport const setup = async (\n provider: ethers.providers.JsonRpcProvider,\n safeSdk: SafeAppsSDK,\n safeInfo: SafeInfo,\n executorAddress: string,\n setupData: SetupData,\n statusCallback: (currentStatus: string, error?: Error) => void,\n) => {\n statusCallback(\"Setting up Reality Module deployment transactions\")\n const deploymentRealityModuleTxsMm = await deployRealityModuleTxs(\n provider,\n safeInfo.chainId,\n safeInfo.safeAddress,\n executorAddress,\n setupData,\n ).catch((e) => {\n statusCallback(\"Error while setting up Reality Module deployment transactions\", e)\n })\n\n if (deploymentRealityModuleTxsMm == null) {\n throw new Error(\n \"The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE. Should be handled in the 'statusCallback' function.\",\n )\n }\n\n const realityModuleAddress = deploymentRealityModuleTxsMm.meta?.expectedModuleAddress\n if (realityModuleAddress == null) {\n const error = new Error(\"Unable to calculate the Reality Module future address.\")\n statusCallback(error.message, error)\n }\n\n if (realityModuleAddress == null) {\n throw new Error(\n \"The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.\",\n )\n }\n\n statusCallback(\n \"Setting up transaction for adding the new snapshot space to the ENS record\",\n )\n const addSafeToSnapshotTxsMm = await addSafeSnapToSnapshotSpaceTxs(\n provider,\n setupData.proposal.ensName,\n realityModuleAddress,\n safeInfo.chainId,\n ).catch((e) => {\n statusCallback(\n \"Error when setting up transactions to add SafeSnap to the Snapshot Space\",\n e,\n )\n })\n\n if (deploymentRealityModuleTxsMm == null || addSafeToSnapshotTxsMm == null) {\n throw new Error(\n \"The creation of transactions failed. IT SHOULD NOT BE POSSIBLE TO REACH THIS STATE.\",\n )\n }\n\n const txs = [...deploymentRealityModuleTxsMm.txs, ...addSafeToSnapshotTxsMm.txs]\n\n statusCallback(\"Setting up monitoring with OZ Defender\")\n await setUpMonitoring(\n safeInfo.chainId as NETWORK,\n realityModuleAddress,\n setupData.oracle.instanceData.instanceAddress,\n setupData.monitoring,\n ).catch((e) => {\n statusCallback(\"Error when setting up monitoring.\", e)\n })\n\n statusCallback(\"Proposing transactions to the Safe\")\n await safeSdk.txs.send({ txs }).catch((e) => {\n statusCallback(\"Error when proposing transactions to the Safe\", e)\n })\n\n // await pokeSnapshotAPI(setupData.proposal.ensName); // TODO: if the transactions does not happen immediately, we need to poke the snapshot API in some other way later when the transactions is executed to make sure the new space settings is picked up.\n}\n\n/**\n * Generate the transactions required to deploy a Reality Module\n *\n * Can throw if inputs are invalided.\n *\n * @param chainId\n * @param safeAddress\n * @param params Reality Module parameters\n * @returns transaction array\n */\nconst deployRealityModuleTxs = async (\n provider: ethers.providers.JsonRpcProvider,\n chainId: number,\n safeAddress: string,\n executorAddress: string,\n setupData: SetupData,\n): Promise => {\n const bondToken = NETWORKS[chainId as NETWORK].nativeAsset\n const moduleDeploymentParameters: RealityModuleParams = {\n executor: executorAddress,\n bond: ethers.utils\n .parseUnits(setupData.oracle.bondData.bond.toString(), bondToken.decimals)\n .toString(),\n timeout: setupData.oracle.delayData.timeout.toString(),\n cooldown: setupData.oracle.delayData.cooldown.toString(),\n expiration: setupData.oracle.delayData.expiration.toString(),\n arbitrator: getArbitrator(chainId, setupData.oracle.arbitratorData.arbitratorOption),\n oracle: setupData.oracle.instanceData.instanceAddress,\n }\n return await deployRealityModule(\n provider,\n safeAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n chainId,\n moduleDeploymentParameters,\n setupData.oracle.templateData,\n false,\n )\n}\n\nexport const addSafeSnapToSettings = (\n originalSpaceSettings: any,\n chainId: number,\n realityModuleAddress: string,\n) =>\n R.assocPath(\n [\"plugins\", \"safeSnap\"],\n {\n safes: [\n {\n network: chainId,\n realityAddress: realityModuleAddress,\n multisend: MULTI_SEND_CONTRACT,\n },\n ],\n },\n originalSpaceSettings,\n )\n\nexport const addSafeSnapToSnapshotSpaceTxs = async (\n provider: ethers.providers.JsonRpcProvider,\n ensName: string,\n realityModuleAddress: string,\n chainId: number,\n): Promise => {\n // 1. Get the current Space setting file. from IPFS directly or from\n const originalSpaceSettings = await snapshot.getSnapshotSpaceSettings(ensName, chainId)\n\n // 2. Update the Space setting file, by adding the SafeSnap plugin.\n const newSpaceSettings = addSafeSnapToSettings(\n originalSpaceSettings,\n chainId,\n realityModuleAddress,\n )\n // validate the new schema\n if (!snapshot.verifyNewSnapshotSettings(originalSpaceSettings, newSpaceSettings)) {\n throw new Error(\"The new settings file is changed in unexpected ways\")\n }\n\n // 3. Deploy the modified settings file to IPFS.\n const cidV0Locale = (await ipfs.add(JSON.stringify(newSpaceSettings))).toV0().toString()\n // 4. Pin the new file\n let cidV0FromPinning = \"\"\n try {\n const { cidV0 } = await pinSnapshotSpace({\n snapshotSpaceEnsName: ensName,\n snapshotSpaceSettings: newSpaceSettings,\n chainId,\n })\n cidV0FromPinning = cidV0\n } catch (e) {\n throw new Error(\n \"Failed to pin the new snapshot space settings file. Error from backend: \" + e,\n )\n }\n\n if (cidV0FromPinning === \"\" || cidV0FromPinning == null) {\n throw new Error(\n \"Communication with the backend pinning service failed. No CID was returned.\",\n )\n }\n\n if (cidV0Locale != null && cidV0Locale !== cidV0FromPinning) {\n throw new Error(\n `The CID from the locale browser node (${cidV0Locale}) does not correspond the CID from the pinning service (${cidV0FromPinning})`,\n )\n }\n\n // 5. Sett the hash of the new setting file in the ENS snapshot record.\n const setEnsRecordTx = await setTextRecordTx(\n provider,\n ensName,\n \"snapshot\",\n `ipfs://${cidV0Locale}`,\n )\n\n return { txs: [setEnsRecordTx] }\n}\n","import React from \"react\"\nimport {\n Box,\n Grid,\n makeStyles,\n MenuItem,\n Select,\n SelectProps,\n Tooltip,\n Typography,\n} from \"@material-ui/core\"\nimport { colors } from \"zodiac-ui-components\"\nimport HelpOutline from \"@material-ui/icons/HelpOutline\"\nimport * as R from \"ramda\"\n\nconst useStyles = makeStyles(() => ({\n label: {\n marginBottom: 4,\n },\n select: {\n border: `1px solid ${colors.tan[300]}`,\n },\n selectContainer: {\n padding: 2,\n boxSizing: \"border-box\",\n border: `1px solid ${colors.tan[300]}`,\n },\n icon: {\n fontSize: \"1rem\",\n },\n}))\n\ninterface DropdownProps extends SelectProps {\n label?: string\n options: { label: string; value: string | number }[]\n tooltipMsg?: string\n}\n\nexport const Dropdown: React.FC = (props) => {\n const classes = useStyles()\n\n return (\n \n {props.label && (\n \n \n {props.label}\n \n {props.tooltipMsg && (\n \n \n \n \n \n )}\n \n )}\n\n \n \n \n \n )\n}\n","import { Grid, makeStyles, Typography, Tooltip } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React from \"react\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { HelpOutline } from \"@material-ui/icons\"\nimport { InputPartProps } from \"../..\"\n\nexport const getDefaultTemplateQuestion = (ensName: string) =>\n `Did the Snapshot proposal with the id %s in the ${ensName} space pass the execution of the array of Module transactions that have the hash 0x%s and does it meet the requirements of the document referenced in the dao requirements record at ${ensName}? The hash is the keccak of the concatenation of the individual EIP-712 hashes of the Module transactions. If this question was asked before the corresponding Snapshot proposal was resolved, it should ALWAYS be resolved to INVALID!`\n\nconst TEMPLATE_QUESTION_HELP = `Provide a question. This must include two %s placeholders.\nThe first placeholder is for the id of the proposal (e.g., an IPFS hash).\nThe second is the hash of the concatenation of the EIP-712 transaction hashes.`\n\nconst ORACLE_TEMPLATE_OPTIONS = [\n { label: \"Zodiac Reality Module (default)\", value: \"default\" },\n { label: \"Custom\", value: \"custom\" },\n]\n\nconst ORACLE_LANGUAGE = [{ label: \"English\", value: \"english\" }]\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n textFieldSmall: {\n \"& .MuiFormLabel-root\": {\n fontSize: 12,\n },\n },\n select: {\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n },\n paperTemplateContainer: {\n marginTop: 4,\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n templateQuestion: {\n fontFamily: \"Roboto Mono\",\n \"& .MuiInputBase-root\": {\n border: \"none\",\n fontSize: \"0.85rem\",\n },\n },\n input: {\n \"& .MuiInputBase-root\": {\n padding: \"9px 8px\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n button: {\n width: \"100%\",\n padding: \"4px 15px\",\n },\n buttonContainer: {\n marginTop: 8,\n cursor: \"pointer\",\n },\n icon: {\n color: colors.tan[1000],\n fontSize: \"1rem\",\n marginTop: 3,\n },\n text: {\n fontSize: \"0.75rem\",\n },\n tooltipIcon: {\n fontSize: \"1rem\",\n },\n}))\n\nexport type Data = {\n templateType: \"default\" | \"custom\"\n language: \"english\"\n category: \"DAO proposal\"\n templateQuestion: string\n}\n\ninterface OracleTemplateProps extends InputPartProps {\n ensName: string\n}\n\nexport const OracleTemplate: React.FC = ({\n data,\n setData,\n ensName,\n}) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const setTemplateType = (templateType: \"default\" | \"custom\") => {\n if (templateType === \"default\") {\n setData({\n ...data,\n templateQuestion: getDefaultTemplateQuestion(ensName),\n templateType: templateType,\n })\n } else {\n setData({ ...data, templateQuestion: \"\", templateType: templateType })\n }\n }\n\n return (\n \n \n \n \n \n Oracle Template\n \n \n \n \n The oracle template creates an appropriate question based on the data of the\n proposal. We highly recommend using the default Zodiac Reality Module\n template\n \n \n \n \n \n \n \n \n setTemplateType(evt.target.value as \"default\" | \"custom\")\n }\n label=\"Select template:\"\n tooltipMsg=\"The Zodiac Reality Module type has defaults set for connecting the Reality Module to Safesnap. If you need a more specific setup, use the ‘Custom’ type.\"\n />\n \n \n set(\"language\")(target.value as string)}\n />\n \n <>\n \n \n Template question preview:\n\n \n \n \n \n\n \n \n set(\"templateQuestion\")(target.value as string)\n }\n multiline\n minRows={5}\n disabled={get(\"templateType\") === \"default\"}\n placeholder={\n get(\"templateType\") === \"default\"\n ? getDefaultTemplateQuestion(ensName)\n : TEMPLATE_QUESTION_HELP\n }\n />\n \n \n \n \n \n \n )\n}\n\nexport default OracleTemplate\n","import { useState } from \"react\"\nimport { validationCredentials } from \"../service/monitoring\"\n\nexport const useMonitoringValidation = () => {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState()\n\n const execute = async (apiKey: string, apiSecret: string) => {\n setLoading(true)\n setError(undefined)\n try {\n await validationCredentials({\n apiKey,\n apiSecret,\n }).then((res) => {\n setLoading(false)\n if (res.status === 200) {\n return setError(false)\n }\n setError(true)\n })\n } catch {\n setLoading(false)\n }\n }\n\n return { loading, error, execute }\n}\n","import React, { useEffect, useState, useCallback, useMemo } from \"react\"\nimport {\n Box,\n Grid,\n IconButton,\n Link,\n makeStyles,\n Switch,\n Typography,\n withStyles,\n} from \"@material-ui/core\"\nimport debounce from \"lodash.debounce\"\nimport { ethers } from \"ethers\"\nimport { NETWORK, NETWORKS } from \"utils/networks\"\nimport { getDefaultOracle, getKlerosAddress } from \"services\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\nimport { TimeSelect } from \"components/input/TimeSelect\"\nimport { colors, ZodiacTextField } from \"zodiac-ui-components\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { deployRealityModule } from \"../RealityModule/service/moduleDeployment\"\nimport {\n addSafeSnapToSnapshotSpaceTxs,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n} from \"../RealityModule/service/setupService\"\nimport {\n Data as TemplateData,\n getDefaultTemplateQuestion,\n} from \"../RealityModule/sections/Oracle/components/OracleTemplate\"\nimport * as snapshot from \"services/snapshot\"\nimport { checkIfIsController, getEnsTextRecord } from \"services/ens\"\nimport { Icon, Loader } from \"@gnosis.pm/safe-react-components\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport WarningOutlinedIcon from \"@material-ui/icons/WarningOutlined\"\nimport { MonitoringSectionData } from \"../RealityModule/sections/Monitoring\"\nimport { setUpMonitoring } from \"../RealityModule/service/monitoring\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport { ReactComponent as CheckmarkIcon } from \"../../../../assets/icons/checkmark-nofill.svg\"\nimport { useMonitoringValidation } from \"../RealityModule/hooks/useMonitoringValidation\"\n\nconst SECONDS_IN_DAY = 86400\n\ninterface RealityModuleModalProps {\n open: boolean\n\n onClose?(): void\n\n onSubmit?(): void\n}\n\ninterface RealityModuleParams {\n snapshotEns: string\n timeout: string\n cooldown: string\n expiration: string\n bond: string\n}\nconst useStyles = makeStyles((theme) => ({\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"20px\",\n },\n warningIcon: {\n fill: \"rgba(230, 230, 54, 1)\",\n width: \"20px\",\n },\n fields: {\n marginBottom: theme.spacing(1),\n },\n loadMessage: {\n textAlign: \"center\",\n },\n loadingContainer: {\n marginRight: 4,\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 14,\n width: 14,\n border: `1px solid ${colors.tan[300]}`,\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `yellow !important`,\n fill: `yellow !important`,\n opacity: \"100% !important\",\n },\n addSpinner: {\n color: `white !important`,\n fill: `white !important`,\n opacity: \"100% !important\",\n },\n detailsContainer: {\n width: \"95%\",\n },\n messageContainer: {\n width: \"85%\",\n fill: \"rgba(244, 67, 54, 1)\",\n },\n errorMessageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n warningMessageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n color: \"rgba(230, 230, 54, 1)\",\n },\n errorMessage: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n fontWeight: \"bolder\",\n },\n warningMessage: {\n fontSize: 12,\n color: \"rgba(230, 230, 54, 1)\",\n },\n linkStyle: {\n color: \"rgba(190, 190, 120, 1)\",\n },\n flexRow: {\n display: \"flex\",\n flexDirection: \"row\",\n },\n}))\n\nconst CustomSwitch = withStyles({\n switchBase: {\n \"&.Mui-checked\": { color: \"white\" },\n },\n colorSecondary: {\n \"&.Mui-checked + .MuiSwitch-track\": {\n backgroundColor: \"yellow\",\n },\n },\n track: {\n backgroundColor: \"black\",\n },\n})(Switch)\n\nconst PropStatus: React.FC<{\n status: \"error\" | \"warning\" | null\n message: string | null\n link?: string\n}> = ({ status, message, link }) => {\n const classes = useStyles()\n\n return (\n status && (\n \n \n {status === \"error\" && }\n {status === \"warning\" && (\n \n )}\n \n \n \n \n \n {message}\n \n \n {link ? (\n \n \n Details\n \n \n ) : (\n \n )}\n \n \n \n )\n )\n}\n\nexport const KlerosRealityModuleModal = ({\n open,\n onClose,\n onSubmit,\n}: RealityModuleModalProps) => {\n const classes = useStyles()\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n // hack to resolve mainnet ENS\n const mainnetProvider = useMemo(\n () => new ethers.providers.InfuraProvider(1, process.env.REACT_APP_INFURA_ID),\n [],\n )\n const goerliProvider = useMemo(\n () => new ethers.providers.InfuraProvider(5, process.env.REACT_APP_INFURA_ID),\n [],\n )\n\n const bondToken = NETWORKS[safe.chainId as NETWORK].nativeAsset\n const [params, setParams] = useState({\n snapshotEns: \"\",\n timeout: (SECONDS_IN_DAY * 2).toString(),\n cooldown: (SECONDS_IN_DAY * 2).toString(),\n expiration: (SECONDS_IN_DAY * 7).toString(),\n bond: \"0.1\",\n })\n const [loadingEns, setLoadingEns] = useState(false)\n const [loadedEns, setLoadedEns] = useState(false)\n const [validEns, setValidEns] = useState(false)\n const [daorequirements, setDaorequirements] = useState(\"\")\n\n const [isController, setIsController] = useState(false)\n const [isSafesnapInstalled, setIsSafesnapInstalled] = useState(false)\n const validSnapshot =\n !!params.snapshotEns &&\n params.snapshotEns.includes(\".eth\") &&\n !loadingEns &&\n loadedEns &&\n validEns\n\n const [validFields, setValidFields] = useState({\n snapshotEns: validSnapshot,\n bond: !!params.bond,\n })\n\n const [openMonitoring, setOpenMonitoring] = useState(false)\n const [apiKey, setApiKey] = useState(\"\")\n const [apiSecret, setApiSecret] = useState(\"\")\n const [validatedCredentials, setValidatedCredentials] = useState(false)\n\n const [currentEmail, setCurrentEmail] = useState(\"\")\n const [emails, setEmails] = useState([])\n const [discordKey, setDiscordKey] = useState(\"\")\n const [telegramBotToken, setTelegramBotToken] = useState(\"\")\n const [telegramChatId, setTelegramChatId] = useState(\"\")\n\n const [step, setStep] = useState<\"form\" | \"confirm\">(\"form\")\n\n const isValid = Object.values(validFields).every((field) => field)\n const emailIsValid =\n /^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$/.test(currentEmail) && !emails.includes(currentEmail)\n\n const canConfirm =\n isValid &&\n (!openMonitoring ||\n (apiKey !== undefined &&\n apiSecret !== undefined &&\n // we want to force the user to, at least, pass an email address\n // because the other notification systems could break and are hard to validate\n // if that wasn't a concern, you could pass:\n // (emails.length > 0 || discordKey || (telegramBotToken && telegramChatId))))\n emails.length > 0))\n\n const [deploying, setDeploying] = useState(false)\n\n const validateEns = useCallback(async () => {\n // On production, ENS is mainnet. On Goerli, ENS is resolved in goerli.\n const ensProvider = safe.chainId === 5 ? goerliProvider : mainnetProvider\n const address = await ensProvider.resolveName(params.snapshotEns)\n console.log({ address })\n if (address) {\n const snapshotSpace = await snapshot.getSnapshotSpaceSettings(\n params.snapshotEns,\n safe.chainId,\n )\n const daorequirements = await getEnsTextRecord(\n params.snapshotEns,\n \"daorequirements\",\n ensProvider,\n )\n setDaorequirements(daorequirements[0])\n setValidEns(snapshotSpace !== undefined)\n if (snapshotSpace !== undefined) {\n setIsSafesnapInstalled(!!snapshotSpace.plugins?.safeSnap)\n const isController = await checkIfIsController(\n ensProvider,\n params.snapshotEns,\n safe.safeAddress,\n )\n setIsController(isController)\n // We don't check if SafeSnap is installed, because:\n // - either have no control\n // - we have control, and we will create it or overwrite it for the given chain\n console.log({ isController, snapshotSpace })\n console.log({ snapshotSpace })\n }\n } else {\n }\n }, [\n params.snapshotEns,\n safe.chainId,\n safe.safeAddress,\n mainnetProvider,\n goerliProvider,\n ])\n\n const debouncedSnapshotEnsValidation = debounce(() => {\n setValidEns(false)\n setDaorequirements(\"\")\n setIsController(false)\n setIsSafesnapInstalled(false)\n setLoadedEns(false)\n if (params.snapshotEns && params.snapshotEns.includes(\".eth\")) {\n setLoadingEns(true)\n const validateInfo = async () => {\n await validateEns()\n setLoadingEns(false)\n setLoadedEns(true)\n }\n validateInfo()\n }\n }, 300)\n\n // snapshot ens validation\n useEffect(() => {\n debouncedSnapshotEnsValidation()\n // eslint-disable-next-line\n }, [params.snapshotEns])\n\n const {\n loading: loadingCredentials,\n execute: validateCredentials,\n error: invalidCredentials,\n } = useMonitoringValidation()\n\n const debouncedCredentialValidation = debounce(async () => {\n setValidatedCredentials(false)\n await validateCredentials(apiKey, apiSecret)\n setValidatedCredentials(true)\n }, 300)\n\n useEffect(() => {\n if (apiKey && apiSecret) {\n debouncedCredentialValidation()\n }\n\n // eslint-disable-next-line\n }, [apiKey, apiSecret])\n\n // add appropriate default amounts, chain dependant.\n // 1 ETH, 1500 xDAI, 1000 MATIC. Defaults to 1 unit otherwise.\n useEffect(() => {\n if (safe.chainId) {\n const defaultAmount =\n safe.chainId === 1\n ? \"1\"\n : safe.chainId === 100\n ? \"1500\"\n : safe.chainId === 137\n ? \"1000\"\n : \"1\"\n setParams((prevParams) => {\n return { ...prevParams, bond: defaultAmount }\n })\n }\n }, [safe.chainId])\n\n // on change in params, recheck validation\n useEffect(() => {\n setValidFields({\n snapshotEns: validSnapshot,\n bond: !!params.bond,\n })\n }, [params, loadingEns, validSnapshot])\n\n const onParamChange = (\n field: Field,\n value: RealityModuleParams[Field],\n valid?: boolean,\n ) => {\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddRealityModule = async () => {\n setDeploying(true)\n try {\n const minimumBond = ethers.utils.parseUnits(params.bond, bondToken.decimals)\n const args = {\n ...params,\n oracle: getDefaultOracle(safe.chainId),\n arbitrator: getKlerosAddress(safe.chainId),\n executor: safe.safeAddress,\n bond: minimumBond.toString(),\n }\n\n const templateQuestion = getDefaultTemplateQuestion(args.snapshotEns)\n const templateData: TemplateData = {\n templateType: \"default\",\n language: \"english\",\n category: \"DAO proposal\",\n templateQuestion: templateQuestion,\n }\n const deploymentRealityModuleTxsMm = await deployRealityModule(\n provider,\n safe.safeAddress,\n DETERMINISTIC_DEPLOYMENT_HELPER_ADDRESS,\n safe.chainId,\n args,\n templateData,\n )\n\n let txs = [...deploymentRealityModuleTxsMm.txs]\n const realityModuleAddress = deploymentRealityModuleTxsMm.meta\n ?.expectedModuleAddress as string\n // We can only batch the SafeSnap creation when Safe is controller + mainnet\n // Otherwise, just create the module, hope the user got the hint and opened Details\n // to figure out how to set up SafeSnap in the space themselves.\n if (isController && safe.chainId === 1) {\n if (realityModuleAddress == null) {\n throw new Error(\n \"The calculated reality module address is 'null'. This should be handled in the 'statusCallback' function.\",\n )\n }\n const { txs: safeSnapTxs } = await addSafeSnapToSnapshotSpaceTxs(\n provider,\n args.snapshotEns,\n realityModuleAddress,\n safe.chainId,\n )\n txs.push(safeSnapTxs[0])\n }\n // If monitoring enabled, try to setup monitoring\n if (openMonitoring) {\n const monitoringData: MonitoringSectionData = {\n // api and secret are required for button to be enabled\n apiKey: apiKey,\n secretKey: apiSecret,\n discordKey: discordKey,\n email: emails,\n slackKey: \"\",\n telegram: { botToken: telegramBotToken, chatId: telegramChatId },\n }\n // we trust the notification parameters for discord and telegram are valid\n // user was forced to pass at least an email address to get here\n await setUpMonitoring(\n safe.chainId,\n realityModuleAddress,\n args.oracle,\n monitoringData,\n )\n }\n\n await sdk.txs.send({ txs })\n\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.log(\"Error deploying module: \", error)\n }\n setDeploying(false)\n }\n\n const handleBondChange = (event: React.ChangeEvent) => {\n const value = event.target.value || \"0\"\n const leftZero = value.startsWith(\"0\") && value.length > 1\n let bond = leftZero ? value.substr(1) : value\n bond = bond.startsWith(\".\") ? \"0\" + bond : bond\n\n try {\n ethers.utils.parseUnits(bond, bondToken.decimals)\n onParamChange(\"bond\", bond)\n } catch (error) {\n console.warn(\"invalid bond\", value, error)\n }\n }\n\n return (\n \n {step === \"form\" ? (\n <>\n Parameters\n\n \n \n onParamChange(\"snapshotEns\", e.target.value, true)}\n label=\"Snapshot Name\"\n placeholder=\"gnosis.eth\"\n rightIcon={\n <>\n {loadingEns ? (\n \n \n \n ) : loadedEns && validEns ? (\n \n \n \n ) : null}\n \n }\n />\n {!loadingEns && loadedEns && !validSnapshot && (\n \n )}\n \n \n onParamChange(\"timeout\", value)}\n />\n \n \n onParamChange(\"cooldown\", value)}\n />\n \n \n onParamChange(\"expiration\", value)}\n />\n \n \n \n \n \n \n \n Configure Monitoring\n \n \n
\n {\n setOpenMonitoring(!openMonitoring)\n }}\n />\n \n \n {openMonitoring && (\n \n \n \n Setting up an effective monitoring strategy is critical for the security\n of your safe. First, you need to{\" \"}\n \n create an Open Zeppelin account\n \n .\n \n \n \n {\n setApiKey(e.target.value)\n }}\n label=\"API Key\"\n placeholder=\"3pwZzZZZzzZZZzzZZzZZZAAaaAAaaZZzz\"\n rightIcon={\n loadingCredentials ? (\n \n \n \n ) : (\n validatedCredentials &&\n !invalidCredentials && (\n \n \n \n )\n )\n }\n />\n \n\n \n {\n setApiSecret(e.target.value)\n }}\n label=\"API Secret\"\n placeholder=\"2LUwZwwuUuuUUzzZZdDddooodudDDdaaDDdaAAAddDDadDzZZzdDDdcCCdDDaaAA\"\n rightIcon={\n loadingCredentials ? (\n \n \n \n ) : (\n validatedCredentials &&\n !invalidCredentials && (\n \n \n \n )\n )\n }\n />\n \n\n {validatedCredentials && invalidCredentials && (\n \n \n \n )}\n\n {/* Emails section */}\n \n \n Email\n \n  (required)\n \n \n \n Enter as many email addresses as you need\n \n {\n setCurrentEmail(e.target.value)\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && emailIsValid) {\n setEmails([...emails, currentEmail])\n setCurrentEmail(\"\")\n }\n }}\n rightIcon={\n <>\n {emailIsValid ? (\n \n {\n setEmails([...emails, currentEmail])\n setCurrentEmail(\"\")\n }}\n >\n {\" \"}\n \n \n \n ) : null}\n \n }\n />\n {emails.length > 0 ? (\n emails.map((e) => (\n \n \n setEmails(emails.filter((x) => x !== e))}\n >\n \n \n \n \n {e}\n \n \n ))\n ) : (\n \n {emailIsValid\n ? \"Press Enter or click + to add this email\"\n : \"(No emails entered, at least one is required)\"}\n \n )}\n \n\n \n \n Discord Integration\n \n  (optional)\n \n \n \n \n Include the Discord channel's url key\n \n \n Learn more\n \n \n {\n setDiscordKey(e.target.value)\n }}\n placeholder=\"https://discord.com/api/webhooks/.../\"\n />\n \n\n \n \n Telegram Integration\n \n  (optional)\n \n \n \n \n Include the Telegram bot token and Chat ID\n \n \n Learn more\n \n \n \n \n \n {\n setTelegramBotToken(e.target.value)\n }}\n />\n \n \n {\n setTelegramChatId(e.target.value)\n }}\n />\n \n \n \n \n \n )}\n {/* Button Section */}\n }\n onClick={() => {\n setStep(\"confirm\")\n }}\n disabled={!canConfirm}\n style={{ marginTop: \"16px\" }}\n >\n {/* Button Messages */}\n {canConfirm || !openMonitoring\n ? \"Add Module\"\n : loadingCredentials\n ? \"Validating OpenZeppelin Credentials...\"\n : !validatedCredentials || invalidCredentials\n ? \"Missing OpenZeppelin API\"\n : \"Missing Email\"}\n \n \n ) : (\n <>\n It's almost ready! Just a reminder:\n {loadedEns &&\n (validSnapshot ? (\n isController && safe.chainId === 1 ? (\n isSafesnapInstalled ? (\n
\n SafeSnap plugin is already installed, and will be overwritten.\n
\n ) : (\n
The SafeSnap plugin will be automatically installed.
\n )\n ) : (\n // A way to paste the safesnap plugin info is here.\n
\n \n
\n )\n ) : (\n \n ))}\n {loadedEns && daorequirements === \"\" && (\n // Notice on how to setup DAO requirements, which appear on template.\n \n )}\n \n \n }\n onClick={() => setStep(\"form\")}\n >\n Return\n \n \n \n \n ) : (\n \n )\n }\n onClick={() => {\n handleAddRealityModule()\n }}\n >\n Add Module\n \n \n {deploying && openMonitoring && (\n \n
This can take around a minute, please wait...
\n
\n )}\n \n \n )}\n \n )\n}\n","import React, { useState } from \"react\"\nimport { Typography, makeStyles } from \"@material-ui/core\"\nimport { ParamType } from \"@ethersproject/abi\"\nimport { ConnextModuleParams, deployConnextModule, getConnextAddress } from \"services\"\nimport { ReactComponent as ArrowUpIcon } from \"../../../../assets/icons/arrow-up-icon.svg\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { ParamInput } from \"../../../../components/ethereum/ParamInput\"\nimport { ActionButton } from \"../../../../components/ActionButton\"\nimport { AddModuleModal } from \"../components/AddModuleModal\"\n\ninterface ConnextModuleProps {\n open: boolean\n onClose?(): void\n onSubmit?(): void\n}\n\nconst useStyles = makeStyles((theme) => ({\n addButton: {\n marginTop: theme.spacing(2),\n },\n addTransactionButton: {\n marginTop: theme.spacing(1),\n },\n addIcon: {\n stroke: theme.palette.common.white,\n width: 20,\n height: 20,\n },\n inputParam: {\n marginTop: theme.spacing(2),\n },\n errorMessage: {\n marginTop: theme.spacing(1),\n color: \"red\",\n },\n}))\n\nexport const ConnextModuleModal = ({ onSubmit, open, onClose }: ConnextModuleProps) => {\n const { sdk, safe, provider } = useSafeAppsSDKWithProvider()\n const classes = useStyles()\n\n const [errors, setErrors] = useState>({\n owner: false,\n avatar: false,\n target: false,\n domainId: true,\n sender: true,\n })\n\n const [params, setParams] = useState({\n owner: safe.safeAddress,\n avatar: safe.safeAddress,\n target: safe.safeAddress,\n domainId: 0,\n sender: \"\",\n })\n\n const onParamChange = (\n field: Field,\n value: ConnextModuleParams[Field],\n valid?: boolean,\n ) => {\n setErrors({ ...errors, [field]: !valid })\n setParams({\n ...params,\n [field]: value,\n })\n }\n\n const handleAddConnextModule = async () => {\n try {\n const args = {\n ...params,\n }\n const txs = deployConnextModule(provider, safe.safeAddress, safe.chainId, args)\n\n await sdk.txs.send({ txs })\n if (onSubmit) onSubmit()\n if (onClose) onClose()\n } catch (error) {\n console.error(\"Error deploying module: \", error)\n }\n }\n\n return (\n \n Parameters\n\n onParamChange(\"sender\", value, valid)}\n />\n\n onParamChange(\"domainId\", value, valid)}\n />\n\n \n {!getConnextAddress(safe.chainId) ? \"Not supported network for the Module\" : null}\n \n\n }\n onClick={handleAddConnextModule}\n >\n Add Module\n \n \n )\n}\n","import React from \"react\"\nimport { TellorModuleModal } from \"./TellorModule/TellorModuleModal\"\nimport { OptimisticGovernorModuleModal } from \"./OptimisticGovernorModule/OptimisticGovernorModuleModal\"\nimport { DelayModuleModal } from \"./DelayModule/DelayModuleModal\"\nimport { ModuleType } from \"../../../store/modules/models\"\nimport { CustomModuleModal } from \"./CustomModule/CustomModuleModal\"\nimport { AMBModuleModal } from \"./AMBModuleModal/AMBModuleModal\"\nimport { ExitModuleModal } from \"./ExitModule/ExitModuleModal\"\nimport { RolesV1ModifierModal } from \"./RolesModifier/RolesV1ModifierModal\"\nimport { RolesV2ModifierModal } from \"./RolesModifier/RolesV2ModifierModal\"\nimport { RealityModuleOldModal } from \"./RealityModuleOld/RealityModuleOldModal\"\nimport { KlerosRealityModuleModal } from \"./KlerosRealityModule/KlerosRealityModuleModal\"\nimport { ConnextModuleModal } from \"./ConnextModule/ConnextModuleModal\"\n\n/**\n * All wizards that use a Modal must be added here.\n */\n\ninterface ModuleModalsProps {\n selected?: ModuleType\n\n onClose?(): void\n\n onSubmit?(module: ModuleType): void\n}\n\nexport const ModuleModals = ({ selected, onClose, onSubmit }: ModuleModalsProps) => {\n return (\n <>\n onSubmit && onSubmit(ModuleType.TELLOR)}\n />\n onSubmit && onSubmit(ModuleType.OPTIMISTIC_GOVERNOR)}\n />\n onSubmit && onSubmit(ModuleType.DELAY)}\n />\n onSubmit && onSubmit(ModuleType.BRIDGE)}\n />\n onSubmit && onSubmit(ModuleType.EXIT)}\n />\n onSubmit && onSubmit(ModuleType.ROLES_V1)}\n />\n onSubmit && onSubmit(ModuleType.ROLES_V2)}\n />\n onSubmit && onSubmit(ModuleType.REALITY_ETH)}\n />\n onSubmit && onSubmit(ModuleType.KLEROS_REALITY)}\n />\n onSubmit && onSubmit(ModuleType.CONNEXT)}\n />\n\n onSubmit && onSubmit(ModuleType.UNKNOWN)}\n />\n \n )\n}\n","import React, { useState } from \"react\"\nimport { makeStyles, Typography } from \"@material-ui/core\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { ModuleButton } from \"./ModuleButton\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getModulesList } from \"../../store/modules/selectors\"\nimport { ModuleModals } from \"./wizards/ModalWizards\"\nimport { ModuleType } from \"../../store/modules/models\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setOzGovernorModuleScreen,\n setRealityModuleScreen,\n} from \"../../store/modules\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { NETWORK } from \"utils/networks\"\nimport { klerosAvailability } from \"components/input/ArbitratorSelect\"\nimport {\n ContractAddresses as AllContractAddresses,\n KnownContracts,\n SupportedNetworks,\n} from \"@gnosis.pm/zodiac\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(1.5),\n },\n gridContainer: {\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fill, minmax(180px, 1fr))\",\n gap: theme.spacing(2),\n },\n paper: {\n padding: theme.spacing(2.5, 2),\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n introBox: {\n gridColumn: \"1/3\",\n \"@media (max-width:930px)\": {\n gridColumn: \"1/2\",\n },\n },\n firstModule: {\n gridColumn: 1,\n },\n link: {\n color: theme.palette.text.primary,\n },\n}))\n\nexport const AddModulesView = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const { safe } = useSafeAppsSDK()\n const hasModules = useRootSelector((state) => getModulesList(state).length > 0)\n const [module, setModule] = useState()\n\n const handleSubmit = () => {\n dispatch(fetchPendingModules(safe))\n dispatch(setModuleAdded(true))\n }\n\n const ContractAddresses = AllContractAddresses[safe.chainId as SupportedNetworks]\n\n const title = hasModules ? \"Add another mod\" : \"Start by adding a mod\"\n\n return (\n
\n
\n
\n \n \n {title}\n \n \n Built according to an open standard, the Zodiac collection of tools are mods\n that support, expand, and transform how organizations operate. Learn more\n about Zodiac in{\" \"}\n \n this article\n {\" \"}\n and about Gnosis Safe modules more generally in{\" \"}\n \n this article\n \n .\n \n \n
\n\n setModule(ModuleType.BRIDGE)}\n className={classes.firstModule}\n available={!!ContractAddresses[KnownContracts.BRIDGE]}\n />\n\n setModule(ModuleType.DELAY)}\n available={!!ContractAddresses[KnownContracts.DELAY]}\n />\n\n setModule(ModuleType.EXIT)}\n available={!!ContractAddresses[KnownContracts.EXIT_ERC20]}\n />\n\n setModule(ModuleType.ROLES_V2)}\n available={!!ContractAddresses[KnownContracts.ROLES_V2]}\n />\n\n dispatch(setRealityModuleScreen(true))}\n available={[NETWORK.MAINNET, NETWORK.GOERLI].includes(safe.chainId)}\n />\n\n setModule(ModuleType.REALITY_ETH)}\n available={[NETWORK.MAINNET, NETWORK.GOERLI].includes(safe.chainId)}\n />\n\n setModule(ModuleType.KLEROS_REALITY)}\n available={klerosAvailability.includes(safe.chainId)}\n />\n\n setModule(ModuleType.TELLOR)}\n available={!!ContractAddresses[KnownContracts.TELLOR]}\n />\n\n setModule(ModuleType.OPTIMISTIC_GOVERNOR)}\n available // TODO\n />\n\n dispatch(setOzGovernorModuleScreen(true))}\n available={!!ContractAddresses[KnownContracts.OZ_GOVERNOR]}\n />\n\n setModule(ModuleType.CONNEXT)}\n available={!!ContractAddresses[KnownContracts.CONNEXT]}\n />\n\n setModule(ModuleType.ROLES_V1)}\n available={!!ContractAddresses[KnownContracts.ROLES_V1]}\n />\n\n setModule(ModuleType.UNKNOWN)}\n available\n />\n
\n\n setModule(undefined)}\n onSubmit={handleSubmit}\n />\n
\n )\n}\n\nexport default AddModulesView\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { ContractReadFunctionsList } from \"./ContractReadFunctionsList\";\nimport { ContractOperationToggleButtons } from \"../ContractOperationToggleButtons\";\nimport { ContractInterface } from \"@ethersproject/contracts\";\n\ninterface ContractInteractionsPreviewProps {\n address: string;\n abi: ContractInterface;\n}\n\nconst useStyles = makeStyles((theme) => ({\n content: {\n padding: theme.spacing(2.5),\n marginTop: theme.spacing(3),\n },\n}));\n\nexport const ContractInteractionsPreview = ({\n address,\n abi,\n}: ContractInteractionsPreviewProps) => {\n const classes = useStyles();\n\n return (\n <>\n \n\n \n \n \n \n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\nimport { Skeleton } from \"@material-ui/lab\";\nimport { useRootSelector } from \"../../store\";\nimport {\n getCurrentPendingModule,\n getSafeThreshold,\n} from \"../../store/modules/selectors\";\nimport { ContractInteractionsPreview } from \"./contract/ContractInteractionsPreview\";\nimport { getModuleContractMetadata } from \"../../utils/modulesValidation\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n padding: theme.spacing(3),\n },\n paper: {\n padding: theme.spacing(2.5),\n maxWidth: 500,\n },\n title: {\n marginBottom: theme.spacing(2),\n },\n header: {\n display: \"grid\",\n gridTemplateColumns: \"50px auto\",\n gridGap: theme.spacing(2),\n alignItems: \"center\",\n marginBottom: theme.spacing(3),\n },\n addressText: {\n margin: theme.spacing(0, 2, 0, 3),\n fontWeight: \"bold\",\n },\n icon: {\n marginLeft: \"16px\",\n },\n buttons: {\n marginTop: theme.spacing(3),\n opacity: 0.5,\n },\n}));\n\nfunction ModulePendingInstantTx() {\n const currentPendingTx = useRootSelector(getCurrentPendingModule);\n\n if (!currentPendingTx) return null;\n\n const metadata = getModuleContractMetadata(currentPendingTx.module);\n\n if (!metadata || !metadata.abi) return null;\n\n return (\n \n );\n}\n\nexport const ModulePendingTransaction = () => {\n const classes = useStyles();\n const safeThreshold = useRootSelector(getSafeThreshold);\n const isInstantExecution = safeThreshold === 1;\n\n return (\n
\n
\n \n \n
\n\n {!isInstantExecution ? (\n \n \n Waiting on module approval\n \n \n Once this module transaction has been approved by the other signers,\n you will be able to read and write to it.\n \n \n ) : (\n \n )}\n
\n );\n};\n","import { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React, { useEffect, useState } from \"react\"\nimport { colors, ZodiacTextField } from \"zodiac-ui-components\"\nimport { InputPartProps, ORACLE_MAINNET_OPTIONS, ORACLE_GOERLI_OPTIONS } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n padding: \"9px 8px\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n}))\n\nexport type Data = {\n instanceAddress: string\n instanceType: \"ETH\" | \"GNO\" | \"custom\"\n}\n\nexport const OracleInstance: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const options = safe.chainId === 1 ? ORACLE_MAINNET_OPTIONS : ORACLE_GOERLI_OPTIONS\n const [selectedOracle, setSelectedOracle] = useState(\"\")\n\n useEffect(() => {\n if (data && options.length && selectedOracle === \"\") {\n const item = options.filter((element) =>\n element.label.includes(data.instanceAddress),\n )\n setSelectedOracle(item[0].value)\n }\n }, [data, options, selectedOracle])\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const handleInstance = (instance: string) => {\n if (instance === \"custom\") {\n set(\"instanceType\")(instance)\n return\n }\n const address = instance.substr(instance.indexOf(\"-\") + 1)\n const instanceType = instance.substr(0, instance.indexOf(\"-\"))\n setSelectedOracle(instance)\n set(\"instanceAddress\")(address)\n set(\"instanceType\")(instanceType as string)\n }\n\n return (\n \n \n \n \n \n Oracle Instance\n \n \n \n \n The oracle instance sets the appropriate bond token. It's recommended\n to use the default (ETH) oracle instance unless you have a specific reason\n to use something like a native token which can potentially be more prone to\n price manipulation.\n \n \n \n \n \n {\n handleInstance(target.value as string)\n }}\n />\n \n {get(\"instanceType\") === \"custom\" && (\n \n \n \n set(\"instanceAddress\")(evt.target.value as string)}\n />\n \n \n {/* //TODO: get the bond token name from the contract} */}\n WEENUS\n \n \n \n )}\n \n )\n}\n\nexport default OracleInstance\n","export const DEFAULT_TIMEOUT = 172800 // 2 Days\nexport const MIN_TIMEOUT = 86400 // 1 Day\nexport const WARNING_TIMEOUT = 172800 // 2 Days\nexport const DEFAULT_COOLDOWN = 172800 // 2 Days\nexport const WARNING_COOLDOWN = 172800 // 2 Days\nexport const MIN_COOLDOWN = 0\nexport const DEFAULT_EXPIRATION = 604800 // 7 Days\nexport const WARNING_EXPIRATION = 432000 // 5 Day\nexport const MIN_EXPIRATION = 86400 // 1 Day\n\nexport const TIMEOUT_WARNING_MSG =\n \"We highly recommend that your timeout delay exceeds 48 hours.\"\nexport const TIMEOUT_ERROR_MSG = \"Your timeout delay must exceed 24 hours.\"\nexport const COOLDOWN_WARNING_MSG =\n \"We highly recommend that your cooldown delay exceeds 48 hours.\"\nexport const COOLDOWN_ERROR_MSG = \"Your cooldown delay must exceed 0\"\nexport const EXPIRATION_WARNING_MSG =\n \"We highly recommend that your expiration delay exceeds cooldown + 5 days.\"\nexport const EXPIRATION_ERROR_MSG =\n \"Your expiration delay must exceeds cooldown + 1 days.\"\n\nexport const isValidOracleDelay = (\n type: \"timeout\" | \"cooldown\" | \"expiration\",\n delayValue: string | number,\n dependsDelayValue?: string | number,\n): boolean => {\n const value = parseInt(delayValue as string)\n const depends = parseInt(dependsDelayValue as string)\n switch (type) {\n case \"timeout\":\n if (value < MIN_TIMEOUT) {\n return false\n }\n break\n case \"cooldown\":\n if (value <= MIN_COOLDOWN) {\n return false\n }\n break\n case \"expiration\":\n if (value === 0) {\n return true\n }\n if (dependsDelayValue && value < depends + MIN_EXPIRATION) {\n return false\n }\n break\n }\n return true\n}\n\nexport const warningOracleDelay = (\n type: \"timeout\" | \"cooldown\" | \"expiration\",\n delayValue: string | number,\n): boolean => {\n const value = parseInt(delayValue as string)\n switch (type) {\n case \"timeout\":\n if (value >= MIN_TIMEOUT && value < WARNING_TIMEOUT) {\n return false\n }\n break\n case \"cooldown\":\n if (value >= MIN_COOLDOWN && value < WARNING_COOLDOWN) {\n return false\n }\n break\n case \"expiration\":\n if (value === 0) {\n return false\n }\n if (value >= MIN_EXPIRATION && value < WARNING_EXPIRATION) {\n return false\n }\n break\n }\n return true\n}\n","import React from \"react\"\nimport { Grid, Typography, makeStyles } from \"@material-ui/core\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport ReportProblemOutlinedIcon from \"@material-ui/icons/ReportProblemOutlined\"\nimport { colors } from \"zodiac-ui-components\"\n\nconst useStyles = makeStyles(() => ({\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n },\n warningIcon: {\n fill: colors.tan[800],\n },\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n warningMessage: {\n fontSize: 12,\n color: colors.tan[800],\n },\n}))\n\nexport const OracleAlert: React.FC<{\n type: \"error\" | \"warning\"\n message: string\n}> = ({ type, message }) => {\n const classes = useStyles()\n return (\n \n {type === \"error\" && (\n \n {\" \"}\n \n )}\n\n {type === \"warning\" && (\n \n \n \n )}\n\n \n \n {message}\n \n \n \n )\n}\n","import { Grid } from \"@material-ui/core\"\nimport React, { Fragment, useEffect, useState } from \"react\"\nimport {\n COOLDOWN_ERROR_MSG,\n COOLDOWN_WARNING_MSG,\n EXPIRATION_ERROR_MSG,\n EXPIRATION_WARNING_MSG,\n isValidOracleDelay,\n TIMEOUT_ERROR_MSG,\n TIMEOUT_WARNING_MSG,\n warningOracleDelay,\n} from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { OracleAlert } from \"../OracleAlert\"\n\nexport interface OracleDelayValidationProps {\n type: \"timeout\" | \"cooldown\" | \"expiration\"\n delayValue: string | number\n dependsDelayValue?: string | number\n}\ninterface OracleAlertType {\n type: \"error\" | \"warning\"\n message: string\n}\n\nexport const OracleDelayValidation: React.FC = ({\n type,\n delayValue,\n dependsDelayValue,\n}) => {\n const timeoutError = isValidOracleDelay(\"timeout\", parseInt(delayValue as string))\n const cooldownError = isValidOracleDelay(\"cooldown\", parseInt(delayValue as string))\n const expirationError = isValidOracleDelay(\n \"expiration\",\n parseInt(delayValue as string),\n dependsDelayValue,\n )\n const timeoutWarning = warningOracleDelay(\"timeout\", parseInt(delayValue as string))\n const cooldownWarning = warningOracleDelay(\"cooldown\", parseInt(delayValue as string))\n const expirationWarning = warningOracleDelay(\n \"expiration\",\n parseInt(delayValue as string),\n )\n\n const [timeoutAlert, setTimeoutAlert] = useState(undefined)\n const [cooldownAlert, setCooldownAlert] = useState(\n undefined,\n )\n const [expirationAlert, setExpirationAlert] = useState(\n undefined,\n )\n\n useEffect(() => {\n if (!timeoutError) {\n return setTimeoutAlert({ type: \"error\", message: TIMEOUT_ERROR_MSG })\n }\n if (!timeoutWarning) {\n return setTimeoutAlert({ type: \"warning\", message: TIMEOUT_WARNING_MSG })\n }\n setTimeoutAlert(undefined)\n }, [timeoutError, timeoutWarning])\n\n useEffect(() => {\n if (!cooldownError) {\n return setCooldownAlert({ type: \"error\", message: COOLDOWN_ERROR_MSG })\n }\n if (!cooldownWarning) {\n return setCooldownAlert({ type: \"warning\", message: COOLDOWN_WARNING_MSG })\n }\n setCooldownAlert(undefined)\n }, [cooldownError, cooldownWarning])\n\n useEffect(() => {\n if (!expirationError) {\n return setExpirationAlert({ type: \"error\", message: EXPIRATION_ERROR_MSG })\n }\n if (!expirationWarning) {\n return setExpirationAlert({ type: \"warning\", message: EXPIRATION_WARNING_MSG })\n }\n setExpirationAlert(undefined)\n }, [expirationError, expirationWarning])\n\n return (\n \n {type === \"timeout\" && timeoutAlert && (\n \n \n \n )}\n {type === \"cooldown\" && cooldownAlert && (\n \n \n \n )}\n {type === \"expiration\" && expirationAlert && (\n \n \n \n )}\n \n )\n}\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { TimeSelect, unitConversion } from \"components/input/TimeSelect\"\nimport React from \"react\"\nimport { isValidOracleDelay } from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { InputPartProps } from \"../..\"\nimport { OracleDelayValidation } from \"../OracleDelayValidation\"\n\nconst useStyles = makeStyles(() => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n}))\n\ntype Unit = keyof typeof unitConversion\n\nexport type Data = {\n expiration: number\n expirationUnit: Unit\n cooldown: number\n cooldownUnit: Unit\n timeout: number\n timeoutUnit: Unit\n}\n\nexport const OracleDelay: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n const get = (key: keyof Data) => data[key]\n const timeout = get(\"timeout\")\n const cooldown = get(\"cooldown\")\n const expiration = get(\"expiration\")\n const isValidTimeout = isValidOracleDelay(\"timeout\", timeout)\n const isValidCooldown = isValidOracleDelay(\"cooldown\", cooldown)\n const isValidExpiration = isValidOracleDelay(\"expiration\", expiration, cooldown)\n\n return (\n \n \n \n \n \n Delay Configuration\n \n \n \n \n These Parameters are very important for your DAO's security and should\n be considered carefully. Allowing enough time in these configurations will\n enable the safe to have a final chance to veto or circumvent any potential\n malicious proposals that have snuck through.\n \n \n \n \n \n \n \n {\n setData({ ...data, timeout: value, timeoutUnit: unit })\n }}\n />\n \n \n {\n setData({ ...data, cooldown: value, cooldownUnit: unit })\n }}\n />\n \n \n {\n setData({ ...data, expiration: value, expirationUnit: unit })\n }}\n />\n \n \n \n \n \n \n \n )\n}\nexport default OracleDelay\n","import { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { ZodiacTextField, colors } from \"zodiac-ui-components\"\nimport { InputPartProps } from \"../..\"\nimport { OracleAlert } from \"../OracleAlert\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n error: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n}))\n\nexport const MIN_BOND = 0.1\n\nexport type Data = {\n bond: number\n}\n\nexport const OracleBond: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n const bond = get(\"bond\")\n\n return (\n \n \n \n \n \n Bond\n \n \n \n \n Minimum bond required for an answer to be accepted. New answers must be\n submitted with double the previous bond. For more on why a bond is required\n in an escalation-game-based oracle, read more in the{\" \"}\n \n Reality.eth whitepaper.\n \n \n \n \n \n \n set(\"bond\")(e.target.value)}\n />\n \n {bond < MIN_BOND && (\n \n \n \n )}\n \n )\n}\n\nexport default OracleBond\n","import { Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { Dropdown } from \"components/Dropdown\"\nimport React from \"react\"\nimport { ARBITRATOR_OPTIONS } from \"services\"\nimport { InputPartProps } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n}))\n\nexport type Data = {\n arbitratorOption: ARBITRATOR_OPTIONS\n}\n\nexport const OracleArbitration: React.FC = ({ data, setData }) => {\n const classes = useStyles()\n\n const set = (key: keyof Data) => (value: any) => setData({ ...data, [key]: value })\n\n const get = (key: keyof Data) => data[key]\n\n return (\n \n \n \n \n \n Arbitration\n \n \n \n \n An arbitrator is responsible for providing a final answer to a question when there is a dispute, in\n exchange for a fee. In most cases, the bond escalation-game eliminates the need for this. However, if you\n feel it's necessary to include a backup arbitration strategy incase of a dispute, you can select one\n from below. Read more in the{` `}\n \n Reality.eth arbitrators documentation\n \n .\n \n \n \n \n \n set(\"arbitratorOption\")(target.value)}\n />\n \n \n )\n}\n\nexport default OracleArbitration\n","import { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { Link } from \"components/text/Link\"\nimport React, { useEffect, useState } from \"react\"\nimport { ZodiacModal, ZodiacPaper } from \"zodiac-ui-components\"\nimport OracleTemplate, {\n Data as OracleTemplateData,\n getDefaultTemplateQuestion,\n} from \"./components/OracleTemplate\"\nimport OracleInstance, { Data as OracleInstanceData } from \"./components/OracleInstance\"\nimport OracleDelay, { Data as OracleDelayData } from \"./components/OracleDelay\"\nimport OracleBond, { Data as OracleBondData, MIN_BOND } from \"./components/OracleBond\"\nimport OracleArbitration, {\n Data as OracleArbitratorData,\n} from \"./components/OracleArbitration\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { ARBITRATOR_OPTIONS } from \"services\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport { OracleAlert } from \"./components/OracleAlert\"\nimport {\n DEFAULT_COOLDOWN,\n DEFAULT_EXPIRATION,\n DEFAULT_TIMEOUT,\n isValidOracleDelay,\n warningOracleDelay,\n} from \"views/AddModule/wizards/RealityModule/utils/oracleValidations\"\nimport { OracleDelayValidation } from \"./components/OracleDelayValidation\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n icon: {\n fill: \"white\",\n width: \"20px\",\n },\n\n divider: {\n marginTop: 8,\n marginBottom: 8,\n },\n warningModal: {\n maxWidth: 650,\n },\n errorPaperContainer: {\n width: \"100%\",\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n border: 0,\n borderRadius: 4,\n display: \"inline-block\",\n \"& .MuiTypography-root\": {\n fontFamily: \"Roboto Mono\",\n },\n },\n}))\n\nexport const ORACLE_MAINNET_OPTIONS = [\n {\n label: \"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\",\n value: \"ETH-0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c\",\n },\n {\n label: \"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9\",\n value: \"GNO-0x33aa365a53a4c9ba777fb5f450901a8eef73f0a9\",\n },\n // { label: \"Add Custom Instance\", value: \"custom\" },\n]\n\nexport const ORACLE_GOERLI_OPTIONS = [\n {\n label: \"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\",\n value: \"ETH-0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f\",\n },\n // { label: \"Add Custom Instance\", value: \"custom\" },\n]\n\nexport interface InputPartProps {\n data: any\n setData: (data: any) => void\n}\n\nexport type OracleSectionData = {\n templateData: OracleTemplateData\n instanceData: OracleInstanceData\n delayData: OracleDelayData\n bondData: OracleBondData\n arbitratorData: OracleArbitratorData\n}\n\nexport const OracleSection: React.FC = ({\n handleBack,\n handleNext,\n setupData,\n}) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const options = safe.chainId === 1 ? ORACLE_MAINNET_OPTIONS : ORACLE_GOERLI_OPTIONS\n const [showModal, setShowModal] = useState(false)\n if (setupData?.proposal.ensName == null) {\n throw new Error(\"ENS name is not set\")\n }\n const [templateData, setTemplateData] = useState({\n templateType: \"default\",\n language: \"english\",\n category: \"DAO proposal\",\n templateQuestion: getDefaultTemplateQuestion(setupData?.proposal.ensName),\n })\n\n const [instanceData, setInstanceData] = useState({\n instanceAddress: options[0].value.substr(options[0].value.indexOf(\"-\") + 1),\n instanceType: options[0].value.substr(0, options[0].value.indexOf(\"-\")) as\n | \"ETH\"\n | \"GNO\"\n | \"custom\",\n })\n\n const [delayData, setDelayData] = useState({\n timeout: DEFAULT_TIMEOUT,\n timeoutUnit: \"days\",\n cooldown: DEFAULT_COOLDOWN,\n cooldownUnit: \"days\",\n expiration: DEFAULT_EXPIRATION,\n expirationUnit: \"days\",\n })\n\n const [bondData, setBondData] = useState({\n bond: 0.1,\n })\n\n const { timeout, cooldown, expiration } = delayData\n const { bond } = bondData\n const isValidTimeout = isValidOracleDelay(\"timeout\", timeout)\n const isValidCooldown = isValidOracleDelay(\"cooldown\", cooldown)\n const isValidExpiration = isValidOracleDelay(\"expiration\", expiration, cooldown)\n const isWarningTimeout = warningOracleDelay(\"timeout\", timeout)\n const isWarningCooldown = warningOracleDelay(\"cooldown\", cooldown)\n const isWarningExpiration = warningOracleDelay(\"expiration\", expiration)\n\n const [arbitratorData, setArbitratorData] = useState({\n arbitratorOption: ARBITRATOR_OPTIONS.NO_ARBITRATOR,\n })\n\n const collectData = (): OracleSectionData => ({\n templateData,\n instanceData,\n delayData,\n bondData,\n arbitratorData,\n })\n\n const validateOracle = () => {\n if (\n [isWarningTimeout, isWarningCooldown, isWarningExpiration].includes(false) ||\n bond < MIN_BOND\n ) {\n return setShowModal(true)\n }\n handleNext(collectData())\n }\n\n useEffect(() => {\n if (setupData && setupData.oracle) {\n const { bondData, delayData, instanceData, templateData, arbitratorData } =\n setupData.oracle\n setBondData(bondData)\n setDelayData(delayData)\n setInstanceData(instanceData)\n setTemplateData(templateData)\n setArbitratorData(arbitratorData)\n }\n }, [setupData])\n\n if (setupData?.proposal.ensName == null) {\n throw new Error(\n \"The ENS name is not available, it needs to already be in the setupData, before initiating this step.\",\n )\n }\n\n return (\n \n \n \n \n \n Set up the Oracle\n \n \n \n Now, it's time to set up the oracle for your reality module. The\n oracle ensures the results of proposals are brought accurately on-chain.\n The Reality.eth oracle uses a mechanism known as the{\" \"}\n \n escalation game\n {\" \"}\n to generate correct answers that can be used as inputs for smart\n contracts. The following parameters are very important for your DAO's\n security and should be considered carefully.\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n handleBack(collectData())}\n >\n Back\n \n \n \n \n Next\n \n \n \n \n \n setShowModal(!showModal)}\n children={\n \n \n \n \n \n \n \n Security Risk Detected\n \n \n \n\n \n \n The following security risks have been detected. We highly recommend that\n you resolve them before moving forward, as these can leave to loss of\n funds.\n \n \n\n \n \n \n \n \n {bond < MIN_BOND && (\n \n \n \n )}\n \n \n\n \n \n \n\n \n \n \n \n \n \n setShowModal(false)}\n >\n Resolve (Recommended)\n \n \n \n \n \n }\n />\n \n )\n}\n\nexport default OracleSection\n","import React from \"react\"\nimport { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport { ZodiacPaper } from \"zodiac-ui-components\"\nimport { Link } from \"components/text/Link\"\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n fill: \"white\",\n width: \"20px\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n background: \"rgba(244, 67, 54, 0.1)\",\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n \"&, &:before, &:after\": {\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n },\n },\n addressPaperContainer: {\n width: \"100%\",\n padding: theme.spacing(1),\n background: \"rgba(0, 0, 0, 0.2)\",\n border: 0,\n borderRadius: 4,\n display: \"inline-block\",\n \"& .MuiTypography-root\": {\n fontFamily: \"Roboto Mono\",\n },\n },\n}))\n\nexport interface ProposalDetailsModalProps {\n title: string\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\"\n address?: string\n}\n\nexport const ProposalDetailsModal: React.FC = ({\n title,\n type,\n address,\n}) => {\n const classes = useStyles()\n\n return (\n \n \n \n \n \n \n \n {title}\n \n \n \n \n \n {type === \"controller\" &&\n \"The safe you are currently using with Zodiac is not the controller of the ENS you've entered. Try one of the following: \"}\n {type === \"owner\" &&\n \"The ENS that you've entered is not owned by a safe. This gives unilateral control to the individual with this address: \"}\n {type === \"safesnap\" &&\n \"The Snapshot space has already installed the Safesnap plugin.\"}\n {type === \"snapshot\" &&\n title.includes(\"Invalid\") &&\n \"The current snapshot settings file is invalid. Check the browser console for validation details. The schema for validating the settings file can be found\"}\n {type === \"snapshot\" && title.includes(\"Invalid\") && (\n <>\n {\" \"}\n \n here.\n \n \n )}\n {type === \"snapshot\" &&\n !title.includes(\"Invalid\") &&\n \"The ENS you've entered is not setup with a Snapshot space. To setup a snapshot space with this ENS, follow the guide\"}\n\n {type === \"snapshot\" && !title.includes(\"Invalid\") && (\n <>\n {\" \"}\n \n here.\n \n \n )}\n \n \n {address && (\n \n \n \n {address}\n \n \n \n )}\n {[\"controller\", \"owner\"].includes(type) && (\n \n \n {type === \"controller\" && \"- Check that your ENS is typed correctly.\"}\n {type === \"owner\" &&\n \"We highly recommend transferring the ENS to a multisig safe before continuing.\"}\n \n \n )}\n\n {type === \"controller\" && (\n \n \n - Update your ENS controller settings via the{\" \"}\n \n ENS.\n \n \n \n )}\n \n )\n}\n\nexport default ProposalDetailsModal\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React, { useState } from \"react\"\n\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport WarningOutlinedIcon from \"@material-ui/icons/WarningOutlined\"\nimport { ZodiacModal } from \"zodiac-ui-components\"\nimport ProposalDetailsModal from \"./ProposalDetailsModal\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n messageDetails: {\n fontSize: 12,\n textDecoration: \"underline\",\n cursor: \"pointer\",\n },\n\n errorIcon: {\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"20px\",\n },\n detailsContainer: {\n width: \"95%\",\n },\n messageContainer: {\n width: \"85%\",\n },\n}))\n\nexport interface ProposalStatusProps {\n status: \"error\" | \"warning\" | null\n message: string | null\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\"\n address?: string\n}\n\nexport const ProposalStatus: React.FC = ({\n status,\n message,\n type,\n address,\n}) => {\n const classes = useStyles()\n const [showModal, setShowModal] = useState(false)\n\n const handleTitle = (): string => {\n switch (type) {\n case \"controller\":\n return \"Safe not controller of ENS\"\n\n case \"owner\":\n return \"Security Risk Detected\"\n\n case \"snapshot\":\n if (message?.includes(\"invalid\")) {\n return \"Invalid Snapshot settings file\"\n }\n return \"Snapshot space not found\"\n\n case \"safesnap\":\n return \"Safesnap plugin is already installed\"\n\n default:\n return \"\"\n }\n }\n\n const title = handleTitle()\n return (\n status && (\n \n \n {status === \"error\" && }\n {status === \"warning\" && }\n \n \n \n \n {message}\n \n \n setShowModal(!showModal)}\n >\n Details\n \n \n \n \n setShowModal(!showModal)}\n children={}\n />\n \n )\n )\n}\n\nexport default ProposalStatus\n","export const handleProposalStatus = (\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\",\n loading: boolean,\n isController: boolean,\n isOwner: boolean,\n hasSnapshot: boolean,\n validSnapshot: boolean,\n isSafesnapInstalled: boolean,\n): \"warning\" | \"error\" | null => {\n if (!loading) {\n if (type === \"snapshot\" && !hasSnapshot) {\n return \"error\"\n }\n if (type === \"snapshot\" && !validSnapshot) {\n return \"error\"\n }\n if (type === \"controller\" && !isController) {\n return \"error\"\n }\n if (type === \"safesnap\" && isSafesnapInstalled) {\n return \"error\"\n }\n if (type === \"owner\" && !isOwner) {\n return \"warning\"\n }\n }\n return null\n}\n\nexport const handleProposalStatusMessage = (\n type: \"controller\" | \"owner\" | \"snapshot\" | \"safesnap\",\n isController: boolean,\n isOwner: boolean,\n hasSnapshot: boolean,\n hasValidSnapshot: boolean,\n isSafesnapInstalled: boolean,\n): string | null => {\n if (type === \"snapshot\" && !hasSnapshot) {\n return \"The ENS name should have a Snapshot space created.\"\n }\n if (type === \"snapshot\" && !hasValidSnapshot) {\n return \"Your snapshot settings file is invalid.\"\n }\n if (type === \"controller\" && !isController) {\n return \"The safe must be the controller of the ENS name.\"\n }\n if (type === \"owner\" && !isOwner) {\n return \"The safe is not the owner of the ENS name. We highly recommend transferring the ENS to this safe or enter a different ENS before continuing.\"\n }\n if (type === \"safesnap\" && isSafesnapInstalled) {\n return \"The plugin is already installed on the Snapshot space.\"\n }\n return null\n}\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport {\n Box,\n Button,\n Divider,\n Grid,\n makeStyles,\n // FormControlLabel,\n // Radio,\n // RadioGroup,\n Typography,\n} from \"@material-ui/core\"\n\nimport { Link } from \"components/text/Link\"\nimport React, { useEffect, useState } from \"react\"\n// import useSpace from \"services/snapshot/hooks/useSpace\"\nimport { checkIfIsController, checkIfIsOwner } from \"services/ens\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport ProposalStatus from \"./components/ProposalStatus\"\nimport * as snapshot from \"services/snapshot\"\nimport {\n handleProposalStatus,\n handleProposalStatusMessage,\n} from \"utils/proposalValidation\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ErrorOutlineIcon from \"@material-ui/icons/ErrorOutline\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport { safeAppUrl } from \"utils/url\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n doneIcon: {\n marginRight: 4,\n fill: \"#A8E07E\",\n width: \"16px\",\n },\n errorIcon: {\n marginRight: 4,\n fill: \"rgba(244, 67, 54, 1)\",\n width: \"16px\",\n },\n\n loadingContainer: {\n marginRight: 4,\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 14,\n width: 14,\n border: `1px solid ${colors.tan[300]}`,\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `${colors.tan[300]} !important`,\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n marginRight: 8,\n },\n radio: {\n marginLeft: -2,\n padding: 2,\n \"& ~ .MuiFormControlLabel-label\": {\n fontSize: 12,\n marginLeft: 4,\n },\n \"&$checked\": {\n color: colors.tan[1000],\n },\n },\n checked: {},\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n textFieldSmall: {\n \"& .MuiFormLabel-root\": {\n fontSize: 12,\n },\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n errorContainer: { margin: 8, display: \"flex\", alignItems: \"center\" },\n}))\n\nexport type ProposalSectionData = {\n // proposalType: \"snapshot\" | \"custom\";\n ensName: string\n}\n\nexport const ProposalSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const { safe, provider } = useSafeAppsSDKWithProvider()\n const classes = useStyles()\n // const [proposalType, setProposalType] = useState<\"snapshot\" | \"custom\">(\n // \"snapshot\"\n // );\n const [ensName, setEnsName] = useState(\"\")\n const [ensAddress, setEnsAddress] = useState(\"\")\n const [isOwner, setIsOwner] = useState(false)\n const [isSafesnapInstalled, setIsSafesnapInstalled] = useState(false)\n const [isController, setIsController] = useState(false)\n const [hasSnapshot, setHasSnapshot] = useState(false)\n const [validSnapshot, setValidSnapshot] = useState(false)\n const [loading, setLoading] = useState(false)\n const [ensIsValid, setEnsIsValid] = useState(false)\n\n useEffect(() => {\n if (provider && setupData && setupData.proposal) {\n setEnsName(setupData.proposal.ensName)\n }\n }, [])\n\n useEffect(() => {\n if (ensName) {\n if (ensName.includes(\".eth\")) {\n setEnsIsValid(true)\n setLoading(true)\n const validateInfo = async () => {\n await validEns()\n }\n validateInfo()\n } else {\n setEnsIsValid(false)\n setIsController(false)\n setIsOwner(false)\n }\n }\n }, [ensName])\n\n const validEns = async () => {\n const address = await provider.resolveName(ensName)\n if (address) {\n const snapshotSpace = await snapshot.getSnapshotSpaceSettings(ensName, safe.chainId)\n const snapshotSpaceValidation = snapshot.validateSchema(snapshotSpace)\n const isOwner = await checkIfIsOwner(provider, ensName, safe.safeAddress)\n const isController = await checkIfIsController(provider, ensName, safe.safeAddress)\n const plugins = snapshotSpace?.plugins\n if (plugins) {\n setIsSafesnapInstalled(plugins.safeSnap ? true : false) // comment out for easy testing\n }\n if (snapshotSpaceValidation !== true) {\n console.log(\n \"The current snapshot space is not valid. Valid snapshot space schema. Errors:\",\n )\n console.log(JSON.stringify(snapshot.validateSchema(snapshotSpace), undefined, 2))\n }\n setHasSnapshot(snapshotSpace ? true : false)\n setValidSnapshot(snapshotSpaceValidation === true)\n setIsOwner(isOwner)\n setIsController(isController)\n setEnsAddress(address)\n setLoading(false)\n return\n } else {\n setEnsAddress(\"\")\n setLoading(false)\n setIsOwner(false)\n setIsController(false)\n setHasSnapshot(false)\n setValidSnapshot(false)\n setIsSafesnapInstalled(false)\n return\n }\n }\n\n const collectSectionData = (): ProposalSectionData => ({\n // proposalType,\n ensName,\n })\n\n // const handleChange = (event: React.ChangeEvent) => {\n // setProposalType(\n // (event.target as HTMLInputElement).value as \"snapshot\" | \"custom\"\n // );\n // };\n\n const handleEns = (ens: string) => {\n if (ens === \"\") {\n setIsController(false)\n setIsOwner(false)\n setHasSnapshot(false)\n setValidSnapshot(false)\n setEnsName(\"\")\n } else {\n setEnsName(ens)\n }\n }\n\n return (\n \n \n \n \n \n Configure Proposal Space\n \n \n \n Add your preferred proposal type below to get started. If you're\n unsure, we recommend starting with Snapshot.\n \n \n \n \n Don't have a snapshot space setup yet?{` `}\n \n Get started here.\n \n \n \n \n \n \n \n \n \n \n \n \n Proposal Configuration\n \n \n \n \n {/* Enter your snapshot space ENS domain below to get started. If\n you'd prefer to provide a custom proposal integration,\n select Custom and provide the appropriate URL where the\n proposals can be viewed publicly. */}\n Enter your snapshot space ENS domain below to get started. The Safe must\n be the controller of this ENS domain.\n \n \n {/* For now we're only use snapshot space */}\n {/* \n \n Select your proposal type:\n \n \n \n }\n label=\"Snapshot\"\n />\n \n }\n label=\"Custom\"\n />\n \n */}\n \n handleEns(target.value)}\n label=\"Enter the Snapshot ENS name.\"\n placeholder=\"ex: gnosis.eth\"\n borderStyle=\"double\"\n className={`${classes.textFieldSmall} ${\n ensName.includes(\".eth\") &&\n !loading &&\n (!hasSnapshot || !isController || !isOwner)\n ? classes.inputError\n : classes.input\n }`}\n rightIcon={\n <>\n {loading && (\n \n \n \n )}\n {ensName.includes(\".eth\") &&\n !loading &&\n (!hasSnapshot || !isController || !isOwner) && (\n \n )}\n {ensName.includes(\".eth\") &&\n !loading &&\n hasSnapshot &&\n isController &&\n isOwner && }\n \n }\n />\n
\n
\n\n {ensIsValid && (\n <>\n \n \n \n \n {/* {ensAddress && !isOwner && handleProposalStatus(\"owner\") === \"error\" && (\n \n \n \n )} */}\n \n )}\n
\n
\n
\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Cancel\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n
\n
\n )\n}\n\nexport default ProposalSection\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\";\nimport React from \"react\";\nimport { colors } from \"zodiac-ui-components\";\n\ntype CircleStepProps = {\n label: string;\n number: number;\n onClick: () => void;\n disabled?: boolean;\n};\n\nconst useStyles = makeStyles((theme) => ({\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 25,\n width: 25,\n border: `1px solid ${colors.tan[300]}`,\n background: colors.blue[500],\n },\n label: {\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n}));\n\nexport const CircleStep: React.FC = ({\n label,\n number,\n disabled,\n onClick,\n}) => {\n const classes = useStyles();\n return (\n {\n !disabled && onClick();\n }}>\n \n \n {number}\n \n \n \n {label}\n \n \n );\n};\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors } from \"zodiac-ui-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ClearIcon from \"@material-ui/icons/Clear\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: \"0.9rem\",\n },\n messageError: {\n fontSize: \"0.9rem\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n background: colors.tan[1000],\n },\n loadingContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: `1px solid ${colors.tan[300]}`,\n },\n errorContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n width: \"12px\",\n height: \"12px\",\n color: `#F44336`,\n },\n loading: {\n width: \"12px !important\",\n height: \"12px !important\",\n color: `${colors.tan[300]} !important`,\n },\n doneIcon: {\n fill: \"black\",\n width: \"16px\",\n },\n}))\n\nexport interface StatusLog {\n error: boolean\n msg: string\n}\n\nexport interface SubmittingStatusProps {\n statusLog: StatusLog[]\n}\n\nexport const SubmittingStatus: React.FC = ({ statusLog }) => {\n const classes = useStyles()\n\n return (\n \n {statusLog.map((item, index) => (\n \n \n \n {statusLog.length > index + 1 && !item.error && (\n \n \n \n )}\n {statusLog.length === index + 1 && !item.error && (\n \n \n \n )}\n {statusLog.length === index + 1 && item.error && (\n \n \n \n )}\n \n \n \n {item.msg}\n \n \n \n \n ))}\n \n )\n}\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport { Button, Divider, Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { CircleStep } from \"components/CircleStep\"\nimport React, { useEffect, useState } from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\"\nimport AddIcon from \"@material-ui/icons/Add\"\nimport RemoveIcon from \"@material-ui/icons/Remove\"\nimport { SectionProps, SetupData } from \"views/AddModule/wizards/RealityModule\"\nimport { DelayModule, ModuleType } from \"store/modules/models\"\nimport { AttachModuleForm } from \"views/AddModule/wizards/components/AttachModuleForm\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { OracleSectionData } from \"../Oracle\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport { BigNumber } from \"ethers\"\nimport { unitConversion } from \"components/input/TimeSelect\"\nimport { EXPLORERS_CONFIG } from \"utils/explorers\"\nimport { NETWORK } from \"utils/networks\"\nimport { getSnapshotSpaceUrl } from \"services/snapshot\"\nimport { StatusLog, SubmittingStatus } from \"./components/SubmittingStatus\"\n\ninterface ReviewSectionProps extends SectionProps {\n goToStep: (step: number) => void\n delayModules: DelayModule[]\n setupData: SetupData | undefined\n loading: boolean\n statusLog: StatusLog[]\n}\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n paperTemplateContainer: {\n marginTop: 4,\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n icon: {\n fill: \"white\",\n cursor: \"pointer\",\n },\n collapse: {\n textDecoration: \"underline\",\n cursor: \"pointer\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n textarea: {\n \"& .MuiInputBase-root\": {\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n link: {\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n textDecoration: \"underline\",\n fontWeight: \"bold\",\n },\n label: {\n fontFamily: \"Roboto Mono\",\n fontSize: 12,\n fontWeight: \"bold\",\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n },\n}))\n\nconst SECTIONS = [\n {\n label: \"Proposal\",\n number: 1,\n section: 0,\n },\n {\n label: \"Oracle\",\n number: 2,\n section: 1,\n },\n {\n label: \"Monitoring\",\n number: 3,\n section: 2,\n },\n]\n\nexport const ReviewSection: React.FC = ({\n handleBack,\n handleNext,\n goToStep,\n delayModules,\n setupData,\n loading,\n statusLog,\n}) => {\n const classes = useStyles()\n const { safe } = useSafeAppsSDK()\n const [snapshotSpace, setSnapshotSpace] = useState()\n const [collapseSection, setCollapseSection] = useState(false)\n const [oracleData, setOracleData] = useState(undefined)\n const [delayModule, setDelayModule] = useState(\n delayModules.length === 1 ? delayModules[0].address : \"\",\n )\n const monitoring = setupData && setupData.monitoring\n\n useEffect(() => {\n if (setupData && setupData.proposal) {\n setSnapshotSpace(getSnapshotSpaceUrl(safe.chainId, setupData.proposal.ensName))\n }\n if (setupData && setupData.oracle) {\n setOracleData(setupData.oracle)\n }\n }, [setupData])\n\n return (\n \n \n {!collapseSection && (\n <>\n \n \n \n Review\n \n \n \n Here is an overview of your reality module configuration. Please\n review carefully. Once you've confirmed that the details are\n correct, you can submit the transaction which will add the reality\n module to this safe, and automatically integrate the SafeSnap plugin\n with the snapshot space you've include.\n \n \n \n \n\n \n \n \n\n {SECTIONS.map((item) => (\n \n \n goToStep(item.section)}\n />\n \n\n {item.label === \"Proposal\" && (\n \n Snapshot Space:\n \n {snapshotSpace}\n \n \n )}\n\n {item.label === \"Oracle\" && oracleData && setupData && (\n \n \n \n Template question preview:\n \n \n {setupData.oracle.templateData.templateQuestion}\n \n \n \n \n Oracle Address:\n \n {oracleData.instanceData.instanceAddress}\n \n \n \n \n \n Timeout:\n \n {BigNumber.from(oracleData.delayData.timeout)\n .div(unitConversion[oracleData.delayData.timeoutUnit])\n .toString()}{\" \"}\n {oracleData.delayData.timeoutUnit}\n \n \n \n Cooldown:\n \n {BigNumber.from(oracleData.delayData.cooldown)\n .div(unitConversion[oracleData.delayData.cooldownUnit])\n .toString()}{\" \"}\n {oracleData.delayData.cooldownUnit}\n \n \n \n Expiration:\n \n {BigNumber.from(oracleData.delayData.expiration)\n .div(unitConversion[oracleData.delayData.expirationUnit])\n .toString()}{\" \"}\n {oracleData.delayData.expirationUnit}\n \n \n \n Bond:\n \n {oracleData.bondData.bond} ETH\n \n \n \n \n \n Arbitrator:\n \n {oracleData.arbitratorData.arbitratorOption === 0 &&\n \"No arbitration (highest bond wins)\"}\n {oracleData.arbitratorData.arbitratorOption === 1 && \"Kleros\"}\n \n \n {/* \n Oracle Address:\n \n https://reality.eth/proposal/343293804ji32khfgahfa\n \n */}\n \n \n )}\n\n {item.label === \"Monitoring\" && monitoring && (\n \n \n \n API key/secret:\n Valid\n \n {monitoring.email.length > 0 && (\n \n Emails:\n {monitoring.email.map((email, index) => (\n \n - {email}\n \n ))}\n \n )}\n {monitoring.discordKey !== \"\" && (\n \n Discord:\n \n {monitoring.discordKey}\n \n \n )}\n {monitoring.telegram.botToken !== \"\" && (\n \n Telegram:\n \n Bot token: {monitoring.telegram.botToken}\n \n \n Chat ID: {monitoring.telegram.chatId}\n \n \n )}\n {monitoring.slackKey !== \"\" && (\n \n Slack:\n \n {monitoring.slackKey}\n \n \n )}\n \n \n )}\n\n \n \n \n \n ))}\n\n {delayModules.length >= 1 && (\n \n \n \n \n Deploy Options\n \n setDelayModule(value)}\n type={ModuleType.DELAY}\n />\n \n \n \n )}\n \n )}\n\n {statusLog.length > 0 && (\n setCollapseSection(!collapseSection)}>\n \n \n {!collapseSection ? (\n \n ) : (\n \n )}\n \n \n {!collapseSection ? \"Show Less\" : \"Show More\"}\n \n \n \n )}\n\n {statusLog.length > 0 && (\n \n \n \n \n Setting up Module\n \n \n \n \n \n \n \n )}\n\n \n \n \n \n Back\n \n \n \n \n ) : (\n \n )\n }\n disabled={loading}\n onClick={() => {\n setCollapseSection(true)\n handleNext(setupData)\n }}\n >\n Submit\n \n \n \n \n \n \n )\n}\n\nconst executionModuleDescription = (\n \n This will add a time delay to any transactions created by this module.{\" \"}\n Note that this delay is cumulative with the cooldown set above (e.g. if both\n are set to 24 hours, the cumulative delay before the transaction can be executed will\n be 48 hours).\n \n)\n\nexport default ReviewSection\n","import { Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport Creatable from \"react-select/creatable\"\nimport { Props as MultiSelectProps } from \"react-select\"\n\nexport interface MultiSelectValues {\n label: string\n value: string\n}\n\nconst useStyles = makeStyles((theme) => ({\n paperContainer: {\n background: \"rgba(0, 0, 0, 0.2)\",\n },\n message: {\n fontSize: 12,\n color: \"rgba(244, 67, 54, 1)\",\n },\n}))\n\nconst customStyles = {\n control: (base: any, state: { isFocused: any }) => ({\n ...base,\n background: \"none\",\n border: \"none\",\n fontFamily: \"Roboto Mono !important\",\n color: \"yellow !important\",\n boxShadow: state.isFocused ? null : null,\n \"&:hover\": {\n border: \"none\",\n },\n }),\n option: (base: any) => ({\n ...base,\n color: \"white\",\n backgroundColor: \"#101010\",\n cursor: \"pointer\",\n }),\n menu: (base: any) => ({\n ...base,\n // override border radius to match the box\n borderRadius: 0,\n backgroundColor: \"#101010\",\n // kill the gap\n marginTop: 0,\n }),\n menuList: (base: any) => ({\n ...base,\n // kill the white space on first and last option\n padding: 0,\n }),\n multiValue: (base: any) => ({\n ...base,\n color: \"white !important\",\n background: colors.tan[300],\n maxWidth: \"calc(28% - 4px)\",\n \"&:hover\": {\n background: colors.tan[300],\n },\n \"& > div\": {\n color: `white !important`,\n },\n \"& > div[role=button]:hover\": {\n cursor: \"pointer\",\n color: \"blue\",\n background: colors.tan[500],\n },\n }),\n}\n\ninterface MultiSelectCustomProps extends MultiSelectProps {\n invalidText?: string\n}\n\nexport const MultiSelect: React.FC = (props) => {\n const classes = useStyles()\n return (\n \n \n \n ({\n ...theme,\n colors: {\n ...theme.colors,\n font: \"#101010\",\n primary25: \"#101010\",\n primary: \"#101010\",\n neutral80: \"white\",\n },\n })}\n />\n \n \n {props.invalidText && (\n \n {props.invalidText}\n \n )}\n \n )\n}\n","import { useRef, useEffect } from \"react\"\n\nconst usePrevious = (value: string) => {\n const ref = useRef()\n useEffect(() => {\n ref.current = value\n }, [value])\n return ref.current\n}\nexport default usePrevious\n","import { Box, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport React from \"react\"\nimport { colors } from \"zodiac-ui-components\"\nimport DoneIcon from \"@material-ui/icons/Done\"\nimport ClearIcon from \"@material-ui/icons/Clear\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\n\nconst useStyles = makeStyles((theme) => ({\n message: {\n fontSize: \"0.9rem\",\n },\n messageError: {\n fontSize: \"0.8rem\",\n color: \"rgba(244, 67, 54, 1)\",\n },\n circle: {\n padding: 6,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n background: colors.tan[1000],\n },\n loadingContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: `1px solid ${colors.tan[300]}`,\n },\n errorContainer: {\n padding: 2,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n borderRadius: \"50%\",\n height: 20,\n width: 20,\n border: \"1px solid rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.3)\",\n },\n errorIcon: {\n width: \"12px\",\n height: \"12px\",\n color: `#F44336`,\n },\n loading: {\n width: \"12px !important\",\n height: \"12px !important\",\n color: `${colors.tan[300]} !important`,\n },\n doneIcon: {\n fill: \"black\",\n width: \"16px\",\n },\n}))\n\nexport interface MonitoringStatus {\n status: \"loading\" | \"success\" | \"error\" | null\n message: string | null\n}\n\nexport const MonitoringStatus: React.FC = ({ status, message }) => {\n const classes = useStyles()\n return (\n status && (\n \n \n {status === \"success\" && (\n \n \n \n )}\n {status === \"loading\" && (\n \n \n \n )}\n {status === \"error\" && (\n \n \n \n )}\n \n \n \n {message}\n \n \n \n )\n )\n}\n","import { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\nimport { MultiSelect, MultiSelectValues } from \"components/MultiSelect\"\nimport { Link } from \"components/text/Link\"\nimport usePrevious from \"hooks/usePrevious\"\nimport React, { ChangeEvent, useEffect, useState } from \"react\"\nimport { SectionProps } from \"views/AddModule/wizards/RealityModule\"\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { useMonitoringValidation } from \"../../hooks/useMonitoringValidation\"\nimport { MonitoringStatus } from \"./components/MonitoringStatus\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n inputContainer: {\n width: \"50%\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n textarea: {\n \"& .MuiInputBase-root\": {\n padding: theme.spacing(2),\n background: \"rgba(0, 0, 0, 0.2)\",\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n spinner: {\n width: \"8px !important\",\n height: \"8px !important\",\n color: `${colors.tan[300]} !important`,\n },\n}))\n\nexport interface MonitoringSectionData {\n apiKey: string\n secretKey: string\n email: string[]\n discordKey: string\n telegram: { botToken: string; chatId: string }\n slackKey: string\n}\n\nconst INITIAL_DATA: MonitoringSectionData = {\n apiKey: \"\",\n secretKey: \"\",\n email: [],\n discordKey: \"\",\n telegram: {\n botToken: \"\",\n chatId: \"\",\n },\n slackKey: \"\",\n}\n\nexport const MonitoringSection: React.FC = ({\n handleBack,\n handleNext,\n setupData,\n}) => {\n const classes = useStyles()\n const {\n loading,\n execute: validateCredentials,\n error: invalidCredentials,\n } = useMonitoringValidation()\n const monitoring = setupData?.monitoring\n const [monitoringData, setMonitoringData] = useState(\n monitoring ?? INITIAL_DATA,\n )\n const [emailValues, setEmailValues] = useState([])\n const [invalidEmail, setInvalidEmail] = useState(false)\n const [loadValidations, setLoadValidations] = useState(false)\n\n const { apiKey, secretKey, email, discordKey, slackKey, telegram } = monitoringData\n const previousApiKey = usePrevious(apiKey)\n const previousSecretKey = usePrevious(secretKey)\n\n useEffect(() => {\n if (monitoring && monitoring.email.length) {\n const emails: MultiSelectValues[] = []\n monitoring.email.forEach((item: string) =>\n emails.push({ label: item, value: item }),\n )\n setEmailValues(emails)\n }\n }, [monitoring])\n\n useEffect(() => {\n if (!loading && ![apiKey, secretKey].includes(\"\") && !loadValidations) {\n setLoadValidations(true)\n const executeValidations = async () => {\n await validateCredentials(apiKey, secretKey)\n }\n executeValidations()\n }\n }, [apiKey, secretKey, loading, loadValidations, validateCredentials])\n\n useEffect(() => {\n if (\n (previousApiKey !== apiKey || previousSecretKey !== secretKey) &&\n loadValidations\n ) {\n setLoadValidations(false)\n }\n }, [apiKey, secretKey, previousApiKey, previousSecretKey, loadValidations])\n\n const updateForm = (\n event: ChangeEvent,\n fieldName: string,\n ) => {\n event.preventDefault()\n if ([\"chatId\", \"botToken\"].includes(fieldName)) {\n const telegram = { ...monitoringData.telegram }\n const newValues = { ...telegram, [fieldName]: event.target.value }\n setMonitoringData({\n ...monitoringData,\n telegram: newValues,\n })\n return\n }\n setMonitoringData({ ...monitoringData, [fieldName]: event.target.value })\n }\n\n const isValidEmail = (email: string) => {\n return /\\S+@\\S+\\.\\S+/.test(email)\n }\n\n const handleNewEmail = (values: MultiSelectValues[]) => {\n const newestEmail = values[values.length - 1]?.value\n\n if (isValidEmail(newestEmail) || newestEmail == null) {\n setInvalidEmail(false)\n setEmailValues(values)\n setMonitoringData({ ...monitoringData, email: values.map((_) => _.value) })\n } else {\n setInvalidEmail(true)\n }\n }\n\n const handleStatusMessage = (): string | null => {\n if (loading) return \"Validating API credentials...\"\n if (invalidCredentials)\n return \"The API credentials that you have provided are not valid. Please verify that you have the correct information.\"\n if (!invalidCredentials && typeof invalidCredentials === \"boolean\")\n return \"API credentials are valid.\"\n return null\n }\n\n const handleStatus = (): \"loading\" | \"error\" | \"success\" | null => {\n if (loading) return \"loading\"\n if (invalidCredentials) return \"error\"\n if (!invalidCredentials && typeof invalidCredentials === \"boolean\") return \"success\"\n return null\n }\n\n const isInvalidForm = (): boolean => {\n const { botToken, chatId } = telegram\n if (loading || invalidCredentials) {\n return true\n }\n if ((botToken === \"\" && chatId !== \"\") || (botToken !== \"\" && chatId === \"\")) {\n return true\n }\n if (\n botToken === \"\" &&\n chatId === \"\" &&\n discordKey === \"\" &&\n slackKey === \"\" &&\n email.length === 0\n ) {\n return true\n }\n return false\n }\n\n return (\n \n \n \n \n \n Configure Monitoring\n \n \n \n Setting up an effective monitoring strategy is critical for the security\n of your safe. In order to set up the monitoring for this module,\n you'll need to first{\" \"}\n \n create an Open Zeppelin account.\n \n \n \n \n \n\n \n \n \n\n \n \n \n \n API Configuration\n \n \n \n \n Include the API Key and Secret Key from your Open Zeppelin account below.\n Follow the Open Zeppelin guide {\"\"}\n \n here.\n \n \n \n \n updateForm(e, \"apiKey\")}\n className={invalidCredentials ? classes.inputError : classes.input}\n />\n \n \n updateForm(e, \"secretKey\")}\n borderStyle=\"double\"\n className={invalidCredentials ? classes.inputError : classes.input}\n />\n \n \n \n \n \n \n\n \n \n \n \n Email\n \n \n \n Add as many emails as you'd like.\n \n \n handleNewEmail(values as MultiSelectValues[])}\n value={emailValues}\n />\n \n \n \n\n \n \n \n \n Discord\n \n \n \n \n To add a Discord integration, include the Discord channel's url\n including key below. Find out more{\" \"}\n \n here.\n \n \n \n \n updateForm(e, \"discordKey\")}\n />\n \n \n \n\n \n \n \n \n Telegram\n \n \n \n \n To add a Telegram integration, include the telegram bot token and chat ID\n below. Find out more{\" \"}\n \n here.\n \n \n \n \n \n \n updateForm(e, \"botToken\")}\n />\n \n \n updateForm(e, \"chatId\")}\n />\n \n \n \n \n \n\n \n \n \n \n Slack\n \n \n \n \n To add a Slack integration, include the Slack channel's url including\n key below. Find out more{\" \"}\n \n here.\n \n \n \n \n updateForm(e, \"slackKey\")}\n />\n \n \n \n\n \n \n \n\n \n \n \n handleBack(monitoringData)}\n >\n Back\n \n \n \n handleNext(monitoringData)}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default MonitoringSection\n","import React, { useEffect, useState } from \"react\"\nimport { useRootDispatch, useRootSelector } from \"store\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setRealityModuleScreen,\n} from \"../../../../store/modules\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport {\n Button,\n Divider,\n Grid,\n makeStyles,\n Step,\n StepContent,\n StepLabel,\n Stepper,\n Typography,\n} from \"@material-ui/core\"\nimport { TagList } from \"components/list/TagList\"\nimport { Link } from \"components/text/Link\"\nimport OracleSection, { OracleSectionData } from \"./sections/Oracle\"\nimport ProposalSection, { ProposalSectionData } from \"./sections/Proposal\"\nimport ReviewSection from \"./sections/Review\"\nimport classnames from \"classnames\"\nimport MonitoringSection, { MonitoringSectionData } from \"./sections/Monitoring\"\nimport { setup } from \"./service/setupService\"\nimport { getDelayModules, getModulesList } from \"store/modules/selectors\"\nimport { StatusLog } from \"./sections/Review/components/SubmittingStatus\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nexport interface SectionProps {\n handleNext: (\n stepData: ProposalSectionData | OracleSectionData | MonitoringSectionData | any,\n ) => void\n handleBack: (\n stepData: ProposalSectionData | OracleSectionData | MonitoringSectionData | any,\n ) => void\n setupData: SetupData | undefined\n}\n\nexport type SetupData = {\n proposal: ProposalSectionData\n oracle: OracleSectionData\n monitoring: MonitoringSectionData\n review: any\n}\n\nconst REALITY_MODULE_STEPS: (keyof SetupData)[] = [\n \"proposal\",\n \"oracle\",\n \"monitoring\",\n \"review\",\n]\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n tag: {\n background: theme.palette.secondary.main,\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n paperTitle: {\n margin: 0,\n },\n step: {\n \"& text\": {\n fontFamily: \"Roboto Mono\",\n },\n \"& .step-label\": {\n textTransform: \"capitalize\",\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n \"&.clickable\": {\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n },\n },\n stepperRoot: {\n backgroundColor: \"transparent\",\n border: \"none\",\n padding: theme.spacing(0),\n \"& .MuiStepIcon-active\": {\n color: theme.palette.secondary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n \"& .MuiStepIcon-completed\": {\n background: theme.palette.text.primary,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n color: theme.palette.secondary.main,\n },\n \"& .Mui-disabled .MuiStepIcon-root\": {\n color: theme.palette.primary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n },\n}))\n\nexport const RealityModule: React.FC = () => {\n const classes = useStyles()\n const { sdk: safeSdk, safe: safeInfo, provider } = useSafeAppsSDKWithProvider()\n const delayModules = useRootSelector(getDelayModules)\n const dispatch = useRootDispatch()\n const modulesList = useRootSelector(getModulesList)\n const [modules, setModules] = useState(modulesList.length)\n const [statusLog, setStatusLog] = useState([])\n const [activeStep, setActiveStep] = useState(0)\n const [completed, setCompleted] = useState({\n proposal: false,\n oracle: false,\n monitoring: false,\n review: false,\n })\n const [loading, setLoading] = useState(false)\n // we can keep the user input data here. No need to send it anywhere else (no need for Redux here, this is self contained).\n const [setupData, setSetupData] = useState()\n\n const handleOpenSection = (pageToOpen: number, step: keyof SetupData) => {\n if (completed[step]) {\n setActiveStep(pageToOpen)\n }\n }\n\n const navigate = (nextPage: number, step: keyof SetupData, stepCompleted: boolean) => {\n return (stepData: any) => {\n setActiveStep(nextPage)\n setCompleted({ ...completed, [step]: stepCompleted })\n setSetupData({ ...setupData, [step]: stepData } as SetupData)\n }\n }\n\n const handleDone = async (delayModuleExecutor?: string) => {\n const logger: StatusLog[] = []\n setLoading(true)\n if (setupData == null) {\n setLoading(false)\n throw new Error(\"No setup data\")\n }\n const executorAddress =\n delayModuleExecutor !== \"\" || delayModuleExecutor == null\n ? safeInfo.safeAddress\n : delayModuleExecutor\n\n const statusLogger = (currentStatus: string, error?: Error) => {\n if (error != null) {\n if (error.name === \"OpenError\") {\n logger.push({\n error: true,\n msg:\n error.toString() +\n `This error can be caused by add/track blockers. Please disable any blockers (for instance, the Brave Shield) and try again.`,\n })\n } else {\n logger.push({ error: true, msg: error.toString() })\n }\n throw error\n } else {\n logger.push({ error: false, msg: currentStatus })\n }\n setStatusLog(logger)\n }\n\n try {\n await setup(provider, safeSdk, safeInfo, executorAddress, setupData, statusLogger)\n } catch (error) {\n setLoading(false)\n console.error(error)\n }\n dispatch(fetchPendingModules(safeInfo))\n dispatch(setModuleAdded(true))\n }\n\n useEffect(() => {\n if (loading && modulesList.length > modules) {\n setModules(modulesList.length)\n setLoading(false)\n dispatch(setRealityModuleScreen(false))\n }\n }, [dispatch, loading, modules, modulesList])\n\n return (\n
\n \n \n \n \n \n \n \n Reality Module\n \n \n \n \n \n \n Allows Reality.eth questions to execute a transaction when resolved.{\" \"}\n \n Read more here.\n \n \n \n \n \n \n \n \n \n \n \n Add Reality Module\n \n \n \n dispatch(setRealityModuleScreen(false))}\n >\n Cancel\n \n \n \n \n {REALITY_MODULE_STEPS.map((label, index) => (\n \n handleOpenSection(index, label as keyof SetupData)}\n >\n \n {label}\n {\" \"}\n \n \n {label === \"proposal\" && (\n dispatch(setRealityModuleScreen(false))}\n setupData={setupData}\n />\n )}\n {label === \"oracle\" && (\n \n )}\n {label === \"monitoring\" && (\n \n )}\n {label === \"review\" && (\n \n )}\n \n \n ))}\n \n \n \n \n
\n )\n}\n\nexport default RealityModule\n","import { ethers } from \"ethers\"\n\nconst VOTES_ABI = [\n \"function getVotes(address account) external view returns (uint256)\",\n \"function getPastVotes(address account, uint256 blockNumber) external view returns (uint256)\",\n \"function getPastTotalSupply(uint256 blockNumber) external view returns (uint256)\",\n \"function delegates(address account) external view returns (address)\",\n \"function delegate(address delegatee) external\",\n \"function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external\",\n]\n\nconst RANDOM_VALID_ADDRESS = \"0xD028d504316FEc029CFa36bdc3A8f053F6E5a6e4\"\nconst RANDOM_BLOCK_NUMBER = 1234\n\nexport const isVotesCompilable =\n (provider: ethers.providers.JsonRpcProvider) => async (tokenAddress: string) => {\n const tokenContract = new ethers.Contract(tokenAddress, VOTES_ABI, provider)\n\n try {\n await Promise.all([\n tokenContract.getVotes(RANDOM_VALID_ADDRESS),\n tokenContract.getPastVotes(RANDOM_VALID_ADDRESS, RANDOM_BLOCK_NUMBER),\n tokenContract.getPastTotalSupply(RANDOM_BLOCK_NUMBER),\n tokenContract.callStatic.delegates(RANDOM_VALID_ADDRESS),\n ])\n // eslint-disable-next-line\n tokenContract.functions[\"delegateBySig\"].name\n } catch (e) {\n console.log(e)\n return false\n }\n\n return true\n }\n","import React, { ChangeEvent, Fragment, useEffect, useState } from \"react\"\nimport {\n Button,\n Divider,\n FormControlLabel,\n FormHelperText,\n Grid,\n makeStyles,\n Radio,\n RadioGroup,\n Typography,\n} from \"@material-ui/core\"\n\nimport { colors, ZodiacPaper, ZodiacTextField } from \"zodiac-ui-components\"\nimport { ethers } from \"ethers\"\nimport { GovernorWizardProps } from \"../..\"\nimport { isVotesCompilable } from \"../../service/tokenValidation\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n radio: {\n marginLeft: -2,\n padding: 2,\n \"& ~ .MuiFormControlLabel-label\": {\n fontSize: 12,\n marginLeft: 4,\n },\n \"&$checked\": {\n color: colors.tan[1000],\n },\n },\n checked: {},\n errorColor: {\n color: \"rgba(244, 67, 54, 1)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n inputError: {\n \"& .MuiInputBase-root\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n background: \"rgba(244, 67, 54, 0.1)\",\n \"&::before\": {\n borderColor: \"rgba(244, 67, 54, 0.3)\",\n },\n },\n },\n}))\n\nexport type TokenFields =\n | \"tokenAddress\"\n | \"tokenName\"\n | \"tokenSymbol\"\n | \"initialAmount\"\n | \"tokenConfiguration\"\n\nexport type TokenConfigurationType = \"existingToken\" | \"ERC20\" | \"ERC721\"\n\nexport type TokenSectionData = {\n tokenAddress: string | undefined\n tokenName: string\n tokenSymbol: string\n initialAmount: number\n tokenConfiguration: TokenConfigurationType\n}\n\nexport const TOKEN_INITIAL_VALUES: TokenSectionData = {\n tokenAddress: undefined,\n tokenName: \"\",\n tokenSymbol: \"\",\n initialAmount: 100000,\n tokenConfiguration: \"existingToken\",\n}\n\nexport const TokenSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const classes = useStyles()\n const token = setupData.token\n const [tokenData, setTokenData] = useState(token)\n const [isValidTokenAddress, setIsValidTokenAddress] = useState(false)\n\n const { provider } = useSafeAppsSDKWithProvider()\n const tokenAddressValidator = isVotesCompilable(provider)\n const { tokenAddress, tokenName, tokenSymbol, tokenConfiguration, initialAmount } =\n tokenData\n\n const collectSectionData = (): TokenSectionData => ({\n tokenAddress,\n tokenName,\n tokenSymbol,\n tokenConfiguration,\n initialAmount,\n })\n\n const handleInputClasses = () => {\n if ([tokenAddress].includes(\"\")) {\n return classes.input\n }\n if (![tokenAddress].includes(\"\" || undefined) && !isValidTokenAddress) {\n return classes.inputError\n }\n return classes.input\n }\n\n const handleChange = (event: React.ChangeEvent) => {\n setTokenData({\n ...tokenData,\n tokenConfiguration: (event.target as HTMLInputElement)\n .value as TokenConfigurationType,\n })\n }\n\n const updateFields = (\n event: ChangeEvent,\n fieldName: TokenFields,\n ) => {\n setTokenData({ ...tokenData, [fieldName]: event.target.value })\n }\n\n useEffect(() => {\n if (![tokenAddress].includes(\"\" || undefined)) {\n const validations = async () => {\n if (\n ethers.utils.isAddress(tokenAddress as string) &&\n (await tokenAddressValidator(tokenAddress as string))\n ) {\n setIsValidTokenAddress(true)\n } else {\n setIsValidTokenAddress(false)\n }\n }\n validations()\n }\n }, [tokenAddress, tokenAddressValidator])\n\n const handleValidation = (): boolean => {\n if (tokenConfiguration === \"existingToken\") {\n return !isValidTokenAddress || [tokenAddress].includes(\"\") ? true : false\n }\n if (tokenConfiguration === \"ERC721\" || tokenConfiguration === \"ERC20\") {\n return [tokenName, tokenSymbol].includes(\"\") ? true : false\n }\n return true\n }\n\n const isValid = handleValidation()\n return (\n \n \n \n \n \n Setup Token for Voting\n \n \n \n The following token will enable members to vote on proposals with this\n governor contract. The token must be ERC20Votes compatible.\n \n \n \n \n \n \n Token Configuration\n \n \n \n \n Do you have an existing token in your safe that you'd like to use as the\n token for voting in this contract?\n \n \n \n }\n label=\"Existing Token\"\n />\n \n }\n label=\"Deploy a new ERC20 for voting.\"\n />\n \n }\n label=\"Deploy a new ERC721 for voting.\"\n />\n \n \n\n {tokenConfiguration === \"existingToken\" && (\n \n updateFields(e, \"tokenAddress\")}\n />\n {![tokenAddress].includes(\"\" || undefined) && !isValidTokenAddress && (\n \n Please provide a valid address\n \n )}\n \n )}\n\n {(tokenConfiguration === \"ERC20\" || tokenConfiguration === \"ERC721\") && (\n \n \n \n \n updateFields(e, \"tokenName\")}\n tooltipMsg=\"The same as collection name in OpenSea, e.g. Nouns\"\n />\n \n \n updateFields(e, \"tokenSymbol\")}\n tooltipMsg=\"e.g. LOOT\"\n />\n \n \n \n {/* {tokenConfiguration === \"ERC20\" && (\n \n updateFields(e, \"initialAmount\")}\n tooltipMsg=\"The number of tokens you want to mint when the contract is deployed. These will be sent straight to the safe.\"\n />\n \n )} */}\n \n )}\n\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Cancel\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default TokenSection\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport { Button, Divider, Grid, Link, makeStyles, Typography } from \"@material-ui/core\"\nimport { CircleStep } from \"components/CircleStep\"\nimport React from \"react\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\"\nimport { Loader } from \"@gnosis.pm/safe-react-components\"\nimport { GovernorWizardProps, SetupData } from \"../..\"\nimport { EXPLORERS_CONFIG } from \"utils/explorers\"\nimport { NETWORK } from \"utils/networks\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\n\ninterface OZReviewSectionProps extends GovernorWizardProps {\n goToStep: (step: number) => void\n setupData: SetupData\n loading: boolean\n}\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n\n icon: {\n fill: \"white\",\n cursor: \"pointer\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n label: {\n fontFamily: \"Roboto Mono, monospace\",\n fontSize: 12,\n fontWeight: \"bold\",\n },\n loading: {\n width: \"15px !important\",\n height: \"15px !important\",\n },\n value: {\n fontFamily: \"Roboto Mono, monospace\",\n fontWeight: \"bold\",\n color: \"white\",\n },\n underline: {\n textDecoration: \"underline\",\n },\n}))\n\nconst SECTIONS = [\n {\n label: \"Token\",\n number: 1,\n section: 0,\n },\n {\n label: \"Governor\",\n number: 2,\n section: 1,\n },\n]\n\nexport const OZReviewSection: React.FC = ({\n handleBack,\n handleNext,\n goToStep,\n setupData,\n loading,\n}) => {\n const classes = useStyles()\n const token = setupData?.token\n const governor = setupData?.governor\n const { safe } = useSafeAppsSDK()\n\n return (\n \n \n \n \n \n Review\n \n \n \n Please take a final look at your OZ Governor Module details.\n \n \n \n \n\n \n \n \n\n {SECTIONS.map((item) => (\n \n \n goToStep(item.section)}\n />\n \n\n {item.label === \"Token\" && token && (\n <>\n {token.tokenAddress && (\n \n Voting Token:\n \n {token.tokenAddress}\n \n \n )}\n {token.tokenName && (\n \n Token Name:\n {token.tokenName}\n \n )}\n {token.tokenSymbol && (\n \n Token Symbol:\n {token.tokenSymbol}\n \n )}\n {/* {token.tokenConfiguration === \"ERC20\" && token.initialAmount && (\n \n Initial Amount:\n \n {token.initialAmount}\n \n \n )} */}\n \n )}\n {item.label === \"Governor\" && governor && (\n <>\n \n Name:\n {governor.daoName}\n \n \n Voting Delay:\n \n {governor.votingDelayInBlocks} blocks\n \n \n \n Voting Period:\n \n {governor.votingPeriodInBlocks} blocks\n \n \n \n Proposal Threshold:\n \n {governor.proposalThreshold}%\n \n \n \n Quorum (%):\n \n {governor.quorumPercent}%\n \n \n \n )}\n\n \n \n \n \n ))}\n\n \n \n \n \n Back\n \n \n \n \n ) : (\n \n )\n }\n onClick={() => {\n handleNext(setupData)\n }}\n >\n Deploy and Enable Module\n \n \n \n \n \n \n )\n}\n\nexport default OZReviewSection\n","import { deployAndSetUpModule, KnownContracts } from \"@gnosis.pm/zodiac\"\nimport { ethers } from \"ethers\"\nimport { enableModule, TxWitMeta } from \"services\"\nimport SafeAppsSDK from \"@gnosis.pm/safe-apps-sdk\"\n\nconst MULTI_SEND_CONTRACT = process.env.REACT_APP_MULTI_SEND_CONTRACT\nif (MULTI_SEND_CONTRACT == null) {\n throw new Error(\"The MULTI_SEND_CONTRACT environment variable is not set.\")\n}\n\nexport type CreateTokenArgs = {\n name: string\n symbol: string\n kind: \"ERC20\" | \"ERC721\"\n}\n\nconst deployOzGovernorModule = async (\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n tokenAddress: string,\n name: string,\n votingDelayInBlocks: number,\n votingPeriodInBlocks: number,\n proposalThreshold: number,\n quorumPercent: number,\n): Promise => {\n // input validation\n if (safeAddress == null) {\n throw new Error(\"No safe address provided\")\n }\n if (tokenAddress == null) {\n throw new Error(\"No token address provided\")\n }\n if (name == null) {\n throw new Error(\"No name provided\")\n }\n if (votingDelayInBlocks == null) {\n throw new Error(\"No voting delay provided\")\n }\n if (votingPeriodInBlocks == null) {\n throw new Error(\"No voting period provided\")\n }\n if (proposalThreshold == null) {\n throw new Error(\"No proposal threshold provided\")\n }\n if (quorumPercent == null) {\n throw new Error(\"No quorum percent provided\")\n }\n if (quorumPercent > 100 || quorumPercent < 0) {\n throw new Error(\"Quorum percent must be between 0 and 100\")\n }\n\n const initData = {\n values: [\n safeAddress, // owner\n safeAddress, // target\n MULTI_SEND_CONTRACT, // multisend\n tokenAddress, // token\n name, // name\n votingDelayInBlocks.toString(), // votingDelay\n votingPeriodInBlocks.toString(), // votingPeriod\n proposalThreshold.toString(), // proposalThreshold\n quorumPercent.toString(), // quorum\n \"0\", // initialVoteExtension\n ],\n types: [\n \"address\",\n \"address\",\n \"address\",\n \"address\",\n \"string\",\n \"uint256\",\n \"uint256\",\n \"uint256\",\n \"uint256\",\n \"uint64\",\n ],\n }\n\n const saltNonce = Date.now().toString()\n const chainId = (await provider.getNetwork()).chainId\n\n const { transaction: deploymentTx, expectedModuleAddress: expectedAddress } =\n deployAndSetUpModule(\n KnownContracts.OZ_GOVERNOR,\n initData,\n provider,\n chainId,\n saltNonce,\n )\n\n return {\n txs: [\n {\n ...deploymentTx,\n value: deploymentTx.value.toString(),\n },\n ], // transactions to be executed by the safe\n meta: { expectedAddress }, // any additional data needed from the setup process\n }\n}\n\nexport const deployVotesTokenTx = async (\n provider: ethers.providers.JsonRpcProvider,\n safeAddress: string,\n tokenName: string,\n tokenSymbol: string,\n kind: \"ERC20\" | \"ERC721\",\n): Promise => {\n if (safeAddress == null) {\n throw new Error(\"No safe address provided\")\n }\n if (tokenName == null) {\n throw new Error(\"No token name provided\")\n }\n if (tokenSymbol == null) {\n throw new Error(\"No token symbol provided\")\n }\n if (kind !== \"ERC20\" && kind !== \"ERC721\") {\n throw new Error(\"Invalid token kind\")\n }\n\n const initData = {\n values: [\n safeAddress, // owner\n tokenName, // name\n tokenSymbol, // symbol\n ],\n types: [\"address\", \"string\", \"string\"],\n }\n\n const saltNonce = Date.now().toString()\n const chainId = (await provider.getNetwork()).chainId\n\n const { transaction: deploymentTx, expectedModuleAddress: expectedAddress } =\n deployAndSetUpModule(\n kind === \"ERC20\" ? KnownContracts.ERC20_VOTES : KnownContracts.ERC721_VOTES,\n initData,\n provider,\n chainId,\n saltNonce,\n )\n\n return {\n txs: [\n {\n ...deploymentTx,\n value: deploymentTx.value.toString(),\n },\n ], // transactions to be executed by the safe\n meta: { expectedAddress }, // any additional data needed from the setup process\n }\n}\n\nexport const deployAndEnableOzGovernorModule = async (\n provider: ethers.providers.JsonRpcProvider,\n safeSdk: SafeAppsSDK,\n safeAddress: string,\n name: string,\n votingDelayInBlocks: number,\n votingPeriodInBlocks: number,\n proposalThreshold: number,\n quorumPercent: number,\n tokenAddress?: string,\n createTokenArgs?: CreateTokenArgs,\n) => {\n if (tokenAddress == null && createTokenArgs == null) {\n throw new Error(\"No token address or create token args provided\")\n } else if (tokenAddress != null && createTokenArgs != null) {\n throw new Error(\"Both token address and create token args provided\")\n }\n const txs = []\n if (createTokenArgs != null) {\n const { txs: deployTokenTxs, meta } = await deployVotesTokenTx(\n provider,\n safeAddress,\n createTokenArgs.name,\n createTokenArgs.symbol,\n createTokenArgs.kind,\n )\n txs.push(...deployTokenTxs)\n\n if (meta?.expectedAddress == null) {\n throw new Error(\"No expected address returned from token deployment\")\n }\n tokenAddress = meta.expectedAddress\n }\n\n if (tokenAddress == null) {\n throw new Error(\n \"No token address provided. Should not be possible. Either the token address should be provided or a new token should be deployed.\",\n )\n }\n\n const { txs: deployOzGovernorTxs, meta } = await deployOzGovernorModule(\n provider,\n safeAddress,\n tokenAddress,\n name,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n )\n txs.push(...deployOzGovernorTxs)\n if (meta?.expectedAddress == null) {\n throw new Error(\"The expected value is missing\")\n }\n const enableModuleTx = enableModule(safeAddress, meta.expectedAddress)\n txs.push(enableModuleTx)\n\n return safeSdk.txs.send({ txs: txs }).catch((e) => {\n console.error(e)\n throw new Error(\"Error when proposing transactions to the Safe\")\n })\n}\n","var _circle, _circle2, _circle3, _circle4, _circle5, _circle6;\n\nvar _excluded = [\"svgRef\", \"title\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React from \"react\";\n\nvar SvgGripIcon = function SvgGripIcon(_ref) {\n var svgRef = _ref.svgRef,\n title = _ref.title,\n props = _objectWithoutProperties(_ref, _excluded);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 9,\n height: 16,\n viewBox: \"0 0 9 16\",\n fill: \"none\",\n ref: svgRef\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", null, title) : null, _circle || (_circle = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 2,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle2 || (_circle2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 14,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle3 || (_circle3 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1.5,\n cy: 8,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle4 || (_circle4 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 2,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle5 || (_circle5 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 14,\n r: 1.5,\n fill: \"#B2B5B2\"\n })), _circle6 || (_circle6 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 7.5,\n cy: 8,\n r: 1.5,\n fill: \"#B2B5B2\"\n })));\n};\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(function (props, ref) {\n return /*#__PURE__*/React.createElement(SvgGripIcon, _extends({\n svgRef: ref\n }, props));\n});\nexport default __webpack_public_path__ + \"static/media/grip-icon.27ae46ee.svg\";\nexport { ForwardRef as ReactComponent };","import React, { ChangeEvent, useState } from \"react\"\nimport { Button, Divider, Grid, makeStyles, Typography } from \"@material-ui/core\"\n\nimport { colors, ZodiacPaper, ZodiacSlider, ZodiacTextField } from \"zodiac-ui-components\"\nimport { GovernorWizardProps } from \"../..\"\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n paperContainer: {\n padding: theme.spacing(2),\n },\n textSubdued: {\n color: \"rgba(255 255 255 / 70%)\",\n },\n input: {\n \"& .MuiInputBase-root\": {\n borderColor: colors.tan[300],\n \"&::before\": {\n borderColor: colors.tan[300],\n },\n },\n },\n}))\n\nexport type GovernorSectionData = {\n daoName: string\n votingDelayInBlocks: number\n votingPeriodInBlocks: number\n proposalThreshold: number\n quorumPercent: number\n}\n\ntype GovernorFields =\n | \"daoName\"\n | \"votingDelay\"\n | \"votingPeriod\"\n | \"proposalThreshold\"\n | \"quorumPercent\"\n\nexport const GOVERNOR_INITIAL_VALUES: GovernorSectionData = {\n daoName: \"\",\n votingDelayInBlocks: 0,\n votingPeriodInBlocks: 50400,\n proposalThreshold: 0,\n quorumPercent: 4,\n}\n\nexport const GovernorSection: React.FC = ({\n handleNext,\n handleBack,\n setupData,\n}) => {\n const classes = useStyles()\n const governor = setupData.governor\n const [governorData, setGovernorData] = useState(governor)\n\n const updateFields = (\n event: ChangeEvent,\n fieldName: GovernorFields,\n ) => {\n setGovernorData({ ...governorData, [fieldName]: event.target.value })\n }\n\n const collectSectionData = (): GovernorSectionData => governorData\n const {\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n } = governorData\n\n const nextValidations = (): boolean => {\n if (![daoName].includes(\"\") && quorumPercent >= 0 && quorumPercent <= 100) {\n return false\n }\n return true\n }\n return (\n \n \n \n \n \n Setup OZ Governor Contract\n \n \n \n Configure your governor contract. It can always be changed later, so\n don't worry too much about getting it perfect the first time.\n \n \n \n \n \n updateFields(e, \"daoName\")}\n />\n \n\n \n \n \n \n Voting Delay Configurations\n \n \n \n \n Configure a delay modifier to determine the duration required before\n voting (Cooldown), and the amount of time that the proposal will be valid\n (Expiration).\n \n \n \n \n \n \n \n {\n setGovernorData({\n ...governorData,\n votingDelayInBlocks: parseInt(event.target.value),\n })\n }}\n tooltipMsg=\"The time between proposal submission and when voting starts.\"\n />\n \n \n {\n setGovernorData({\n ...governorData,\n votingPeriodInBlocks: parseInt(event.target.value),\n })\n }}\n tooltipMsg=\"The number of blocks between when a proposal's voting period starts and ends.\"\n />\n \n \n \n \n \n \n \n Voting Thresholds\n \n \n \n \n \n updateFields(e, \"proposalThreshold\")}\n />\n \n \n {\n if (typeof value === \"number\" && quorumPercent !== value && value >= 0) {\n setGovernorData({\n ...governorData,\n quorumPercent: value,\n })\n }\n }}\n />\n \n\n \n \n \n \n \n \n handleBack(collectSectionData())}\n >\n Back\n \n \n \n handleNext(collectSectionData())}\n >\n Next\n \n \n \n \n \n \n )\n}\n\nexport default GovernorSection\n","import React, { useState } from \"react\"\nimport { BadgeIcon, colors, ZodiacPaper } from \"zodiac-ui-components\"\nimport {\n Button,\n Divider,\n Grid,\n makeStyles,\n Step,\n StepContent,\n StepLabel,\n Stepper,\n Typography,\n} from \"@material-ui/core\"\nimport { Link } from \"components/text/Link\"\nimport classnames from \"classnames\"\nimport { useRootDispatch } from \"store\"\nimport {\n fetchPendingModules,\n setModuleAdded,\n setOzGovernorModuleScreen,\n} from \"store/modules\"\nimport TokenSection, {\n TokenSectionData,\n TOKEN_INITIAL_VALUES,\n} from \"../OzGovernor/sections/Token\"\nimport OZReviewSection from \"./sections/Review\"\nimport {\n CreateTokenArgs,\n deployAndEnableOzGovernorModule,\n} from \"./service/moduleDeployment\"\nimport useSafeAppsSDKWithProvider from \"hooks/useSafeAppsSDKWithProvider\"\nimport GovernorSection, {\n GovernorSectionData,\n GOVERNOR_INITIAL_VALUES,\n} from \"./sections/Governor\"\n\nexport interface GovernorWizardProps {\n handleNext: (stepData: TokenSectionData | GovernorSectionData | any) => void\n handleBack: (stepData: TokenSectionData | GovernorSectionData | any) => void\n setupData: SetupData\n}\n\nexport type SetupData = {\n token: TokenSectionData\n governor: GovernorSectionData\n review: any\n}\n\nexport const OZ_GOVERNOR_MODULE_STEPS: (keyof SetupData)[] = [\n \"token\",\n \"governor\",\n \"review\",\n]\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n padding: theme.spacing(1.5),\n overflowY: \"auto\",\n },\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n },\n\n paperContainer: {\n padding: theme.spacing(2),\n },\n paperTitle: {\n margin: 0,\n },\n step: {\n \"& text\": {\n fontFamily: \"Roboto Mono\",\n },\n \"& .step-label\": {\n textTransform: \"capitalize\",\n display: \"inline\",\n fontFamily: \"Roboto Mono\",\n \"&.clickable\": {\n cursor: \"pointer\",\n \"&:hover\": {\n textDecoration: \"underline\",\n },\n },\n },\n },\n stepperRoot: {\n backgroundColor: \"transparent\",\n border: \"none\",\n padding: theme.spacing(0),\n \"& .MuiStepIcon-active\": {\n color: theme.palette.secondary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n \"& .MuiStepIcon-completed\": {\n background: theme.palette.text.primary,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n color: theme.palette.secondary.main,\n },\n \"& .Mui-disabled .MuiStepIcon-root\": {\n color: theme.palette.primary.main,\n border: `1px solid ${colors.tan[300]}`,\n borderRadius: \"100%\",\n },\n },\n}))\n\nexport const OzGovernorModule: React.FC = () => {\n const classes = useStyles()\n const { sdk: safeSdk, safe: safeInfo, provider } = useSafeAppsSDKWithProvider()\n const dispatch = useRootDispatch()\n const [activeStep, setActiveStep] = useState(0)\n const [loading, setLoading] = useState(false)\n const [completed, setCompleted] = useState({\n token: false,\n governor: false,\n review: false,\n })\n // we can keep the user input data here. No need to send it anywhere else (no need for Redux here, this is self contained).\n const [setupData, setSetupData] = useState({\n token: TOKEN_INITIAL_VALUES,\n governor: GOVERNOR_INITIAL_VALUES,\n review: {},\n })\n\n const handleOpenSection = (pageToOpen: number, step: keyof SetupData) => {\n if (completed[step]) {\n setActiveStep(pageToOpen)\n }\n }\n\n const navigate = (nextPage: number, step: keyof SetupData, stepCompleted: boolean) => {\n return (stepData: any) => {\n setActiveStep(nextPage)\n setCompleted({ ...completed, [step]: stepCompleted })\n setSetupData({ ...setupData, [step]: stepData } as SetupData)\n }\n }\n\n const handleDone = async () => {\n setLoading(true)\n if (setupData == null) {\n setLoading(false)\n throw new Error(\"No setup data\")\n }\n const { tokenAddress, tokenSymbol, tokenConfiguration, tokenName } = setupData.token\n const {\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n } = setupData.governor\n try {\n let createTokenArgs: CreateTokenArgs | undefined = undefined\n\n if (tokenConfiguration === \"ERC20\" || tokenConfiguration === \"ERC721\") {\n createTokenArgs = {\n name: tokenName,\n symbol: tokenSymbol,\n kind: tokenConfiguration as \"ERC20\" | \"ERC721\",\n }\n }\n\n const setup = await deployAndEnableOzGovernorModule(\n provider,\n safeSdk,\n safeInfo.safeAddress,\n daoName,\n votingDelayInBlocks,\n votingPeriodInBlocks,\n proposalThreshold,\n quorumPercent,\n tokenAddress,\n createTokenArgs,\n )\n if (setup.safeTxHash) {\n dispatch(fetchPendingModules(safeInfo))\n dispatch(setModuleAdded(true))\n }\n } catch (error) {\n setLoading(false)\n console.error(error)\n }\n }\n\n return (\n
\n \n \n \n \n \n \n \n Governor Module\n \n \n \n \n \n Enables an Open Zeppelin Governor contract as a module.{\" \"}\n \n Read more here.\n \n \n \n \n \n \n \n \n \n \n \n Add Governor Module\n \n \n \n dispatch(setOzGovernorModuleScreen(false))}\n >\n Cancel\n \n \n \n \n {OZ_GOVERNOR_MODULE_STEPS.map((label, index) => (\n \n handleOpenSection(index, label as keyof SetupData)}\n >\n \n {label}\n {\" \"}\n \n \n {label === \"token\" && (\n dispatch(setOzGovernorModuleScreen(false))}\n setupData={setupData}\n />\n )}\n {label === \"governor\" && (\n \n )}\n {label === \"review\" && (\n \n )}\n \n \n ))}\n \n \n \n \n
\n )\n}\n","import ModuleDetails from \"./views/ModuleDetails\"\nimport React from \"react\"\nimport { useRootSelector } from \"./store\"\nimport { getCurrentModule, getCurrentPendingModule } from \"./store/modules/selectors\"\nimport AddModules from \"./views/AddModule\"\nimport { ModulePendingTransaction } from \"./views/ModuleDetails/ModulePendingTransaction\"\nimport RealityModule from \"views/AddModule/wizards/RealityModule\"\nimport { OzGovernorModule } from \"views/AddModule/wizards/OzGovernor\"\n\n\nexport const Views: React.FC = () => {\n const currentModule = useRootSelector(getCurrentModule)\n const currentPendingModule = useRootSelector(getCurrentPendingModule)\n const loadingModules = useRootSelector((state) => state.modules.loadingModules)\n const showRealityModule = useRootSelector((state) => state.modules.realityModuleScreen)\n const showOzGovernorModule = useRootSelector((state) => state.modules.OzGovernorModuleScreen)\n\n if (currentModule) {\n return \n }\n\n if (currentPendingModule) {\n return \n }\n\n if (showRealityModule) {\n return \n }\n\n if (showOzGovernorModule) {\n return \n }\n\n if (!loadingModules) {\n return \n }\n\n return null\n}\n","import React from \"react\"\nimport { Row } from \"../../components/layout/Row\"\nimport { Badge, makeStyles, Typography } from \"@material-ui/core\"\nimport { BadgeIcon, colors, doubleBorder, ZodiacPaper } from \"zodiac-ui-components\"\nimport classNames from \"classnames\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport { getTransactions } from \"../../store/transactionBuilder/selectors\"\nimport { openTransactionBuilder } from \"../../store/transactionBuilder\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n marginBottom: theme.spacing(2),\n },\n container: {\n \"&.MuiPaper-root\": {\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n header: {\n \"&.MuiPaper-root\": {\n padding: theme.spacing(0.5, 2, 0.5, 0.5),\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n txBuilder: {\n \"&.MuiPaper-root\": {\n padding: theme.spacing(0.5, 0.5, 0.5, 2),\n cursor: \"pointer\",\n transition: \"0.2s ease all\",\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n \"&:hover\": {\n background: \"rgba(217, 212, 173, 0.15)\",\n },\n },\n },\n img: {\n display: \"block\",\n width: 36,\n height: 36,\n },\n title: {\n marginLeft: theme.spacing(1),\n },\n bagIcon: {\n marginLeft: theme.spacing(2),\n stroke: \"white\",\n },\n badge: {\n color: theme.palette.common.white,\n display: \"flex\",\n position: \"relative\",\n transform: \"none\",\n textAlign: \"center\",\n background: \"none\",\n fontSize: 16,\n },\n badgeRoot: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n height: 36,\n width: 36,\n borderRadius: 60,\n border: `1px solid ${colors.tan[300]}`,\n padding: theme.spacing(0.5),\n },\n txBuilderTitle: {\n marginRight: theme.spacing(3),\n },\n circleIconContainer: {\n padding: theme.spacing(0.5),\n },\n banner: {\n \"&.MuiPaper-root\": {\n flexGrow: 1,\n position: \"relative\",\n borderWidth: 1,\n borderColor: colors.tan[300],\n backgroundColor: colors.tan[100],\n margin: theme.spacing(0, 2),\n \"&::before\": doubleBorder(-5, colors.tan[300]),\n },\n },\n}))\n\nexport const Header = () => {\n const classes = useStyles()\n const dispatch = useRootDispatch()\n const transaction = useRootSelector(getTransactions)\n\n const handleOpen = () => dispatch(openTransactionBuilder())\n\n return (\n \n \n \n \n Zodiac\n \n \n \n \n Bundle Transactions\n \n \n \n \n \n )\n}\n\nexport default Header\n","import React from \"react\";\nimport { Box, makeStyles } from \"@material-ui/core\";\nimport { Icon } from \"@gnosis.pm/safe-react-components\";\nimport { ActionButton } from \"../../../components/ActionButton\";\n\nexport interface TransactionBlockHeaderButtonsProps {\n edit?: boolean;\n disabled?: boolean;\n onEdit?(): void;\n onDelete?(): void;\n onSave?(): void;\n onCancel?(): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n icon: {\n color: theme.palette.primary.main,\n width: 20,\n height: 20,\n },\n iconContainer: {\n height: 54,\n cursor: \"pointer\",\n padding: theme.spacing(2, 0.5),\n marginRight: theme.spacing(1),\n },\n button: {\n marginRight: theme.spacing(1.5),\n color: theme.palette.text.secondary,\n },\n label: {\n color: theme.palette.text.primary,\n },\n}));\n\nexport const TransactionBlockHeaderButtons = ({\n edit = false,\n disabled = false,\n onCancel,\n onEdit,\n onSave,\n onDelete,\n}: TransactionBlockHeaderButtonsProps) => {\n const classes = useStyles();\n\n if (edit) {\n return (\n <>\n \n Save Changes\n \n \n Cancel\n \n \n );\n }\n\n return (\n <>\n \n \n \n \n \n \n \n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { ZodiacPaper } from \"zodiac-ui-components\";\n\ninterface DisplayFieldProps {\n label: string;\n value?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n borderRadius: 8,\n },\n label: {\n marginBottom: theme.spacing(0.5),\n },\n field: {\n padding: theme.spacing(1, 0, 1, 1),\n },\n}));\n\nexport const DisplayField = ({ label, value }: DisplayFieldProps) => {\n const classes = useStyles();\n return (\n
\n \n {label}\n \n \n {value}\n \n
\n );\n};\n","import React from \"react\";\nimport { FunctionFragment } from \"@ethersproject/abi\";\nimport { Grid } from \"@material-ui/core\";\nimport {\n ParamInput,\n ParamInputProps,\n} from \"../../../components/ethereum/ParamInput\";\nimport { DisplayField } from \"../../../components/input/DisplayField\";\nimport { formatDisplayParamValue } from \"../../../utils/contracts\";\n\nexport type TransactionBlockFieldsProps = Edit extends false\n ? {\n edit: Edit;\n func: FunctionFragment;\n params: any[];\n }\n : {\n edit: Edit;\n paramInputProps: ParamInputProps[];\n };\n\nexport const TransactionBlockFields = (props: TransactionBlockFieldsProps) => {\n const fields = props.edit\n ? props.paramInputProps.map((props, index) => (\n \n \n \n ))\n : props.func.inputs.map((param, index) => (\n \n \n \n ));\n\n return (\n \n {fields}\n \n );\n};\n","import React from \"react\";\nimport { Chip, ChipProps, makeStyles } from \"@material-ui/core\";\nimport { HashInfo } from \"./HashInfo\";\nimport { shortAddress } from \"../../utils/string\";\n\ninterface AddressChipProps extends ChipProps {\n address: string;\n name?: string;\n}\n\nconst useStyles = makeStyles((theme) => ({\n name: {\n marginRight: theme.spacing(1),\n },\n avatar: {\n \"& img\": {\n width: 20,\n height: 20,\n },\n },\n}));\n\nexport const AddressChip = ({ address, name, ...props }: AddressChipProps) => {\n const classes = useStyles();\n const label = (\n <>\n {name ? {name} : null}\n {shortAddress(address)}\n \n );\n return (\n \n }\n label={label}\n />\n );\n};\n","import React from \"react\";\nimport classNames from \"classnames\";\nimport { Box, Chip, makeStyles } from \"@material-ui/core\";\nimport { ArrowIcon } from \"../../../components/icons/ArrowIcon\";\nimport { AddressChip } from \"../../../components/ethereum/AddressChip\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { Grow } from \"../../../components/layout/Grow\";\n\nconst useStyles = makeStyles((theme) => ({\n title: {\n padding: theme.spacing(2, 0.5, 2, 0),\n marginRight: theme.spacing(1),\n display: \"flex\",\n alignItems: \"center\",\n flexDirection: \"row\",\n flexGrow: 1,\n },\n clickable: {\n cursor: \"pointer\",\n },\n moduleChip: {\n marginRight: theme.spacing(1),\n fontSize: 14,\n },\n}));\n\nexport interface TransactionBlockHeaderTitleProps {\n edit: boolean;\n open: boolean;\n transaction: Transaction;\n\n onToggle(): void;\n}\n\nexport const TransactionBlockHeaderTitle = ({\n edit,\n open,\n transaction,\n onToggle,\n}: TransactionBlockHeaderTitleProps) => {\n const classes = useStyles();\n return (\n \n {transaction.module ? (\n \n ) : null}\n {transaction.func.name}} />\n \n {!edit ? : null}\n \n );\n};\n","import React from \"react\";\nimport classNames from \"classnames\";\nimport { makeStyles } from \"@material-ui/core\";\nimport {\n DraggableProvided,\n DraggableStateSnapshot,\n Omit,\n} from \"react-beautiful-dnd\";\nimport { Row } from \"../../../components/layout/Row\";\nimport { ReactComponent as GripIcon } from \"../../../assets/icons/grip-icon.svg\";\nimport { Collapsable } from \"../../../components/Collapsable\";\nimport {\n TransactionBlockHeaderButtons,\n TransactionBlockHeaderButtonsProps,\n} from \"./TransactionBlockHeaderButtons\";\nimport {\n TransactionBlockFields,\n TransactionBlockFieldsProps,\n} from \"./TransactionBlockFields\";\nimport {\n TransactionBlockHeaderTitle,\n TransactionBlockHeaderTitleProps,\n} from \"./TransactionBlockHeaderTitle\";\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n marginTop: \"0 !important\",\n padding: 0,\n },\n collapsableContainer: {\n margin: 0,\n padding: theme.spacing(1, 2, 2, 2),\n },\n dragging: {\n borderColor: \"#31AAB7\",\n borderStyle: \"solid\",\n borderWidth: 2,\n },\n noDragging: {\n transform: \"none !important\",\n },\n dropAnimation: {\n transitionDuration: \"0.001s !important\",\n },\n grip: {\n display: \"flex\",\n cursor: \"grab\",\n padding: theme.spacing(2),\n },\n}));\n\ntype TransactionBlockContentProps = {\n open: boolean;\n edit?: Edit;\n drag: {\n provider: DraggableProvided;\n snapshot: DraggableStateSnapshot;\n };\n blockFieldsProps: TransactionBlockFieldsProps;\n headerTitleProps: Omit;\n headerButtonProps: Omit;\n};\n\nexport const TransactionBlockContent = ({\n open,\n edit = false,\n headerButtonProps,\n headerTitleProps,\n blockFieldsProps,\n drag,\n}: TransactionBlockContentProps) => {\n const classes = useStyles();\n\n return (\n }\n >\n \n
\n \n
\n \n \n
\n \n );\n};\n","import React, { useState } from \"react\";\nimport classNames from \"classnames\";\nimport { makeStyles, Paper, withStyles } from \"@material-ui/core\";\nimport { ContractQueryForm } from \"../../../components/ethereum/ContractQueryForm\";\nimport { Draggable } from \"react-beautiful-dnd\";\nimport { TransactionBlockContent } from \"./TransactionBlockContent\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\n\ninterface ContractFunctionBlockProps {\n isOver: boolean;\n isOverBefore: boolean;\n index: number;\n transaction: Transaction;\n\n onUpdate(id: string, params: any[]): void;\n\n onDelete(id: string): void;\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n position: \"relative\",\n paddingBottom: theme.spacing(2.5),\n },\n placeholder: {\n position: \"absolute\",\n width: \"100%\",\n borderColor: \"#31AAB7\",\n borderStyle: \"solid\",\n borderWidth: 0,\n borderBottomWidth: theme.spacing(0.5),\n \"&.place-after\": {\n bottom: theme.spacing(1),\n },\n \"&.place-before\": {\n top: theme.spacing(-1),\n },\n },\n}));\n\nconst TransactionBlockPlaceholder = withStyles((theme) => ({\n root: {\n height: 56,\n backgroundColor: theme.palette.primary.light,\n },\n}))(Paper);\n\nexport const TransactionBlock = ({\n index,\n isOver,\n isOverBefore,\n transaction,\n onUpdate,\n onDelete,\n}: ContractFunctionBlockProps) => {\n const classes = useStyles();\n\n const [open, setOpen] = useState(false);\n const [edit, setEdit] = useState(false);\n\n const { id, params, func } = transaction;\n\n const handleStartEditing = () => {\n setOpen(true);\n setEdit(true);\n };\n\n const handleToggleContent = () => {\n if (!edit) setOpen(!open);\n };\n\n const handleCancelEditing = () => {\n setEdit(false);\n };\n const handleDeleteTransaction = () => {\n onDelete(id);\n };\n const handleSaveParams = (newParams: any[]) => {\n onUpdate(id, newParams);\n setEdit(false);\n };\n\n return (\n \n {(provider, snapshot) => (\n
\n {edit ? (\n \n {({ paramInputProps, areParamsValid, getParams }) => (\n handleSaveParams(getParams()),\n }}\n />\n )}\n \n ) : (\n \n )}\n {isOver && (\n \n )}\n {snapshot.isDragging && }\n
\n )}\n
\n );\n};\n","import React, { useCallback, useState } from \"react\";\nimport {\n DragDropContext,\n DragStart,\n DragUpdate,\n Droppable,\n DropResult,\n} from \"react-beautiful-dnd\";\nimport { TransactionBlock } from \"./TransactionBlock\";\nimport { serializeTransaction } from \"../../../store/transactionBuilder/helpers\";\nimport { setTransactions } from \"../../../store/transactionBuilder\";\nimport { useRootDispatch } from \"../../../store\";\nimport { Transaction } from \"../../../store/transactionBuilder/models\";\nimport { makeStyles } from \"@material-ui/core\";\n\ninterface TransactionBuilderListProps {\n transactions: Transaction[];\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n display: \"flex\",\n flexGrow: 1,\n outline: \"none\",\n padding: theme.spacing(1.5),\n marginBottom: theme.spacing(2),\n backgroundColor: \"#0d0b217a\",\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n overflowY: \"auto\",\n },\n}));\n\nexport const TransactionBuilderList = ({\n transactions,\n}: TransactionBuilderListProps) => {\n const classes = useStyles();\n const dispatch = useRootDispatch();\n\n const [overIndex, setOverIndex] = useState();\n const [sourceIndex, setSourceIndex] = useState();\n\n const handleDragStart = (result: DragStart) => {\n setSourceIndex(result.source.index);\n };\n\n const handleDragUpdate = (update: DragUpdate) => {\n if (\n update.destination &&\n update.destination.index !== update.source.index\n ) {\n setOverIndex(update.destination.index);\n } else {\n setOverIndex(undefined);\n }\n };\n\n const handleDragEnd = (result: DropResult) => {\n setOverIndex(undefined);\n setSourceIndex(undefined);\n if (result.destination) {\n const sorted = Array.from(transactions).map(serializeTransaction);\n const [removed] = sorted.splice(result.source.index, 1);\n sorted.splice(result.destination.index, 0, removed);\n dispatch(setTransactions(sorted));\n }\n };\n\n const handleTransactionUpdate = useCallback(\n (id, params) => {\n const txs = transactions.map(serializeTransaction).map((transaction) => {\n if (transaction.id !== id) {\n return transaction;\n }\n return { ...transaction, params };\n });\n dispatch(setTransactions(txs));\n },\n [dispatch, transactions]\n );\n\n const handleTransactionDelete = useCallback(\n (id) => {\n const txs = Array.from(transactions).map(serializeTransaction);\n const index = txs.findIndex((tx) => tx.id === id);\n if (index >= 0) {\n txs.splice(index, 1);\n dispatch(setTransactions(txs));\n }\n },\n [dispatch, transactions]\n );\n\n return (\n
\n \n \n {(provider) => (\n \n {transactions.map((transaction, index) => (\n \n ))}\n
\n )}\n \n \n
\n );\n};\n","import React from \"react\";\nimport { makeStyles, Typography } from \"@material-ui/core\";\nimport { Column } from \"../../../components/layout/Column\";\nimport { ReactComponent as AvatarEmptyIcon } from \"../../../assets/icons/avatar-empty.svg\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n display: \"flex\",\n flexGrow: 1,\n alignItems: \"center\",\n justifyContent: \"center\",\n outline: \"none\",\n border: \"1px solid rgba(217, 212, 173, 0.3)\",\n marginBottom: theme.spacing(2),\n backgroundColor: \"#0d0b217a\",\n },\n content: {\n display: \"grid\",\n gridTemplateColumns: \"40px 1fr\",\n maxWidth: 324,\n },\n title: {\n fontWeight: \"bold\",\n marginBottom: theme.spacing(1),\n lineHeight: 1,\n },\n details: {\n marginLeft: theme.spacing(3),\n },\n}));\n\nexport const TransactionBuilderEmptyList = () => {\n const classes = useStyles();\n return (\n
\n
\n \n \n \n No Transactions Added\n \n \n Add transactions using the Write tab on any mod, and view these\n transactions here before submitting them as a bundle.\n \n \n
\n
\n );\n};\n","import React from \"react\"\nimport { Badge, Fade, makeStyles, Modal, Typography } from \"@material-ui/core\"\nimport { Interface } from \"@ethersproject/abi\"\nimport { ActionButton } from \"../../components/ActionButton\"\nimport { useSafeAppsSDK } from \"@gnosis.pm/safe-apps-react-sdk\"\nimport { BaseTransaction } from \"@gnosis.pm/safe-apps-sdk\"\nimport { useRootDispatch, useRootSelector } from \"../../store\"\nimport {\n getTransactionBuilderOpen,\n getTransactions,\n} from \"../../store/transactionBuilder/selectors\"\nimport {\n closeTransactionBuilder,\n resetTransactions,\n} from \"../../store/transactionBuilder\"\nimport { fetchPendingModules } from \"../../store/modules\"\nimport { TransactionBuilderList } from \"./components/TransactionBuilderList\"\nimport { TransactionBuilderEmptyList } from \"./components/TransactionBuilderEmptyList\"\nimport { ReactComponent as ArrowUpIcon } from \"../../assets/icons/arrow-up-icon.svg\"\nimport classNames from \"classnames\"\nimport { Grow } from \"../../components/layout/Grow\"\nimport { colors, ZodiacPaper } from \"zodiac-ui-components\"\n\nconst useStyles = makeStyles((theme) => ({\n fullWindow: {\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n outline: \"none\",\n borderRadius: 0,\n },\n header: {\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n marginBottom: theme.spacing(2),\n padding: theme.spacing(0.5, 0.5, 0.5, 1.5),\n },\n content: {\n padding: theme.spacing(1.5, 1.5, 1.5, 1.5),\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n background: \"rgba(78, 72, 87, 0.8)\",\n borderWidth: 1,\n borderColor: \"rgba(255,255,255,0.2)\",\n },\n modal: {\n width: \"70%\",\n minWidth: 400,\n maxWidth: 820,\n\n height: \"calc(100% - 22px) !important\",\n left: \"auto !important\",\n right: \"19px !important\",\n top: \"11px !important\",\n },\n backdrop: {\n backdropFilter: \"blur(4px)\",\n },\n bagIcon: {\n marginLeft: theme.spacing(2),\n stroke: \"white\",\n },\n badge: {\n color: theme.palette.common.white,\n display: \"flex\",\n position: \"relative\",\n transform: \"none\",\n textAlign: \"center\",\n background: \"none\",\n fontSize: 16,\n },\n badgeRoot: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n height: 36,\n width: 36,\n borderRadius: 60,\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: colors.tan[300],\n padding: theme.spacing(0.5),\n },\n circleIconContainer: {\n borderColor: colors.tan[300],\n padding: theme.spacing(0.5),\n },\n}))\n\nexport const TransactionBuilder = () => {\n const classes = useStyles()\n const { sdk, safe } = useSafeAppsSDK()\n const dispatch = useRootDispatch()\n\n const open = useRootSelector(getTransactionBuilderOpen)\n const transactions = useRootSelector(getTransactions)\n\n const handleClose = () => dispatch(closeTransactionBuilder())\n\n const handleSubmitTransaction = async () => {\n try {\n const txs = transactions.map((tx): BaseTransaction => {\n const encoder = new Interface([tx.func])\n return {\n to: tx.to,\n value: \"0\",\n data: encoder.encodeFunctionData(tx.func, tx.params),\n }\n })\n await sdk.txs.send({ txs })\n dispatch(resetTransactions())\n dispatch(\n fetchPendingModules({\n safeAddress: safe.safeAddress,\n chainId: safe.chainId,\n }),\n )\n handleClose()\n } catch (error) {\n console.log(\"handleSubmitTransaction:error\", error)\n }\n }\n\n return (\n \n \n \n \n Bundle Transactions\n \n\n \n \n \n \n\n {transactions.length ? (\n \n ) : (\n \n )}\n }\n onClick={handleSubmitTransaction}\n >\n Submit Transactions\n \n \n \n \n )\n}\n\nexport default TransactionBuilder\n","import React from \"react\"\nimport { AppLayout } from \"./components/layout/AppLayout\"\nimport Panel from \"./views/Panel\"\nimport { Views } from \"./View\"\nimport Header from \"./views/Header\"\nimport { makeStyles } from \"@material-ui/core\"\nimport TransactionBuilder from \"./views/TransactionBuilder\"\nimport zodiacBackground from \"./assets/images/zodiac-bg.svg\"\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n background: `url(${zodiacBackground})`,\n backgroundSize: \"cover\",\n },\n background: {\n height: \"100vh\",\n padding: theme.spacing(3, 4, 4, 4),\n background:\n \"linear-gradient(108.86deg, rgba(26, 33, 66, 0.85) 6.24%, rgba(12, 19, 8, 0.85) 53.08%, rgba(37, 6, 4, 0.85) 96.54%);\",\n },\n}))\n\nconst App: React.FC = () => {\n const classes = useStyles()\n\n return (\n
\n
\n
\n }>\n \n \n \n
\n
\n )\n}\n\nexport default App\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { ThemeProvider } from \"styled-components\";\nimport {\n CssBaseline,\n ThemeProvider as MUIThemeProvider,\n} from \"@material-ui/core\";\nimport { Loader } from \"@gnosis.pm/safe-react-components\";\nimport SafeProvider from \"@gnosis.pm/safe-apps-react-sdk\";\nimport App from \"./App\";\nimport { Provider } from \"react-redux\";\nimport { REDUX_STORE } from \"./store\";\nimport { Row } from \"./components/layout/Row\";\nimport {\n zodiacMuiTheme,\n gnosisStyledComponentsTheme,\n} from \"zodiac-ui-components\";\n\nconst Main = () => {\n return (\n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n );\n};\n\nReactDOM.render(\n \n
\n ,\n document.getElementById(\"root\")\n);\n","module.exports = __webpack_public_path__ + \"static/media/zodiac-bg.b4d47715.svg\";"],"sourceRoot":""} \ No newline at end of file