diff --git a/.gitignore b/.gitignore index 148b492..b6ab196 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules .nvmrc dist env.json +.env diff --git a/docs/assets/search.js b/docs/assets/search.js index f8ab5b0..a03e892 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = JSON.parse("{\"kinds\":{\"32\":\"Variable\",\"64\":\"Function\",\"128\":\"Class\",\"512\":\"Constructor\",\"1024\":\"Property\",\"2048\":\"Method\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"id\":0,\"kind\":64,\"name\":\"getPod\",\"url\":\"modules.html#getPod\",\"classes\":\"tsd-kind-function\"},{\"id\":1,\"kind\":64,\"name\":\"getSuperProposal\",\"url\":\"modules.html#getSuperProposal\",\"classes\":\"tsd-kind-function\"},{\"id\":2,\"kind\":64,\"name\":\"getUserPods\",\"url\":\"modules.html#getUserPods\",\"classes\":\"tsd-kind-function\"},{\"id\":3,\"kind\":64,\"name\":\"getAdminPods\",\"url\":\"modules.html#getAdminPods\",\"classes\":\"tsd-kind-function\"},{\"id\":4,\"kind\":64,\"name\":\"init\",\"url\":\"modules.html#init\",\"classes\":\"tsd-kind-function\"},{\"id\":5,\"kind\":32,\"name\":\"config\",\"url\":\"modules.html#config\",\"classes\":\"tsd-kind-variable\"},{\"id\":6,\"kind\":65536,\"name\":\"__type\",\"url\":\"modules.html#config.__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-variable\",\"parent\":\"config\"},{\"id\":7,\"kind\":1024,\"name\":\"provider\",\"url\":\"modules.html#config.__type.provider\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":8,\"kind\":1024,\"name\":\"multicall\",\"url\":\"modules.html#config.__type.multicall\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":9,\"kind\":1024,\"name\":\"network\",\"url\":\"modules.html#config.__type.network\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":10,\"kind\":1024,\"name\":\"subgraphUrl\",\"url\":\"modules.html#config.__type.subgraphUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":11,\"kind\":1024,\"name\":\"gnosisUrl\",\"url\":\"modules.html#config.__type.gnosisUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":12,\"kind\":1024,\"name\":\"etherscanUrl\",\"url\":\"modules.html#config.__type.etherscanUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":13,\"kind\":1024,\"name\":\"etherscanApiKey\",\"url\":\"modules.html#config.__type.etherscanApiKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":14,\"kind\":64,\"name\":\"fetchPodUsers\",\"url\":\"modules.html#fetchPodUsers\",\"classes\":\"tsd-kind-function\"},{\"id\":15,\"kind\":64,\"name\":\"fetchUserPodIds\",\"url\":\"modules.html#fetchUserPodIds\",\"classes\":\"tsd-kind-function\"},{\"id\":16,\"kind\":64,\"name\":\"fetchAdminPodIds\",\"url\":\"modules.html#fetchAdminPodIds\",\"classes\":\"tsd-kind-function\"},{\"id\":17,\"kind\":64,\"name\":\"customSubgraphQuery\",\"url\":\"modules.html#customSubgraphQuery\",\"classes\":\"tsd-kind-function\"},{\"id\":18,\"kind\":64,\"name\":\"multiPodCreate\",\"url\":\"modules.html#multiPodCreate\",\"classes\":\"tsd-kind-function\"},{\"id\":19,\"kind\":64,\"name\":\"podifySafe\",\"url\":\"modules.html#podifySafe\",\"classes\":\"tsd-kind-function\"},{\"id\":20,\"kind\":64,\"name\":\"enableController\",\"url\":\"modules.html#enableController\",\"classes\":\"tsd-kind-function\"},{\"id\":21,\"kind\":128,\"name\":\"Pod\",\"url\":\"classes/Pod.html\",\"classes\":\"tsd-kind-class\"},{\"id\":22,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/Pod.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":23,\"kind\":1024,\"name\":\"controller\",\"url\":\"classes/Pod.html#controller\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":24,\"kind\":1024,\"name\":\"id\",\"url\":\"classes/Pod.html#id\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":25,\"kind\":1024,\"name\":\"safe\",\"url\":\"classes/Pod.html#safe\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":26,\"kind\":1024,\"name\":\"address\",\"url\":\"classes/Pod.html#address\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":27,\"kind\":1024,\"name\":\"nonce\",\"url\":\"classes/Pod.html#nonce\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":28,\"kind\":1024,\"name\":\"threshold\",\"url\":\"classes/Pod.html#threshold\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":29,\"kind\":1024,\"name\":\"ensName\",\"url\":\"classes/Pod.html#ensName\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":30,\"kind\":1024,\"name\":\"admin\",\"url\":\"classes/Pod.html#admin\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":31,\"kind\":1024,\"name\":\"description\",\"url\":\"classes/Pod.html#description\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":32,\"kind\":1024,\"name\":\"imageUrl\",\"url\":\"classes/Pod.html#imageUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":33,\"kind\":1024,\"name\":\"imageNoTextUrl\",\"url\":\"classes/Pod.html#imageNoTextUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":34,\"kind\":2048,\"name\":\"getProposals\",\"url\":\"classes/Pod.html#getProposals\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":35,\"kind\":2048,\"name\":\"getProposal\",\"url\":\"classes/Pod.html#getProposal\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":36,\"kind\":2048,\"name\":\"getSuperPods\",\"url\":\"classes/Pod.html#getSuperPods\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":37,\"kind\":2048,\"name\":\"getSuperProposals\",\"url\":\"classes/Pod.html#getSuperProposals\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":38,\"kind\":2048,\"name\":\"getMembers\",\"url\":\"classes/Pod.html#getMembers\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":39,\"kind\":2048,\"name\":\"getMemberEOAs\",\"url\":\"classes/Pod.html#getMemberEOAs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":40,\"kind\":2048,\"name\":\"getMemberPods\",\"url\":\"classes/Pod.html#getMemberPods\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":41,\"kind\":2048,\"name\":\"isMember\",\"url\":\"classes/Pod.html#isMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":42,\"kind\":2048,\"name\":\"isAdmin\",\"url\":\"classes/Pod.html#isAdmin\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":43,\"kind\":2048,\"name\":\"isAdminPodMember\",\"url\":\"classes/Pod.html#isAdminPodMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":44,\"kind\":2048,\"name\":\"isSubPodMember\",\"url\":\"classes/Pod.html#isSubPodMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":45,\"kind\":2048,\"name\":\"getSubPodsByMember\",\"url\":\"classes/Pod.html#getSubPodsByMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":46,\"kind\":2048,\"name\":\"propose\",\"url\":\"classes/Pod.html#propose\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":47,\"kind\":2048,\"name\":\"mintMember\",\"url\":\"classes/Pod.html#mintMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":48,\"kind\":2048,\"name\":\"burnMember\",\"url\":\"classes/Pod.html#burnMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":49,\"kind\":2048,\"name\":\"batchMintAndBurn\",\"url\":\"classes/Pod.html#batchMintAndBurn\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":50,\"kind\":2048,\"name\":\"transferMembership\",\"url\":\"classes/Pod.html#transferMembership\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":51,\"kind\":2048,\"name\":\"changeThreshold\",\"url\":\"classes/Pod.html#changeThreshold\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":52,\"kind\":2048,\"name\":\"transferAdmin\",\"url\":\"classes/Pod.html#transferAdmin\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":53,\"kind\":2048,\"name\":\"migratePodToLatest\",\"url\":\"classes/Pod.html#migratePodToLatest\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":54,\"kind\":2048,\"name\":\"isPodifyInProgress\",\"url\":\"classes/Pod.html#isPodifyInProgress\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":55,\"kind\":2048,\"name\":\"ejectSafe\",\"url\":\"classes/Pod.html#ejectSafe\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":56,\"kind\":2048,\"name\":\"createRejectProposal\",\"url\":\"classes/Pod.html#createRejectProposal\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":57,\"kind\":128,\"name\":\"Proposal\",\"url\":\"classes/Proposal.html\",\"classes\":\"tsd-kind-class\"},{\"id\":58,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/Proposal.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":59,\"kind\":1024,\"name\":\"pod\",\"url\":\"classes/Proposal.html#pod\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":60,\"kind\":1024,\"name\":\"id\",\"url\":\"classes/Proposal.html#id\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":61,\"kind\":1024,\"name\":\"status\",\"url\":\"classes/Proposal.html#status\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":62,\"kind\":1024,\"name\":\"isSubProposal\",\"url\":\"classes/Proposal.html#isSubProposal\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":63,\"kind\":1024,\"name\":\"approvals\",\"url\":\"classes/Proposal.html#approvals\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":64,\"kind\":1024,\"name\":\"rejections\",\"url\":\"classes/Proposal.html#rejections\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":65,\"kind\":1024,\"name\":\"threshold\",\"url\":\"classes/Proposal.html#threshold\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":66,\"kind\":1024,\"name\":\"method\",\"url\":\"classes/Proposal.html#method\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":67,\"kind\":1024,\"name\":\"parameters\",\"url\":\"classes/Proposal.html#parameters\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":68,\"kind\":1024,\"name\":\"value\",\"url\":\"classes/Proposal.html#value\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":69,\"kind\":1024,\"name\":\"timestamp\",\"url\":\"classes/Proposal.html#timestamp\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":70,\"kind\":2048,\"name\":\"approve\",\"url\":\"classes/Proposal.html#approve\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":71,\"kind\":2048,\"name\":\"reject\",\"url\":\"classes/Proposal.html#reject\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":72,\"kind\":2048,\"name\":\"executeApprove\",\"url\":\"classes/Proposal.html#executeApprove\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":73,\"kind\":2048,\"name\":\"executeReject\",\"url\":\"classes/Proposal.html#executeReject\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":74,\"kind\":4194304,\"name\":\"ProposalStatus\",\"url\":\"modules.html#ProposalStatus\",\"classes\":\"tsd-kind-type-alias\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,39.253]],[\"parent/0\",[]],[\"name/1\",[1,39.253]],[\"parent/1\",[]],[\"name/2\",[2,39.253]],[\"parent/2\",[]],[\"name/3\",[3,39.253]],[\"parent/3\",[]],[\"name/4\",[4,39.253]],[\"parent/4\",[]],[\"name/5\",[5,34.144]],[\"parent/5\",[]],[\"name/6\",[6,39.253]],[\"parent/6\",[5,3.073]],[\"name/7\",[7,39.253]],[\"parent/7\",[8,2.085]],[\"name/8\",[9,39.253]],[\"parent/8\",[8,2.085]],[\"name/9\",[10,39.253]],[\"parent/9\",[8,2.085]],[\"name/10\",[11,39.253]],[\"parent/10\",[8,2.085]],[\"name/11\",[12,39.253]],[\"parent/11\",[8,2.085]],[\"name/12\",[13,39.253]],[\"parent/12\",[8,2.085]],[\"name/13\",[14,39.253]],[\"parent/13\",[8,2.085]],[\"name/14\",[15,39.253]],[\"parent/14\",[]],[\"name/15\",[16,39.253]],[\"parent/15\",[]],[\"name/16\",[17,39.253]],[\"parent/16\",[]],[\"name/17\",[18,39.253]],[\"parent/17\",[]],[\"name/18\",[19,39.253]],[\"parent/18\",[]],[\"name/19\",[20,39.253]],[\"parent/19\",[]],[\"name/20\",[21,39.253]],[\"parent/20\",[]],[\"name/21\",[22,7.064]],[\"parent/21\",[]],[\"name/22\",[23,34.144]],[\"parent/22\",[22,0.636]],[\"name/23\",[24,39.253]],[\"parent/23\",[22,0.636]],[\"name/24\",[25,34.144]],[\"parent/24\",[22,0.636]],[\"name/25\",[26,39.253]],[\"parent/25\",[22,0.636]],[\"name/26\",[27,39.253]],[\"parent/26\",[22,0.636]],[\"name/27\",[28,39.253]],[\"parent/27\",[22,0.636]],[\"name/28\",[29,34.144]],[\"parent/28\",[22,0.636]],[\"name/29\",[30,39.253]],[\"parent/29\",[22,0.636]],[\"name/30\",[31,39.253]],[\"parent/30\",[22,0.636]],[\"name/31\",[32,39.253]],[\"parent/31\",[22,0.636]],[\"name/32\",[33,39.253]],[\"parent/32\",[22,0.636]],[\"name/33\",[34,39.253]],[\"parent/33\",[22,0.636]],[\"name/34\",[35,39.253]],[\"parent/34\",[22,0.636]],[\"name/35\",[36,39.253]],[\"parent/35\",[22,0.636]],[\"name/36\",[37,39.253]],[\"parent/36\",[22,0.636]],[\"name/37\",[38,39.253]],[\"parent/37\",[22,0.636]],[\"name/38\",[39,39.253]],[\"parent/38\",[22,0.636]],[\"name/39\",[40,39.253]],[\"parent/39\",[22,0.636]],[\"name/40\",[41,39.253]],[\"parent/40\",[22,0.636]],[\"name/41\",[42,39.253]],[\"parent/41\",[22,0.636]],[\"name/42\",[43,39.253]],[\"parent/42\",[22,0.636]],[\"name/43\",[44,39.253]],[\"parent/43\",[22,0.636]],[\"name/44\",[45,39.253]],[\"parent/44\",[22,0.636]],[\"name/45\",[46,39.253]],[\"parent/45\",[22,0.636]],[\"name/46\",[47,39.253]],[\"parent/46\",[22,0.636]],[\"name/47\",[48,39.253]],[\"parent/47\",[22,0.636]],[\"name/48\",[49,39.253]],[\"parent/48\",[22,0.636]],[\"name/49\",[50,39.253]],[\"parent/49\",[22,0.636]],[\"name/50\",[51,39.253]],[\"parent/50\",[22,0.636]],[\"name/51\",[52,39.253]],[\"parent/51\",[22,0.636]],[\"name/52\",[53,39.253]],[\"parent/52\",[22,0.636]],[\"name/53\",[54,39.253]],[\"parent/53\",[22,0.636]],[\"name/54\",[55,39.253]],[\"parent/54\",[22,0.636]],[\"name/55\",[56,39.253]],[\"parent/55\",[22,0.636]],[\"name/56\",[57,39.253]],[\"parent/56\",[22,0.636]],[\"name/57\",[58,14.685]],[\"parent/57\",[]],[\"name/58\",[23,34.144]],[\"parent/58\",[58,1.322]],[\"name/59\",[22,7.064]],[\"parent/59\",[58,1.322]],[\"name/60\",[25,34.144]],[\"parent/60\",[58,1.322]],[\"name/61\",[59,39.253]],[\"parent/61\",[58,1.322]],[\"name/62\",[60,39.253]],[\"parent/62\",[58,1.322]],[\"name/63\",[61,39.253]],[\"parent/63\",[58,1.322]],[\"name/64\",[62,39.253]],[\"parent/64\",[58,1.322]],[\"name/65\",[29,34.144]],[\"parent/65\",[58,1.322]],[\"name/66\",[63,39.253]],[\"parent/66\",[58,1.322]],[\"name/67\",[64,39.253]],[\"parent/67\",[58,1.322]],[\"name/68\",[65,39.253]],[\"parent/68\",[58,1.322]],[\"name/69\",[66,39.253]],[\"parent/69\",[58,1.322]],[\"name/70\",[67,39.253]],[\"parent/70\",[58,1.322]],[\"name/71\",[68,39.253]],[\"parent/71\",[58,1.322]],[\"name/72\",[69,39.253]],[\"parent/72\",[58,1.322]],[\"name/73\",[70,39.253]],[\"parent/73\",[58,1.322]],[\"name/74\",[71,39.253]],[\"parent/74\",[]]],\"invertedIndex\":[[\"__type\",{\"_index\":6,\"name\":{\"6\":{}},\"parent\":{}}],[\"address\",{\"_index\":27,\"name\":{\"26\":{}},\"parent\":{}}],[\"admin\",{\"_index\":31,\"name\":{\"30\":{}},\"parent\":{}}],[\"approvals\",{\"_index\":61,\"name\":{\"63\":{}},\"parent\":{}}],[\"approve\",{\"_index\":67,\"name\":{\"70\":{}},\"parent\":{}}],[\"batchmintandburn\",{\"_index\":50,\"name\":{\"49\":{}},\"parent\":{}}],[\"burnmember\",{\"_index\":49,\"name\":{\"48\":{}},\"parent\":{}}],[\"changethreshold\",{\"_index\":52,\"name\":{\"51\":{}},\"parent\":{}}],[\"config\",{\"_index\":5,\"name\":{\"5\":{}},\"parent\":{\"6\":{}}}],[\"config.__type\",{\"_index\":8,\"name\":{},\"parent\":{\"7\":{},\"8\":{},\"9\":{},\"10\":{},\"11\":{},\"12\":{},\"13\":{}}}],[\"constructor\",{\"_index\":23,\"name\":{\"22\":{},\"58\":{}},\"parent\":{}}],[\"controller\",{\"_index\":24,\"name\":{\"23\":{}},\"parent\":{}}],[\"createrejectproposal\",{\"_index\":57,\"name\":{\"56\":{}},\"parent\":{}}],[\"customsubgraphquery\",{\"_index\":18,\"name\":{\"17\":{}},\"parent\":{}}],[\"description\",{\"_index\":32,\"name\":{\"31\":{}},\"parent\":{}}],[\"ejectsafe\",{\"_index\":56,\"name\":{\"55\":{}},\"parent\":{}}],[\"enablecontroller\",{\"_index\":21,\"name\":{\"20\":{}},\"parent\":{}}],[\"ensname\",{\"_index\":30,\"name\":{\"29\":{}},\"parent\":{}}],[\"etherscanapikey\",{\"_index\":14,\"name\":{\"13\":{}},\"parent\":{}}],[\"etherscanurl\",{\"_index\":13,\"name\":{\"12\":{}},\"parent\":{}}],[\"executeapprove\",{\"_index\":69,\"name\":{\"72\":{}},\"parent\":{}}],[\"executereject\",{\"_index\":70,\"name\":{\"73\":{}},\"parent\":{}}],[\"fetchadminpodids\",{\"_index\":17,\"name\":{\"16\":{}},\"parent\":{}}],[\"fetchpodusers\",{\"_index\":15,\"name\":{\"14\":{}},\"parent\":{}}],[\"fetchuserpodids\",{\"_index\":16,\"name\":{\"15\":{}},\"parent\":{}}],[\"getadminpods\",{\"_index\":3,\"name\":{\"3\":{}},\"parent\":{}}],[\"getmembereoas\",{\"_index\":40,\"name\":{\"39\":{}},\"parent\":{}}],[\"getmemberpods\",{\"_index\":41,\"name\":{\"40\":{}},\"parent\":{}}],[\"getmembers\",{\"_index\":39,\"name\":{\"38\":{}},\"parent\":{}}],[\"getpod\",{\"_index\":0,\"name\":{\"0\":{}},\"parent\":{}}],[\"getproposal\",{\"_index\":36,\"name\":{\"35\":{}},\"parent\":{}}],[\"getproposals\",{\"_index\":35,\"name\":{\"34\":{}},\"parent\":{}}],[\"getsubpodsbymember\",{\"_index\":46,\"name\":{\"45\":{}},\"parent\":{}}],[\"getsuperpods\",{\"_index\":37,\"name\":{\"36\":{}},\"parent\":{}}],[\"getsuperproposal\",{\"_index\":1,\"name\":{\"1\":{}},\"parent\":{}}],[\"getsuperproposals\",{\"_index\":38,\"name\":{\"37\":{}},\"parent\":{}}],[\"getuserpods\",{\"_index\":2,\"name\":{\"2\":{}},\"parent\":{}}],[\"gnosisurl\",{\"_index\":12,\"name\":{\"11\":{}},\"parent\":{}}],[\"id\",{\"_index\":25,\"name\":{\"24\":{},\"60\":{}},\"parent\":{}}],[\"imagenotexturl\",{\"_index\":34,\"name\":{\"33\":{}},\"parent\":{}}],[\"imageurl\",{\"_index\":33,\"name\":{\"32\":{}},\"parent\":{}}],[\"init\",{\"_index\":4,\"name\":{\"4\":{}},\"parent\":{}}],[\"isadmin\",{\"_index\":43,\"name\":{\"42\":{}},\"parent\":{}}],[\"isadminpodmember\",{\"_index\":44,\"name\":{\"43\":{}},\"parent\":{}}],[\"ismember\",{\"_index\":42,\"name\":{\"41\":{}},\"parent\":{}}],[\"ispodifyinprogress\",{\"_index\":55,\"name\":{\"54\":{}},\"parent\":{}}],[\"issubpodmember\",{\"_index\":45,\"name\":{\"44\":{}},\"parent\":{}}],[\"issubproposal\",{\"_index\":60,\"name\":{\"62\":{}},\"parent\":{}}],[\"method\",{\"_index\":63,\"name\":{\"66\":{}},\"parent\":{}}],[\"migratepodtolatest\",{\"_index\":54,\"name\":{\"53\":{}},\"parent\":{}}],[\"mintmember\",{\"_index\":48,\"name\":{\"47\":{}},\"parent\":{}}],[\"multicall\",{\"_index\":9,\"name\":{\"8\":{}},\"parent\":{}}],[\"multipodcreate\",{\"_index\":19,\"name\":{\"18\":{}},\"parent\":{}}],[\"network\",{\"_index\":10,\"name\":{\"9\":{}},\"parent\":{}}],[\"nonce\",{\"_index\":28,\"name\":{\"27\":{}},\"parent\":{}}],[\"parameters\",{\"_index\":64,\"name\":{\"67\":{}},\"parent\":{}}],[\"pod\",{\"_index\":22,\"name\":{\"21\":{},\"59\":{}},\"parent\":{\"22\":{},\"23\":{},\"24\":{},\"25\":{},\"26\":{},\"27\":{},\"28\":{},\"29\":{},\"30\":{},\"31\":{},\"32\":{},\"33\":{},\"34\":{},\"35\":{},\"36\":{},\"37\":{},\"38\":{},\"39\":{},\"40\":{},\"41\":{},\"42\":{},\"43\":{},\"44\":{},\"45\":{},\"46\":{},\"47\":{},\"48\":{},\"49\":{},\"50\":{},\"51\":{},\"52\":{},\"53\":{},\"54\":{},\"55\":{},\"56\":{}}}],[\"podifysafe\",{\"_index\":20,\"name\":{\"19\":{}},\"parent\":{}}],[\"proposal\",{\"_index\":58,\"name\":{\"57\":{}},\"parent\":{\"58\":{},\"59\":{},\"60\":{},\"61\":{},\"62\":{},\"63\":{},\"64\":{},\"65\":{},\"66\":{},\"67\":{},\"68\":{},\"69\":{},\"70\":{},\"71\":{},\"72\":{},\"73\":{}}}],[\"proposalstatus\",{\"_index\":71,\"name\":{\"74\":{}},\"parent\":{}}],[\"propose\",{\"_index\":47,\"name\":{\"46\":{}},\"parent\":{}}],[\"provider\",{\"_index\":7,\"name\":{\"7\":{}},\"parent\":{}}],[\"reject\",{\"_index\":68,\"name\":{\"71\":{}},\"parent\":{}}],[\"rejections\",{\"_index\":62,\"name\":{\"64\":{}},\"parent\":{}}],[\"safe\",{\"_index\":26,\"name\":{\"25\":{}},\"parent\":{}}],[\"status\",{\"_index\":59,\"name\":{\"61\":{}},\"parent\":{}}],[\"subgraphurl\",{\"_index\":11,\"name\":{\"10\":{}},\"parent\":{}}],[\"threshold\",{\"_index\":29,\"name\":{\"28\":{},\"65\":{}},\"parent\":{}}],[\"timestamp\",{\"_index\":66,\"name\":{\"69\":{}},\"parent\":{}}],[\"transferadmin\",{\"_index\":53,\"name\":{\"52\":{}},\"parent\":{}}],[\"transfermembership\",{\"_index\":51,\"name\":{\"50\":{}},\"parent\":{}}],[\"value\",{\"_index\":65,\"name\":{\"68\":{}},\"parent\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file +window.searchData = JSON.parse("{\"kinds\":{\"32\":\"Variable\",\"64\":\"Function\",\"128\":\"Class\",\"512\":\"Constructor\",\"1024\":\"Property\",\"2048\":\"Method\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"id\":0,\"kind\":64,\"name\":\"getPod\",\"url\":\"modules.html#getPod\",\"classes\":\"tsd-kind-function\"},{\"id\":1,\"kind\":64,\"name\":\"getSuperProposal\",\"url\":\"modules.html#getSuperProposal\",\"classes\":\"tsd-kind-function\"},{\"id\":2,\"kind\":64,\"name\":\"getUserPods\",\"url\":\"modules.html#getUserPods\",\"classes\":\"tsd-kind-function\"},{\"id\":3,\"kind\":64,\"name\":\"getAdminPods\",\"url\":\"modules.html#getAdminPods\",\"classes\":\"tsd-kind-function\"},{\"id\":4,\"kind\":64,\"name\":\"init\",\"url\":\"modules.html#init\",\"classes\":\"tsd-kind-function\"},{\"id\":5,\"kind\":32,\"name\":\"config\",\"url\":\"modules.html#config\",\"classes\":\"tsd-kind-variable\"},{\"id\":6,\"kind\":65536,\"name\":\"__type\",\"url\":\"modules.html#config.__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-variable\",\"parent\":\"config\"},{\"id\":7,\"kind\":1024,\"name\":\"provider\",\"url\":\"modules.html#config.__type.provider\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":8,\"kind\":1024,\"name\":\"multicall\",\"url\":\"modules.html#config.__type.multicall\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":9,\"kind\":1024,\"name\":\"network\",\"url\":\"modules.html#config.__type.network\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":10,\"kind\":1024,\"name\":\"subgraphUrl\",\"url\":\"modules.html#config.__type.subgraphUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":11,\"kind\":1024,\"name\":\"gnosisUrl\",\"url\":\"modules.html#config.__type.gnosisUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":12,\"kind\":1024,\"name\":\"etherscanUrl\",\"url\":\"modules.html#config.__type.etherscanUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":13,\"kind\":1024,\"name\":\"etherscanApiKey\",\"url\":\"modules.html#config.__type.etherscanApiKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"config.__type\"},{\"id\":14,\"kind\":64,\"name\":\"fetchPodUsers\",\"url\":\"modules.html#fetchPodUsers\",\"classes\":\"tsd-kind-function\"},{\"id\":15,\"kind\":64,\"name\":\"fetchUserPodIds\",\"url\":\"modules.html#fetchUserPodIds\",\"classes\":\"tsd-kind-function\"},{\"id\":16,\"kind\":64,\"name\":\"fetchAdminPodIds\",\"url\":\"modules.html#fetchAdminPodIds\",\"classes\":\"tsd-kind-function\"},{\"id\":17,\"kind\":64,\"name\":\"customSubgraphQuery\",\"url\":\"modules.html#customSubgraphQuery\",\"classes\":\"tsd-kind-function\"},{\"id\":18,\"kind\":64,\"name\":\"multiPodCreate\",\"url\":\"modules.html#multiPodCreate\",\"classes\":\"tsd-kind-function\"},{\"id\":19,\"kind\":64,\"name\":\"podifySafe\",\"url\":\"modules.html#podifySafe\",\"classes\":\"tsd-kind-function\"},{\"id\":20,\"kind\":64,\"name\":\"enableController\",\"url\":\"modules.html#enableController\",\"classes\":\"tsd-kind-function\"},{\"id\":21,\"kind\":128,\"name\":\"Pod\",\"url\":\"classes/Pod.html\",\"classes\":\"tsd-kind-class\"},{\"id\":22,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/Pod.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":23,\"kind\":1024,\"name\":\"controller\",\"url\":\"classes/Pod.html#controller\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":24,\"kind\":1024,\"name\":\"id\",\"url\":\"classes/Pod.html#id\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":25,\"kind\":1024,\"name\":\"safe\",\"url\":\"classes/Pod.html#safe\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":26,\"kind\":1024,\"name\":\"address\",\"url\":\"classes/Pod.html#address\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":27,\"kind\":1024,\"name\":\"nonce\",\"url\":\"classes/Pod.html#nonce\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":28,\"kind\":1024,\"name\":\"threshold\",\"url\":\"classes/Pod.html#threshold\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":29,\"kind\":1024,\"name\":\"ensName\",\"url\":\"classes/Pod.html#ensName\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":30,\"kind\":1024,\"name\":\"admin\",\"url\":\"classes/Pod.html#admin\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":31,\"kind\":1024,\"name\":\"description\",\"url\":\"classes/Pod.html#description\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":32,\"kind\":1024,\"name\":\"imageUrl\",\"url\":\"classes/Pod.html#imageUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":33,\"kind\":1024,\"name\":\"imageNoTextUrl\",\"url\":\"classes/Pod.html#imageNoTextUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":34,\"kind\":2048,\"name\":\"getProposals\",\"url\":\"classes/Pod.html#getProposals\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":35,\"kind\":2048,\"name\":\"getProposal\",\"url\":\"classes/Pod.html#getProposal\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":36,\"kind\":2048,\"name\":\"getSuperPods\",\"url\":\"classes/Pod.html#getSuperPods\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":37,\"kind\":2048,\"name\":\"getSuperProposals\",\"url\":\"classes/Pod.html#getSuperProposals\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":38,\"kind\":2048,\"name\":\"getMembers\",\"url\":\"classes/Pod.html#getMembers\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":39,\"kind\":2048,\"name\":\"getMemberEOAs\",\"url\":\"classes/Pod.html#getMemberEOAs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":40,\"kind\":2048,\"name\":\"getMemberPods\",\"url\":\"classes/Pod.html#getMemberPods\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":41,\"kind\":2048,\"name\":\"callAsPersona\",\"url\":\"classes/Pod.html#callAsPersona\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":42,\"kind\":2048,\"name\":\"getPersonas\",\"url\":\"classes/Pod.html#getPersonas\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":43,\"kind\":2048,\"name\":\"isMember\",\"url\":\"classes/Pod.html#isMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":44,\"kind\":2048,\"name\":\"isAdmin\",\"url\":\"classes/Pod.html#isAdmin\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":45,\"kind\":2048,\"name\":\"isAdminPodMember\",\"url\":\"classes/Pod.html#isAdminPodMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":46,\"kind\":2048,\"name\":\"isSubPodMember\",\"url\":\"classes/Pod.html#isSubPodMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":47,\"kind\":2048,\"name\":\"getSubPodsByMember\",\"url\":\"classes/Pod.html#getSubPodsByMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":48,\"kind\":2048,\"name\":\"propose\",\"url\":\"classes/Pod.html#propose\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":49,\"kind\":2048,\"name\":\"mintMember\",\"url\":\"classes/Pod.html#mintMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":50,\"kind\":2048,\"name\":\"burnMember\",\"url\":\"classes/Pod.html#burnMember\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":51,\"kind\":2048,\"name\":\"batchMintAndBurn\",\"url\":\"classes/Pod.html#batchMintAndBurn\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":52,\"kind\":2048,\"name\":\"transferMembership\",\"url\":\"classes/Pod.html#transferMembership\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":53,\"kind\":2048,\"name\":\"changeThreshold\",\"url\":\"classes/Pod.html#changeThreshold\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":54,\"kind\":2048,\"name\":\"transferAdmin\",\"url\":\"classes/Pod.html#transferAdmin\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":55,\"kind\":2048,\"name\":\"migratePodToLatest\",\"url\":\"classes/Pod.html#migratePodToLatest\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":56,\"kind\":2048,\"name\":\"isPodifyInProgress\",\"url\":\"classes/Pod.html#isPodifyInProgress\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":57,\"kind\":2048,\"name\":\"ejectSafe\",\"url\":\"classes/Pod.html#ejectSafe\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":58,\"kind\":2048,\"name\":\"createRejectProposal\",\"url\":\"classes/Pod.html#createRejectProposal\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Pod\"},{\"id\":59,\"kind\":128,\"name\":\"Proposal\",\"url\":\"classes/Proposal.html\",\"classes\":\"tsd-kind-class\"},{\"id\":60,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/Proposal.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":61,\"kind\":1024,\"name\":\"pod\",\"url\":\"classes/Proposal.html#pod\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":62,\"kind\":1024,\"name\":\"id\",\"url\":\"classes/Proposal.html#id\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":63,\"kind\":1024,\"name\":\"status\",\"url\":\"classes/Proposal.html#status\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":64,\"kind\":1024,\"name\":\"isSubProposal\",\"url\":\"classes/Proposal.html#isSubProposal\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":65,\"kind\":1024,\"name\":\"approvals\",\"url\":\"classes/Proposal.html#approvals\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":66,\"kind\":1024,\"name\":\"rejections\",\"url\":\"classes/Proposal.html#rejections\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":67,\"kind\":1024,\"name\":\"threshold\",\"url\":\"classes/Proposal.html#threshold\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":68,\"kind\":1024,\"name\":\"method\",\"url\":\"classes/Proposal.html#method\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":69,\"kind\":1024,\"name\":\"parameters\",\"url\":\"classes/Proposal.html#parameters\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":70,\"kind\":1024,\"name\":\"value\",\"url\":\"classes/Proposal.html#value\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":71,\"kind\":1024,\"name\":\"timestamp\",\"url\":\"classes/Proposal.html#timestamp\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":72,\"kind\":2048,\"name\":\"approve\",\"url\":\"classes/Proposal.html#approve\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":73,\"kind\":2048,\"name\":\"reject\",\"url\":\"classes/Proposal.html#reject\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":74,\"kind\":2048,\"name\":\"executeApprove\",\"url\":\"classes/Proposal.html#executeApprove\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":75,\"kind\":2048,\"name\":\"executeReject\",\"url\":\"classes/Proposal.html#executeReject\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"Proposal\"},{\"id\":76,\"kind\":4194304,\"name\":\"ProposalStatus\",\"url\":\"modules.html#ProposalStatus\",\"classes\":\"tsd-kind-type-alias\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,39.512]],[\"parent/0\",[]],[\"name/1\",[1,39.512]],[\"parent/1\",[]],[\"name/2\",[2,39.512]],[\"parent/2\",[]],[\"name/3\",[3,39.512]],[\"parent/3\",[]],[\"name/4\",[4,39.512]],[\"parent/4\",[]],[\"name/5\",[5,34.404]],[\"parent/5\",[]],[\"name/6\",[6,39.512]],[\"parent/6\",[5,3.107]],[\"name/7\",[7,39.512]],[\"parent/7\",[8,2.115]],[\"name/8\",[9,39.512]],[\"parent/8\",[8,2.115]],[\"name/9\",[10,39.512]],[\"parent/9\",[8,2.115]],[\"name/10\",[11,39.512]],[\"parent/10\",[8,2.115]],[\"name/11\",[12,39.512]],[\"parent/11\",[8,2.115]],[\"name/12\",[13,39.512]],[\"parent/12\",[8,2.115]],[\"name/13\",[14,39.512]],[\"parent/13\",[8,2.115]],[\"name/14\",[15,39.512]],[\"parent/14\",[]],[\"name/15\",[16,39.512]],[\"parent/15\",[]],[\"name/16\",[17,39.512]],[\"parent/16\",[]],[\"name/17\",[18,39.512]],[\"parent/17\",[]],[\"name/18\",[19,39.512]],[\"parent/18\",[]],[\"name/19\",[20,39.512]],[\"parent/19\",[]],[\"name/20\",[21,39.512]],[\"parent/20\",[]],[\"name/21\",[22,6.804]],[\"parent/21\",[]],[\"name/22\",[23,34.404]],[\"parent/22\",[22,0.614]],[\"name/23\",[24,39.512]],[\"parent/23\",[22,0.614]],[\"name/24\",[25,34.404]],[\"parent/24\",[22,0.614]],[\"name/25\",[26,39.512]],[\"parent/25\",[22,0.614]],[\"name/26\",[27,39.512]],[\"parent/26\",[22,0.614]],[\"name/27\",[28,39.512]],[\"parent/27\",[22,0.614]],[\"name/28\",[29,34.404]],[\"parent/28\",[22,0.614]],[\"name/29\",[30,39.512]],[\"parent/29\",[22,0.614]],[\"name/30\",[31,39.512]],[\"parent/30\",[22,0.614]],[\"name/31\",[32,39.512]],[\"parent/31\",[22,0.614]],[\"name/32\",[33,39.512]],[\"parent/32\",[22,0.614]],[\"name/33\",[34,39.512]],[\"parent/33\",[22,0.614]],[\"name/34\",[35,39.512]],[\"parent/34\",[22,0.614]],[\"name/35\",[36,39.512]],[\"parent/35\",[22,0.614]],[\"name/36\",[37,39.512]],[\"parent/36\",[22,0.614]],[\"name/37\",[38,39.512]],[\"parent/37\",[22,0.614]],[\"name/38\",[39,39.512]],[\"parent/38\",[22,0.614]],[\"name/39\",[40,39.512]],[\"parent/39\",[22,0.614]],[\"name/40\",[41,39.512]],[\"parent/40\",[22,0.614]],[\"name/41\",[42,39.512]],[\"parent/41\",[22,0.614]],[\"name/42\",[43,39.512]],[\"parent/42\",[22,0.614]],[\"name/43\",[44,39.512]],[\"parent/43\",[22,0.614]],[\"name/44\",[45,39.512]],[\"parent/44\",[22,0.614]],[\"name/45\",[46,39.512]],[\"parent/45\",[22,0.614]],[\"name/46\",[47,39.512]],[\"parent/46\",[22,0.614]],[\"name/47\",[48,39.512]],[\"parent/47\",[22,0.614]],[\"name/48\",[49,39.512]],[\"parent/48\",[22,0.614]],[\"name/49\",[50,39.512]],[\"parent/49\",[22,0.614]],[\"name/50\",[51,39.512]],[\"parent/50\",[22,0.614]],[\"name/51\",[52,39.512]],[\"parent/51\",[22,0.614]],[\"name/52\",[53,39.512]],[\"parent/52\",[22,0.614]],[\"name/53\",[54,39.512]],[\"parent/53\",[22,0.614]],[\"name/54\",[55,39.512]],[\"parent/54\",[22,0.614]],[\"name/55\",[56,39.512]],[\"parent/55\",[22,0.614]],[\"name/56\",[57,39.512]],[\"parent/56\",[22,0.614]],[\"name/57\",[58,39.512]],[\"parent/57\",[22,0.614]],[\"name/58\",[59,39.512]],[\"parent/58\",[22,0.614]],[\"name/59\",[60,14.945]],[\"parent/59\",[]],[\"name/60\",[23,34.404]],[\"parent/60\",[60,1.35]],[\"name/61\",[22,6.804]],[\"parent/61\",[60,1.35]],[\"name/62\",[25,34.404]],[\"parent/62\",[60,1.35]],[\"name/63\",[61,39.512]],[\"parent/63\",[60,1.35]],[\"name/64\",[62,39.512]],[\"parent/64\",[60,1.35]],[\"name/65\",[63,39.512]],[\"parent/65\",[60,1.35]],[\"name/66\",[64,39.512]],[\"parent/66\",[60,1.35]],[\"name/67\",[29,34.404]],[\"parent/67\",[60,1.35]],[\"name/68\",[65,39.512]],[\"parent/68\",[60,1.35]],[\"name/69\",[66,39.512]],[\"parent/69\",[60,1.35]],[\"name/70\",[67,39.512]],[\"parent/70\",[60,1.35]],[\"name/71\",[68,39.512]],[\"parent/71\",[60,1.35]],[\"name/72\",[69,39.512]],[\"parent/72\",[60,1.35]],[\"name/73\",[70,39.512]],[\"parent/73\",[60,1.35]],[\"name/74\",[71,39.512]],[\"parent/74\",[60,1.35]],[\"name/75\",[72,39.512]],[\"parent/75\",[60,1.35]],[\"name/76\",[73,39.512]],[\"parent/76\",[]]],\"invertedIndex\":[[\"__type\",{\"_index\":6,\"name\":{\"6\":{}},\"parent\":{}}],[\"address\",{\"_index\":27,\"name\":{\"26\":{}},\"parent\":{}}],[\"admin\",{\"_index\":31,\"name\":{\"30\":{}},\"parent\":{}}],[\"approvals\",{\"_index\":63,\"name\":{\"65\":{}},\"parent\":{}}],[\"approve\",{\"_index\":69,\"name\":{\"72\":{}},\"parent\":{}}],[\"batchmintandburn\",{\"_index\":52,\"name\":{\"51\":{}},\"parent\":{}}],[\"burnmember\",{\"_index\":51,\"name\":{\"50\":{}},\"parent\":{}}],[\"callaspersona\",{\"_index\":42,\"name\":{\"41\":{}},\"parent\":{}}],[\"changethreshold\",{\"_index\":54,\"name\":{\"53\":{}},\"parent\":{}}],[\"config\",{\"_index\":5,\"name\":{\"5\":{}},\"parent\":{\"6\":{}}}],[\"config.__type\",{\"_index\":8,\"name\":{},\"parent\":{\"7\":{},\"8\":{},\"9\":{},\"10\":{},\"11\":{},\"12\":{},\"13\":{}}}],[\"constructor\",{\"_index\":23,\"name\":{\"22\":{},\"60\":{}},\"parent\":{}}],[\"controller\",{\"_index\":24,\"name\":{\"23\":{}},\"parent\":{}}],[\"createrejectproposal\",{\"_index\":59,\"name\":{\"58\":{}},\"parent\":{}}],[\"customsubgraphquery\",{\"_index\":18,\"name\":{\"17\":{}},\"parent\":{}}],[\"description\",{\"_index\":32,\"name\":{\"31\":{}},\"parent\":{}}],[\"ejectsafe\",{\"_index\":58,\"name\":{\"57\":{}},\"parent\":{}}],[\"enablecontroller\",{\"_index\":21,\"name\":{\"20\":{}},\"parent\":{}}],[\"ensname\",{\"_index\":30,\"name\":{\"29\":{}},\"parent\":{}}],[\"etherscanapikey\",{\"_index\":14,\"name\":{\"13\":{}},\"parent\":{}}],[\"etherscanurl\",{\"_index\":13,\"name\":{\"12\":{}},\"parent\":{}}],[\"executeapprove\",{\"_index\":71,\"name\":{\"74\":{}},\"parent\":{}}],[\"executereject\",{\"_index\":72,\"name\":{\"75\":{}},\"parent\":{}}],[\"fetchadminpodids\",{\"_index\":17,\"name\":{\"16\":{}},\"parent\":{}}],[\"fetchpodusers\",{\"_index\":15,\"name\":{\"14\":{}},\"parent\":{}}],[\"fetchuserpodids\",{\"_index\":16,\"name\":{\"15\":{}},\"parent\":{}}],[\"getadminpods\",{\"_index\":3,\"name\":{\"3\":{}},\"parent\":{}}],[\"getmembereoas\",{\"_index\":40,\"name\":{\"39\":{}},\"parent\":{}}],[\"getmemberpods\",{\"_index\":41,\"name\":{\"40\":{}},\"parent\":{}}],[\"getmembers\",{\"_index\":39,\"name\":{\"38\":{}},\"parent\":{}}],[\"getpersonas\",{\"_index\":43,\"name\":{\"42\":{}},\"parent\":{}}],[\"getpod\",{\"_index\":0,\"name\":{\"0\":{}},\"parent\":{}}],[\"getproposal\",{\"_index\":36,\"name\":{\"35\":{}},\"parent\":{}}],[\"getproposals\",{\"_index\":35,\"name\":{\"34\":{}},\"parent\":{}}],[\"getsubpodsbymember\",{\"_index\":48,\"name\":{\"47\":{}},\"parent\":{}}],[\"getsuperpods\",{\"_index\":37,\"name\":{\"36\":{}},\"parent\":{}}],[\"getsuperproposal\",{\"_index\":1,\"name\":{\"1\":{}},\"parent\":{}}],[\"getsuperproposals\",{\"_index\":38,\"name\":{\"37\":{}},\"parent\":{}}],[\"getuserpods\",{\"_index\":2,\"name\":{\"2\":{}},\"parent\":{}}],[\"gnosisurl\",{\"_index\":12,\"name\":{\"11\":{}},\"parent\":{}}],[\"id\",{\"_index\":25,\"name\":{\"24\":{},\"62\":{}},\"parent\":{}}],[\"imagenotexturl\",{\"_index\":34,\"name\":{\"33\":{}},\"parent\":{}}],[\"imageurl\",{\"_index\":33,\"name\":{\"32\":{}},\"parent\":{}}],[\"init\",{\"_index\":4,\"name\":{\"4\":{}},\"parent\":{}}],[\"isadmin\",{\"_index\":45,\"name\":{\"44\":{}},\"parent\":{}}],[\"isadminpodmember\",{\"_index\":46,\"name\":{\"45\":{}},\"parent\":{}}],[\"ismember\",{\"_index\":44,\"name\":{\"43\":{}},\"parent\":{}}],[\"ispodifyinprogress\",{\"_index\":57,\"name\":{\"56\":{}},\"parent\":{}}],[\"issubpodmember\",{\"_index\":47,\"name\":{\"46\":{}},\"parent\":{}}],[\"issubproposal\",{\"_index\":62,\"name\":{\"64\":{}},\"parent\":{}}],[\"method\",{\"_index\":65,\"name\":{\"68\":{}},\"parent\":{}}],[\"migratepodtolatest\",{\"_index\":56,\"name\":{\"55\":{}},\"parent\":{}}],[\"mintmember\",{\"_index\":50,\"name\":{\"49\":{}},\"parent\":{}}],[\"multicall\",{\"_index\":9,\"name\":{\"8\":{}},\"parent\":{}}],[\"multipodcreate\",{\"_index\":19,\"name\":{\"18\":{}},\"parent\":{}}],[\"network\",{\"_index\":10,\"name\":{\"9\":{}},\"parent\":{}}],[\"nonce\",{\"_index\":28,\"name\":{\"27\":{}},\"parent\":{}}],[\"parameters\",{\"_index\":66,\"name\":{\"69\":{}},\"parent\":{}}],[\"pod\",{\"_index\":22,\"name\":{\"21\":{},\"61\":{}},\"parent\":{\"22\":{},\"23\":{},\"24\":{},\"25\":{},\"26\":{},\"27\":{},\"28\":{},\"29\":{},\"30\":{},\"31\":{},\"32\":{},\"33\":{},\"34\":{},\"35\":{},\"36\":{},\"37\":{},\"38\":{},\"39\":{},\"40\":{},\"41\":{},\"42\":{},\"43\":{},\"44\":{},\"45\":{},\"46\":{},\"47\":{},\"48\":{},\"49\":{},\"50\":{},\"51\":{},\"52\":{},\"53\":{},\"54\":{},\"55\":{},\"56\":{},\"57\":{},\"58\":{}}}],[\"podifysafe\",{\"_index\":20,\"name\":{\"19\":{}},\"parent\":{}}],[\"proposal\",{\"_index\":60,\"name\":{\"59\":{}},\"parent\":{\"60\":{},\"61\":{},\"62\":{},\"63\":{},\"64\":{},\"65\":{},\"66\":{},\"67\":{},\"68\":{},\"69\":{},\"70\":{},\"71\":{},\"72\":{},\"73\":{},\"74\":{},\"75\":{}}}],[\"proposalstatus\",{\"_index\":73,\"name\":{\"76\":{}},\"parent\":{}}],[\"propose\",{\"_index\":49,\"name\":{\"48\":{}},\"parent\":{}}],[\"provider\",{\"_index\":7,\"name\":{\"7\":{}},\"parent\":{}}],[\"reject\",{\"_index\":70,\"name\":{\"73\":{}},\"parent\":{}}],[\"rejections\",{\"_index\":64,\"name\":{\"66\":{}},\"parent\":{}}],[\"safe\",{\"_index\":26,\"name\":{\"25\":{}},\"parent\":{}}],[\"status\",{\"_index\":61,\"name\":{\"63\":{}},\"parent\":{}}],[\"subgraphurl\",{\"_index\":11,\"name\":{\"10\":{}},\"parent\":{}}],[\"threshold\",{\"_index\":29,\"name\":{\"28\":{},\"67\":{}},\"parent\":{}}],[\"timestamp\",{\"_index\":68,\"name\":{\"71\":{}},\"parent\":{}}],[\"transferadmin\",{\"_index\":55,\"name\":{\"54\":{}},\"parent\":{}}],[\"transfermembership\",{\"_index\":53,\"name\":{\"52\":{}},\"parent\":{}}],[\"value\",{\"_index\":67,\"name\":{\"70\":{}},\"parent\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file diff --git a/docs/classes/Pod.html b/docs/classes/Pod.html index 8568aed..3807c84 100644 --- a/docs/classes/Pod.html +++ b/docs/classes/Pod.html @@ -10,30 +10,38 @@

You can also check if a user is a member, admin, or member of those pods with the following functions:

const pod = await getPod(podAddress);

const isMember = await pod.isMember(userAddress);
// Not an async function
const isAdmin = pod.isAdmin(userAddress);

const isAdminPodMember = await pod.isAdminPodMember(userAddress);

// Includes both pods and users as sub pod members.
const isSubPodMember = await pod.isSubPodMember(userAddress);
-

Hierarchy

Index

Constructors

Hierarchy

Index

Constructors

  • new Pod(identifier: string | number): Pod
  • Note this constructor should not be called directly. Use getPod() instead.

    Parameters

    • identifier: string | number

      Can be either podId or safe address

      -

    Returns Pod

Properties

address: string
property

Gnosis Safe address, duplicate of safe

-
admin: string
property

Admin address

-
controller: string
description: string
property

Description of NFT

-
ensName: string
property

ENS name

-
id: number
property

Pod ID

-
imageNoTextUrl: string
property

Link to Pod NFT image with no text

-
imageUrl: string
property

Link to Pod NFT image

-
nonce: number
property

Current nonce, i.e., the nonce of the active proposal

-
safe: string
property

Gnosis Safe address

-
threshold: number
property

Number of votes required to pass a proposal

-

Methods

  • batchMintAndBurn(mintMembers: string[], burnMembers: string[], signer?: Signer): Promise<any>

Returns Pod

Properties

address: string
property

Gnosis Safe address, duplicate of safe

+
admin: string
property

Admin address

+
controller: string
description: string
property

Description of NFT

+
ensName: string
property

ENS name

+
id: number
property

Pod ID

+
imageNoTextUrl: string
property

Link to Pod NFT image with no text

+
imageUrl: string
property

Link to Pod NFT image

+
nonce: number
property

Current nonce, i.e., the nonce of the active proposal

+
safe: string
property

Gnosis Safe address

+
threshold: number
property

Number of votes required to pass a proposal

+

Methods

  • batchMintAndBurn(mintMembers: string[], burnMembers: string[], signer?: Signer): Promise<any>
  • Mints and burns members simultaneously.

    -

    Parameters

    • mintMembers: string[]
    • burnMembers: string[]
    • Optional signer: Signer

    Returns Promise<any>

  • burnMember(memberToBurn: string | string[], signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • +

    Parameters

    • mintMembers: string[]
    • burnMembers: string[]
    • Optional signer: Signer

    Returns Promise<any>

  • burnMember(memberToBurn: string | string[], signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Burns member(s) from this pod, or returns an unsigned transaction to do so.

    throws

    If signer is not admin

    Parameters

    • memberToBurn: string | string[]

      Can be a single address or an array of addresses

    • Optional signer: Signer

      If a signer is provided, then the tx will execute. Otherwise, an unsigned transaction will be returned.

      -

    Returns Promise<TransactionResponse | { data: string; to: string }>

  • changeThreshold(newThreshold: number, signer?: Signer): Promise<any>

Returns Promise<TransactionResponse | { data: string; to: string }>

  • callAsPersona(method: any, args: any[], persona: { address: string; type: string }, sender?: string | Signer): Promise<any>
  • +

    Calls a Pod method via a persona. +The persona object can be fetched by using Pod.getPersonas(address) +E.g.,

    +
    callAsPersona(
    pod.mintMember,
    [newMember],
    { type: 'admin', address: userAddress },
    signer,
    ) +
    +

    The sender must be a signer in the admin case, or the address of the sender. +The sender must be a member of the relevant pod.

    +

    Parameters

    • method: any
    • args: any[]
    • persona: { address: string; type: string }
      • address: string
      • type: string
    • Optional sender: string | Signer

    Returns Promise<any>

  • changeThreshold(newThreshold: number, signer?: Signer): Promise<any>
  • Changes the threshold for the safe associated with this pod. If a signer is provided, it will execute the transaction. Otherwise it will return the unsigned tx.

    throws

    If signer is not admin

    @@ -41,30 +49,36 @@

    new threshold

  • Optional signer: Signer

    Signer of admin

    -

Returns Promise<any>

  • createRejectProposal(nonce: number, signer: string | Signer): Promise<void>

Returns Promise<any>

  • createRejectProposal(nonce: number, signer: string | Signer): Promise<void>
  • Creates a reject proposal at a given nonce, mostly used to un-stuck the transaction queue

    Parameters

    • nonce: number

      nonce to create the reject transaction at

    • signer: string | Signer

      Signer or address of pod member

      -

    Returns Promise<void>

  • ejectSafe(signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>

Returns Promise<void>

  • ejectSafe(signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Ejects a safe from the Orca ecosystem. This zeroes out all ENS + Controller data, removes the Orca module, and burns the pod's MemberTokens If a signer is provided, it will execute the transaction. Otherwise it will return the unsigned tx.

    This function can also clean up data for safes that have already removed the Orca module, but note that the reverse resolver must be zeroed out by the safe manually in this case.

    -

    Parameters

    • Optional signer: Signer

    Returns Promise<TransactionResponse | { data: string; to: string }>

  • getMemberEOAs(): Promise<string[]>
  • +

    Parameters

    • Optional signer: Signer

    Returns Promise<TransactionResponse | { data: string; to: string }>

  • getMemberEOAs(): Promise<string[]>
  • Returns list of all member EOAs, not including any smart contract/pod members.

    -

    Returns Promise<string[]>

  • getMemberPods(): Promise<Pod[]>
  • getMemberPods(): Promise<Pod[]>
  • Returns Pod objects of all member pods.

    -

    Returns Promise<Pod[]>

  • getMembers(): Promise<string[]>
  • getMembers(): Promise<string[]>
  • Returns of list of all member addresses. Members include member pods and member EOAs

    -

    Returns Promise<string[]>

  • getProposal(identifier: string | number): Promise<Proposal>
  • getPersonas(address: string): Promise<{ address: string; type: string }[]>
  • +

    Fetches all personas for a given address related to this pod. +All personas return as an object indicating the type of the persona and the address of the persona. +For members and admins, the persona address is the user's address. +For admin pods and sub pods, the persona address is the pod address.

    +

    Parameters

    • address: string
      +

    Returns Promise<{ address: string; type: string }[]>

  • getProposal(identifier: string | number): Promise<Proposal>
  • Gets a specific proposal by either nonce or the safeTxHash.

    Parameters

    • identifier: string | number

      Can be either the proposal id/nonce (preferred), or the safeTxHash

      -

    Returns Promise<Proposal>

Returns Promise<Proposal>

  • Returns an array of Proposal objects in reverse chronological order. Defaults to returning 5, which can be overridden by passing { limit: 10 } for example in the options.

    By default, the first Proposal will be the active proposal, if there is one, and then any executed proposals.

    @@ -72,40 +86,40 @@ proposals, then the active proposal, then executed proposals (up to the requested limit).

    Executed proposals can be fetched by passing { status: 'passed' } or { status: 'rejected' } in the options. This will return only executed proposals.

    -

    Parameters

    Returns Promise<Proposal[]>

  • getSubPodsByMember(address: string): Promise<Pod[]>
  • getSubPodsByMember(address: string): Promise<Pod[]>
  • Returns all sub pods of this pod that an address is the member of.

    Parameters

    • address: string
      -

    Returns Promise<Pod[]>

  • getSuperPods(): Promise<Pod[]>

Returns Promise<Pod[]>

  • getSuperPods(): Promise<Pod[]>
  • Returns an array of this pod's super pods, i.e., pods that this pod is a member of

    -

    Returns Promise<Pod[]>

  • getSuperProposals(): Promise<Proposal[]>
  • getSuperProposals(): Promise<Proposal[]>
  • Returns an array of all active super proposals, i.e., active proposals of any super pods

    -

    Returns Promise<Proposal[]>

  • isAdmin(address: string): boolean
  • isAdmin(address: string): boolean
  • Checks if user is admin of this pod

    Parameters

    • address: string
      -

    Returns boolean

  • isAdminPodMember(address: string): Promise<boolean>

Returns boolean

  • isAdminPodMember(address: string): Promise<boolean>
  • Checks if given address is a member of the admin pod (if there is one) Returns false if there is no admin pod.

    -

    Parameters

    • address: string

    Returns Promise<boolean>

  • isMember(address: string): Promise<boolean>
  • +

    Parameters

    • address: string

    Returns Promise<boolean>

  • isMember(address: string): Promise<boolean>
  • Checks if user is a member of this pod

    Parameters

    • address: string
      -

    Returns Promise<boolean>

  • isPodifyInProgress(): Promise<boolean>
  • isSubPodMember(address: string): Promise<boolean>

Returns Promise<boolean>

  • isPodifyInProgress(): Promise<boolean>
  • isSubPodMember(address: string): Promise<boolean>
  • Checks if given address is a member of any subpods. Returns false if the user is a member of this pod, but not any sub pods

    Parameters

    • address: string
      -

    Returns Promise<boolean>

  • migratePodToLatest(signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>

Returns Promise<boolean>

  • migratePodToLatest(signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Migrates the pod to the latest version. Signer must be the admin of pod. If a signer is provided, it will execute the transaction. Otherwise it will return the unsigned tx.

    throws

    If signer is not pod admin

    Parameters

    • Optional signer: Signer

      Signer of pod admin

      -

    Returns Promise<TransactionResponse | { data: string; to: string }>

  • mintMember(newMember: string | string[], signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>

Returns Promise<TransactionResponse | { data: string; to: string }>

  • mintMember(newMember: string | string[], signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Mints member(s) to this pod, or returns an unsigned transaction to do so.

    throws

    if signer is not admin

    Parameters

    • newMember: string | string[]

      Can be a single address or an array of addresses

    • Optional signer: Signer

      If a signer is provided, then the tx will execute. Otherwise, an unsigned transaction will be returned.

      -

    Returns Promise<TransactionResponse | { data: string; to: string }>

  • propose(proposal: Proposal | TransactionResponse | { data: string; to: string }, sender: string, opts?: { nonce?: number }): Promise<Proposal>

Returns Promise<TransactionResponse | { data: string; to: string }>

  • propose(proposal: Proposal | TransactionResponse | { data: string; to: string }, sender: string, opts?: { nonce?: number }): Promise<Proposal>
  • Creates a proposal on the pod.

    If the proposal parameter is in the { data, to } format, this will create a proposal to execute an arbitrary smart contract function on this pod.

    @@ -129,7 +143,7 @@

    Address of sender

  • opts: { nonce?: number } = {}
    • Optional nonce?: number

      Optional nonce. This will create a proposal with the given nonce.

      -

Returns Promise<Proposal>

  • transferAdmin(addressToTransferTo: string, signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>

Returns Promise<Proposal>

  • transferAdmin(addressToTransferTo: string, signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Transfers admin role from signer's account to addressToTransferTo If a signer is provided, it will execute the transaction. Otherwise it will return the unsigned tx.

    throws

    If signer is not admin

    @@ -137,7 +151,7 @@

    Address that will receive admin role

  • Optional signer: Signer

    Signer of admin

    -

Returns Promise<TransactionResponse | { data: string; to: string }>

  • transferMembership(fromAddress: string, toAddress: string, signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>

Returns Promise<TransactionResponse | { data: string; to: string }>

  • transferMembership(fromAddress: string, toAddress: string, signer?: Signer): Promise<TransactionResponse | { data: string; to: string }>
  • Transfers a membership. If a signer is provided, it will execute the transaction. Otherwise it will return the unsigned tx.

    throws

    If toAddress is already a member

    throws

    if fromAddress is not a member

    @@ -148,4 +162,4 @@

    Address that will receive membership

  • Optional signer: Signer

    If a signer is provided, then the tx will execute. Otherwise, an unsigned transaction will be returned.

    -

Returns Promise<TransactionResponse | { data: string; to: string }>

Generated using TypeDoc

\ No newline at end of file +

Returns Promise<TransactionResponse | { data: string; to: string }>

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/classes/Proposal.html b/docs/classes/Proposal.html index 98e7808..62b9ae7 100644 --- a/docs/classes/Proposal.html +++ b/docs/classes/Proposal.html @@ -1,40 +1,40 @@ Proposal | @orcaprotocol/orca-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

The Proposal object is the interface for interacting with any Proposals. Can be gotten via the Pod object, through Pod.getProposals.

-

Hierarchy

  • Proposal

Index

Constructors

  • new Proposal(Pod: Pod, podNonce: number, safeTransaction: SafeTransaction, rejectTransaction?: SafeTransaction): Proposal

Hierarchy

  • Proposal

Index

Constructors

  • new Proposal(Pod: Pod, podNonce: number, safeTransaction: SafeTransaction, rejectTransaction?: SafeTransaction): Proposal
  • Transforms a Safe Transaction object into one of our Proposals.

    Parameters

    • Pod: Pod
    • podNonce: number
    • safeTransaction: SafeTransaction
    • Optional rejectTransaction: SafeTransaction

      Optional reject transaction

      -

    Returns Proposal

Properties

approvals: string[]
property

Array of addresses that approved

-
id: number
property

Proposal ID, i.e., the Gnosis nonce. This is not necessarily a unique number

-
isSubProposal?: boolean
property

Whether or not this proposal corresponds to a superproposal

-
method?: string
property

Name of smart contract method being called, if there is one

-
parameters?: { name: string; type: string; value: string }[]
property

Parameters for the smart contract function being called, if there is one

-
pod: Pod
property

Pod object this Proposal is associated with

-
rejections: string[]
property

Array of addresses that rejected

-
property

Proposal status, i.e., 'active', 'passed', 'rejected', or 'queued',

-
threshold: number
property

Number of votes required to pass/reject a proposal

-
timestamp: Date
value: string
property

Eth value of transfer in Wei, if there is one

-

Methods

  • approve(signer: Signer): Promise<void>

Returns Proposal

Properties

approvals: string[]
property

Array of addresses that approved

+
id: number
property

Proposal ID, i.e., the Gnosis nonce. This is not necessarily a unique number

+
isSubProposal?: boolean
property

Whether or not this proposal corresponds to a superproposal

+
method?: string
property

Name of smart contract method being called, if there is one

+
parameters?: { name: string; type: string; value: string }[]
property

Parameters for the smart contract function being called, if there is one

+
pod: Pod
property

Pod object this Proposal is associated with

+
rejections: string[]
property

Array of addresses that rejected

+
property

Proposal status, i.e., 'active', 'passed', 'rejected', or 'queued',

+
threshold: number
property

Number of votes required to pass/reject a proposal

+
timestamp: Date
value: string
property

Eth value of transfer in Wei, if there is one

+

Methods

  • approve(signer: Signer): Promise<void>
  • Votes to approve the proposal

    throws

    If signer already approved proposal

    throws

    If signer is not a pod member

    throws

    If there was an error approving Proposal

    Parameters

    • signer: Signer

      Signer of pod member

      -

    Returns Promise<void>

  • executeApprove(signer: Signer): Promise<any>

Returns Promise<void>

  • executeApprove(signer: Signer): Promise<any>
  • Executes proposal

    throws

    If not enough approvals to execute

    throws

    If signer was not part of the pod

    Parameters

    • signer: Signer

      Signer of pod member

      -

    Returns Promise<any>

  • executeReject(signer: Signer): Promise<any>

Returns Promise<any>

  • executeReject(signer: Signer): Promise<any>
  • Executes the rejection of proposal

    throws

    If not enough rejections to execute

    throws

    If signer was not part of the pod

    Parameters

    • signer: Signer

      Signer of pod member

      -

    Returns Promise<any>

  • reject(signer: Signer): Promise<void>

Returns Promise<any>

  • reject(signer: Signer): Promise<void>
  • Votes to reject the proposal

    throws

    If signer has already rejected proposal

    throws

    If signer was not pod member

    diff --git a/docs/modules.html b/docs/modules.html index 90c04f4..1dfbc56 100644 --- a/docs/modules.html +++ b/docs/modules.html @@ -1,7 +1,7 @@ -@orcaprotocol/orca-sdk
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    @orcaprotocol/orca-sdk

    Index

    Type aliases

    ProposalStatus: "active" | "passed" | "executed" | "rejected" | "queued"

    Variables

    config: { etherscanApiKey: any; etherscanUrl: any; gnosisUrl: any; multicall: any; network: any; provider: any; subgraphUrl: any } = ...
    +@orcaprotocol/orca-sdk
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    @orcaprotocol/orca-sdk

    Index

    Type aliases

    ProposalStatus: "active" | "passed" | "executed" | "rejected" | "queued"

    Variables

    config: { etherscanApiKey: any; etherscanUrl: any; gnosisUrl: any; multicall: any; network: any; provider: any; subgraphUrl: any } = ...

    The config object. This object should not be manipulated directly, and is exported mostly for debug purposes.

    -

    Type declaration

    • etherscanApiKey: any
    • etherscanUrl: any
    • gnosisUrl: any
    • multicall: any
    • network: any
    • provider: any
    • subgraphUrl: any

    Functions

    • customSubgraphQuery(query: string): Promise<any>
    • +

      Type declaration

      • etherscanApiKey: any
      • etherscanUrl: any
      • gnosisUrl: any
      • multicall: any
      • network: any
      • provider: any
      • subgraphUrl: any

    Functions

    • customSubgraphQuery(query: string): Promise<any>
    • Makes a custom call on the subgraph by passing a query in directly. Note that this data will likely require manual transformation to be usable.

      Example: Making a call to retrieve pod IDs 1 through 3:

      @@ -28,47 +28,47 @@ }


      Note these are not Pod objects as defined by the SDK.

      @param query - GraphQL query
      @returns
      -

      Parameters

      • query: string

      Returns Promise<any>

    • enableController(safe: string, signer: Signer): Promise<void>
    • enableController(safe: string, signer: Signer): Promise<void>
    • Creates a SafeTx on a safe to enable the latest Controller as a module.

      throws

      If a Controller module is already enabled. If you are attempting to upgrade versions, use Pod.migratePodToLatest.

      Parameters

      • safe: string

        Safe address

        -
      • signer: Signer

      Returns Promise<void>

    • fetchAdminPodIds(address: string): Promise<number[]>

    Returns Promise<void>

  • fetchAdminPodIds(address: string): Promise<number[]>
  • Returns an array of Pod IDs from sub graph that an address is the admin of This function bypasses Pod construction and is mostly used for optimization purposes. If you're unsure on what function to use, use getAdminPods instead.

    Parameters

    • address: string
      -

    Returns Promise<number[]>

  • fetchPodUsers(id: number): Promise<string[]>

Returns Promise<number[]>

  • fetchPodUsers(id: number): Promise<string[]>
  • Returns an array of addresses of all pod members.

    Parameters

    • id: number
      -

    Returns Promise<string[]>

  • fetchUserPodIds(address: string): Promise<number[]>

Returns Promise<string[]>

  • fetchUserPodIds(address: string): Promise<number[]>
  • Returns a list of Pod IDs from subgraph that user is a member of. This function bypasses Pod construction and is mostly used for optimization purposes. If you're unsure on what function to use, use getUserPods instead.

    Parameters

    • address: string
      -

    Returns Promise<number[]>

  • getAdminPods(address: string): Promise<Pod[]>

Returns Promise<number[]>

  • getAdminPods(address: string): Promise<Pod[]>
  • Gets an array of Pod objects that a user is the admin of

    Parameters

    • address: string

      user address

      -

    Returns Promise<Pod[]>

  • getPod(identifier: string | number): Promise<Pod>

Returns Promise<Pod[]>

  • getPod(identifier: string | number): Promise<Pod>
  • Gets a pod object.

    Parameters

    • identifier: string | number

      Pod ID (as number), safe address, or ENS name

      -

    Returns Promise<Pod>

Returns Promise<Pod>

  • Gets the super proposal that the sub proposal relates to

    throws

    If this proposal is not a sub proposal

    throws

    If the found super proposal does not relate to this sub proposal.

    -

    Parameters

    Returns Promise<Proposal>

  • getUserPods(address: string): Promise<Pod[]>
  • getUserPods(address: string): Promise<Pod[]>
  • Fetches an array of Pod objects that a user is a member of

    Parameters

    • address: string

      user address

      -

    Returns Promise<Pod[]>

  • init(input: { network: number; provider: Provider; subgraphUrl?: string }): void

Returns Promise<Pod[]>

  • init(input: { network: number; provider: Provider; subgraphUrl?: string }): void
  • Initializes the SDK. This should be called on app startup.

    Parameters

    • input: { network: number; provider: Provider; subgraphUrl?: string }
      • network: number

        Network ID. Currently supporting Mainnet (id 1) and Goerli (id 5)

      • provider: Provider
      • Optional subgraphUrl?: string

        Optional override for development/debug purposes.

        -

    Returns void

  • multiPodCreate(pods: { admin?: string; label: string; members: string[]; threshold: number }[], signer: Signer): Promise<any>

Returns void

  • multiPodCreate(pods: { admin?: string; label: string; members: string[]; threshold: number }[], signer: Signer): Promise<any>
  • Creates multiple pods simultaneously.

    Each pod requires an array of members, a threshold and label, with an optional admin. Members or admins can be other pods in this create action.

    @@ -81,7 +81,7 @@
     [
    {
    label: 'orcanauts',
    // This will add the below pods as sub pods to this newly created one.
    members: ['art-nauts', 'gov-nauts'],
    threshold: 1,
    },
    {
    label: 'art-nauts',
    members: ['0x1234...', '0x2345...'],
    threshold: 1,
    },
    {
    label: 'gov-nauts',
    members: ['0x3456...', '0x4567...'],
    threshold: 1,
    // This will add the above 'orcanauts' pod as the admin to this new pod.
    admin: 'orcanauts',
    }
    ]

    Parameters

    • pods: { admin?: string; label: string; members: string[]; threshold: number }[]
      -
    • signer: Signer

    Returns Promise<any>

  • podifySafe(args: { admin?: string; name: string; safe: string }, signer?: Signer): Promise<ethers.providers.TransactionResponse | { data: string; to: string }>

Returns Promise<any>

  • podifySafe(args: { admin?: string; name: string; safe: string }, signer?: Signer): Promise<ethers.providers.TransactionResponse | { data: string; to: string }>
  • Adds a Gnosis Safe to the pod ecosystem. If a signer is not provided, it instead returns the unsigned transaction.

    throws
      diff --git a/scripts/approve-superproposal.ts b/scripts/approve-superproposal.ts index 57afa1a..6b451c6 100644 --- a/scripts/approve-superproposal.ts +++ b/scripts/approve-superproposal.ts @@ -26,9 +26,9 @@ async function main() { let data; try { if (isMember) { - data = superPod.populateBurn(dummyAccount); + data = superPod.burnMember(dummyAccount); } else { - data = superPod.populateMint(dummyAccount); + data = superPod.mintMember(dummyAccount); } await superPod.propose(data, subPod.safe); } catch (err) { diff --git a/scripts/sandbox.ts b/scripts/sandbox.ts index 37b3aae..ea6e40e 100644 --- a/scripts/sandbox.ts +++ b/scripts/sandbox.ts @@ -77,9 +77,31 @@ const multiPodInput = [ async function main() { const { walletOne } = setup(5); - const pod = await getPod(25); - + const pod = await getPod('balloon.pod.eth'); console.log('pod', pod); + const admin = pod.admin; + console.log(admin, 'ADMIN'); + const adminPod = await getPod(pod.admin); + console.log(adminPod, 'ADMIN POD'); + const personas = await pod.getPersonas('0x3d76351819c5b188C0f7447fe7D1C7AA3e0325C0'); + console.log('personas', personas); + + // await pod.callAsPersona( + // pod.burnMember, + // ['0x8d2d96d31e86843e9B71E635beA331f9b1016055'], + // personas[0] + // ); + + // const pod = await getPod('balloon.pod.eth'); + // console.log('pod', pod); + // const personas = await pod.getPersonas('0x3d76351819c5b188C0f7447fe7D1C7AA3e0325C0'); + // console.log('personas', personas); + + // await pod.callAsPersona( + // pod.mintMember, + // ['0x8d2d96d31e86843e9B71E635beA331f9b1016055'], + // personas[2], + // ); } main(); diff --git a/scripts/utils.ts b/scripts/utils.ts index 2de6b46..72c9859 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -15,10 +15,7 @@ export function sleep(ms) { export function setup(network = 4) { const networkName = network === 1 ? 'mainnet' : 'goerli'; - const provider = new ethers.providers.InfuraProvider( - networkName, - '69ecf3b10bc24c6a972972666fe950c8', - ); + const provider = new ethers.providers.InfuraProvider(networkName, process.env.INFURA_KEY); init({ provider, network }); // Get two accounts diff --git a/src/Pod.ts b/src/Pod.ts index 2a501a7..b863b14 100644 --- a/src/Pod.ts +++ b/src/Pod.ts @@ -2,6 +2,7 @@ import { ethers } from 'ethers'; import ENS, { labelhash } from '@ensdomains/ensjs'; import { getControllerByAddress, getDeployment } from '@orcaprotocol/contracts'; import axios from 'axios'; +import { getPersonas } from './pod-utils'; import { config } from './config'; import { getPodFetchersByAddressOrEns, getPodFetchersById } from './fetchers'; import { @@ -187,6 +188,12 @@ export default class Pod { */ memberEOAs?: string[]; + /** + * @ignore + * @property Admin pod object + */ + adminPod?: Pod; + /** * @ignore * @property Array of Pod objects for any member pods @@ -326,7 +333,9 @@ export default class Pod { } // All safe transactions that have a given nonce. - const safeTransactions = await getSafeTransactionsBySafe(this.safe, { nonce }); + const safeTransactions = await getSafeTransactionsBySafe(this.safe, { + nonce, + }); if (safeTransactions.length === 0) throw new Error('Could not find a related safe transaction'); if (safeTransactions.length === 1) return new Proposal(this, this.nonce, safeTransactions[0]); if (safeTransactions.length === 2) @@ -418,6 +427,105 @@ export default class Pod { return this.memberPods; }; + /** + * Calls a Pod method via a persona. + * The persona object can be fetched by using `Pod.getPersonas(address)` + * E.g., + * ``` + * callAsPersona( + * pod.mintMember, + * [newMember], + * { type: 'admin', address: userAddress }, + * signer, + * ) + * ``` + * The sender must be a signer in the admin case, or the address of the sender. + * The sender must be a member of the relevant pod. + * + * @param method + * @param args + * @param persona + * @param sender + * @returns + */ + callAsPersona = async ( + method: any, + args: Array, + persona: { type: string; address: string }, + sender?: ethers.Signer | string, + ) => { + const senderAddress = sender instanceof ethers.Signer ? await sender.getAddress() : sender; + switch (persona.type) { + case 'admin': + // for the admin case, the sender must be a signer + if (!sender) throw new Error(`Expected sender to be signer, but received ${sender}`); + args.push(sender); + // admin personas do not require proposals + return method.apply(this, args); + case 'member': + // member personas require proposals to be created + return this.propose(await method.apply(this, args), persona.address); + case 'adminPodMember': { + let adminPod; + // if an admin pod object exists, use that + if (this.adminPod) adminPod = this.adminPod; + else { + // create a new admin pod object with admin address + adminPod = await new Pod(this.admin); + this.adminPod = adminPod; + } + let result; + try { + // admin pods require proposal creation + result = await adminPod.propose(await method.apply(this, args), senderAddress); + } catch (err) { + // Make the error message more specific + if (err.message.includes('Sender must be a member of')) { + throw new Error('Sender must be a member of the admin pod'); + } + } + return result; + } + case 'subPodMember': { + // create a new pod object with sub pod address + const subPod = await new Pod(persona.address); + + // check to see if sub pod is member of the pod + const isSubPodMember = await this.isMember(subPod.safe); + + if (!isSubPodMember) throw new Error('Sub pod is not a member of this pod'); + let result; + try { + // sub pods require proposal creation + result = await subPod.propose( + await this.propose(await method.apply(this, args), subPod.safe), + senderAddress, + ); + } catch (err) { + // Make the error message more specific + if (err.message.includes('Sender must be a member of')) { + throw new Error('Sender must be a member of the sub pod'); + } + } + return result; + } + default: + throw new Error(`${persona.type} is not a valid persona`); + } + }; + + /** + * Fetches all personas for a given address related to this pod. + * All personas return as an object indicating the type of the persona and the address of the persona. + * For members and admins, the persona address is the user's address. + * For admin pods and sub pods, the persona address is the pod address. + * @param address + */ + getPersonas(address: string) { + // Function declared separately out for test/mocking purposes. + return getPersonas(this, address); + } + /** * Checks if user is a member of this pod * @param address @@ -444,7 +552,13 @@ export default class Pod { isAdminPodMember = async (address: string): Promise => { const checkedAddress = checkAddress(address); if (!this.admin) return false; - const adminPod = await new Pod(this.admin); + let adminPod; + if (this.adminPod) adminPod = this.adminPod; + else { + adminPod = await new Pod(this.admin); + this.adminPod = adminPod; + } + if (!adminPod) return false; return adminPod.isMember(checkedAddress); }; diff --git a/src/pod-utils.ts b/src/pod-utils.ts new file mode 100644 index 0000000..4ad431c --- /dev/null +++ b/src/pod-utils.ts @@ -0,0 +1,21 @@ +import type Pod from './Pod'; + +// Functions are put here so that they can be mocked for testing purposes. + +// eslint-disable-next-line import/prefer-default-export +export async function getPersonas( + pod: Pod, + address: string, +): Promise> { + const personas = []; + if (pod.isAdmin(address)) personas.push({ type: 'admin', address }); + if (await pod.isAdminPodMember(address)) + personas.push({ type: 'adminPodMember', address: pod.admin }); + if (await pod.isMember(address)) personas.push({ type: 'member', address }); + + const memberSubPods = await pod.getSubPodsByMember(address); + memberSubPods.forEach(subPod => { + personas.push({ type: 'subPodMember', address: subPod.safe }); + }); + return personas; +} diff --git a/test/init.test.ts b/test/init.test.ts index b6d1d0a..08a232f 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -2,7 +2,7 @@ import { ethers } from 'ethers'; import { init, config } from '../src'; const provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); test('init should throw if it receives something other than 1 or 5', async () => { diff --git a/test/pod-create.test.ts b/test/pod.create.test.ts similarity index 98% rename from test/pod-create.test.ts rename to test/pod.create.test.ts index 4967ae3..bbb4fc3 100644 --- a/test/pod-create.test.ts +++ b/test/pod.create.test.ts @@ -14,7 +14,7 @@ import { userAddress, userAddress2, orcanautAddress } from './fixtures'; beforeAll(async () => { const provider = new ethers.providers.InfuraProvider('goerli', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); init({ provider, network: 5 }); }); @@ -41,7 +41,12 @@ describe('pod create', () => { createPod: mockCreate, }); await createPod( - { members: [userAddress, userAddress2], admin: userAddress, threshold: 1, name: 'test' }, + { + members: [userAddress, userAddress2], + admin: userAddress, + threshold: 1, + name: 'test', + }, mockSigner, ); expect(mockCreate).toHaveBeenCalledWith( diff --git a/test/pod.persona.test.ts b/test/pod.persona.test.ts new file mode 100644 index 0000000..72c4070 --- /dev/null +++ b/test/pod.persona.test.ts @@ -0,0 +1,219 @@ +import { ethers } from 'ethers'; +import axios from 'axios'; +import { init, getPod } from '../src'; +import * as createSafe from '../src/lib/services/create-safe-transaction'; +import { userAddress2, constructGqlGetUsers, getSafeTransactionFixture } from './fixtures'; +import * as fetchers from '../src/fetchers'; +import * as utils from '../src/lib/utils'; + +// Some of these tests run long. +jest.setTimeout(7500); + +const adminAddress = '0xf0C7d25c942264D6F21871c05d3dB3b98344b499'; +const adminPodAddress = '0xa60DDcba1C0160595BA435b7fed98783EC13cE05'; +const podId = 6; +const podName = '1-member-pods.pod.eth'; +const adminPodName = '1-root-as-admin.pod.eth'; +const podAddress = '0xC99cE75a83B068DABF48c48f91C62a30fe0afBd2'; +const subPodAddress = '0x203D96211d5f0e0De9788302505dd37D26a28005'; +const podMemberOne = '0x61De0bbb6C8215Af3f821FE4884A28bc737f98D3'; +const podMemberTwo = '0x85760ef61c0ccB7BCC4C7A0116d80D59D92e736d'; +const podMemberThree = '0x08A9C4898e045A4E176C2cbf4Ca86aEf9f6EA478'; +const adminPodAddressTwo = '0xBe71ECaA104645ab78ed62A52763b2854e6DaD2E'; + +function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { + const admin = opts?.overrideAdmin ? opts.overrideAdmin : adminAddress; + jest.spyOn(fetchers, 'getPodFetchersByAddressOrEns').mockResolvedValueOnce({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + Controller: { podAdmin: jest.fn().mockResolvedValueOnce(admin) }, + Safe: { + address: podAddress, + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), + }, + podId: podId, + Name: { name: podName }, + }); +} + +const provider = new ethers.providers.InfuraProvider('goerli', { + infura: process.env.INFURA_KEY, +}); + +beforeAll(async () => { + init({ provider, network: 5 }); +}); + +beforeEach(() => { + jest.restoreAllMocks(); +}); + +describe('admin member persona', () => { + test('Mint via admin persona throws if signer is not included', async () => { + mockGetPodFetchersByAddress(); + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([{ type: 'admin', address: adminAddress }]); + const personas = await pod.getPersonas(adminAddress); + await expect(pod.callAsPersona(pod.mintMember, [adminAddress], personas[0])).rejects.toThrow( + 'Expected sender to be signer, but received', + ); + }); + + test('Mint via admin persona calls the function as an admin', async () => { + mockGetPodFetchersByAddress(); + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([{ type: 'admin', address: adminAddress }]); + const personas = await pod.getPersonas(adminAddress); + + const mockSigner = { + getAddress: jest.fn().mockResolvedValueOnce(adminAddress), + }; + + const mockMint = jest.fn(); + jest.spyOn(utils, 'getMetropolisContract').mockReturnValueOnce({ + mint: mockMint, + }); + + await pod.callAsPersona(pod.mintMember, [adminAddress], personas[0], mockSigner); + // expect(mockMint).toHaveBeenCalled(); + expect(mockMint).toHaveBeenCalledWith(adminAddress, podId, ethers.constants.HashZero); + }); + + test('Mint via admin persona throws if the signer is not the admin', async () => { + mockGetPodFetchersByAddress(); + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([{ type: 'admin', address: adminAddress }]); + const personas = await pod.getPersonas(adminAddress); + + const mockSigner = { + getAddress: jest.fn().mockResolvedValueOnce(podMemberOne), + }; + + const mockMint = jest.fn(); + jest.spyOn(utils, 'getMetropolisContract').mockReturnValueOnce({ + mint: mockMint, + }); + + await expect( + pod.callAsPersona(pod.mintMember, [adminAddress], personas[0], mockSigner), + ).rejects.toThrow('Signer was not admin'); + }); +}); + +describe('member persona', () => { + test('Mint via member persona creates a proposal', async () => { + mockGetPodFetchersByAddress(); + jest.spyOn(axios, 'post').mockResolvedValueOnce(constructGqlGetUsers([podMemberOne])); + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([{ type: 'member', address: podMemberOne }]); + const personas = await pod.getPersonas(podMemberOne); + + const create = jest + .spyOn(createSafe, 'createSafeTransaction') + .mockResolvedValue(getSafeTransactionFixture()); + + await pod.callAsPersona(pod.mintMember, [userAddress2], personas[0]); + + expect(create).toHaveBeenCalled(); + }); + + test('Mint via member persona throws if the persona address is not a member', async () => { + mockGetPodFetchersByAddress(); + jest.spyOn(axios, 'post').mockResolvedValueOnce(constructGqlGetUsers([podMemberOne])); + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([{ type: 'member', address: userAddress2 }]); + const personas = await pod.getPersonas(podMemberOne); + + await expect(pod.callAsPersona(pod.mintMember, [userAddress2], personas[0])).rejects.toThrow( + 'Sender must be a member of this pod or one of its sub pods', + ); + }); +}); + +describe('admin member pod persona', () => { + test('Mint via adminPodMember persona creates a proposal', async () => { + mockGetPodFetchersByAddress({ + overrideAdmin: adminPodAddress, + }); + jest.spyOn(axios, 'post').mockResolvedValueOnce(constructGqlGetUsers([adminAddress])); + const create = jest + .spyOn(createSafe, 'createSafeTransaction') + .mockResolvedValue(getSafeTransactionFixture()); + + const pod = await getPod(adminPodName); + const personas = await pod.getPersonas(podMemberTwo); + + await pod.callAsPersona(pod.mintMember, [userAddress2], personas[0], podMemberTwo); + expect(create).toHaveBeenCalled(); + }); + + test('Mint via adminPodMember persona should throw if sender is not an admin pod member', async () => { + jest.spyOn(axios, 'post').mockResolvedValueOnce(constructGqlGetUsers([adminAddress])); + + const pod = await getPod(adminPodName); + pod.getPersonas = jest.fn().mockResolvedValue([ + { + type: 'adminPodMember', + address: adminPodAddressTwo, + }, + ]); + const personas = await pod.getPersonas(podMemberThree); + + await expect( + pod.callAsPersona(pod.mintMember, [userAddress2], personas[0], userAddress2), + ).rejects.toThrow('Sender must be a member of the admin pod'); + }); +}); + +describe('subd pod member persona', () => { + test('Mint via subPodMember persona creates a proposal', async () => { + mockGetPodFetchersByAddress(); + jest.spyOn(axios, 'post').mockResolvedValue(constructGqlGetUsers([podMemberTwo])); + const create = jest + .spyOn(createSafe, 'createSafeTransaction') + .mockResolvedValue(getSafeTransactionFixture()); + + const pod = await getPod(podName); + const personas = await pod.getPersonas(podMemberTwo); + + await pod.callAsPersona(pod.mintMember, [userAddress2], personas[0], podMemberTwo); + expect(create).toHaveBeenCalled(); + }); + + test('Mint via subPodMember persona should throw if sender is not a sub pod member', async () => { + jest.spyOn(axios, 'post').mockResolvedValueOnce(constructGqlGetUsers([adminAddress])); + + const pod = await getPod(adminPodName); + pod.getPersonas = jest.fn().mockResolvedValue([ + { + type: 'subPodMember', + address: subPodAddress, + }, + ]); + const personas = await pod.getPersonas(podMemberThree); + + await expect( + pod.callAsPersona(pod.mintMember, [userAddress2], personas[0], userAddress2), + ).rejects.toThrow('Sub pod is not a member of this pod'); + }); + + test('Mint via subPodMember persona should throw if the sub pod is not a member of the pod', async () => { + const pod = await getPod(podName); + pod.getPersonas = jest.fn().mockResolvedValue([ + { + type: 'subPodMember', + address: subPodAddress, + }, + ]); + const personas = await pod.getPersonas(podMemberThree); + + await expect(pod.callAsPersona(pod.mintMember, [userAddress2], personas[0])).rejects.toThrow( + 'Sub pod is not a member of this pod', + ); + }); +}); diff --git a/test/pod.propose.test.ts b/test/pod.propose.test.ts index f7a0aff..4a1685f 100644 --- a/test/pod.propose.test.ts +++ b/test/pod.propose.test.ts @@ -28,10 +28,12 @@ function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { }, Safe: { address: orcanautPod.safe, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: orcanautPod.id, Name: { name: orcanautPod.ensName }, @@ -50,10 +52,12 @@ function setupAdminAndSubPod() { }, Safe: { address: orcanautAddress, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: orcanautPod.id, Name: { name: orcanautPod.ensName }, @@ -66,10 +70,12 @@ function setupAdminAndSubPod() { }, Safe: { address: artNautPod.safe, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: artNautPod.id, Name: { name: artNautPod.ensName }, @@ -82,7 +88,7 @@ function setupAdminAndSubPod() { beforeAll(async () => { provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -106,7 +112,10 @@ test('Subpod members should be able to propose a mint member', async () => { .mockResolvedValue(erc20TransferTransaction); const pod = await sdk.getPod(orcanautAddress); - const mint = (await pod.mintMember(userAddress)) as { to: string; data: string }; + const mint = (await pod.mintMember(userAddress)) as { + to: string; + data: string; + }; await pod.propose(mint, artNautPod.members[0]); expect(create).toHaveBeenCalledWith({ @@ -126,7 +135,10 @@ test('Propose with a nonce should override the given nonce', async () => { .mockResolvedValue(erc20TransferTransaction); const pod = await sdk.getPod(orcanautAddress); - const mint = (await pod.mintMember(userAddress)) as { to: string; data: string }; + const mint = (await pod.mintMember(userAddress)) as { + to: string; + data: string; + }; await pod.propose(mint, artNautPod.members[0], { nonce: 5 }); expect(create).toHaveBeenCalledWith({ @@ -146,7 +158,10 @@ test('Sub pod members should be able to propose a super pod mint', async () => { const superPod = await sdk.getPod(orcanautAddress); const subPod = await sdk.getPod(artNautPod.safe); - const mint = (await superPod.mintMember(userAddress)) as { to: string; data: string }; + const mint = (await superPod.mintMember(userAddress)) as { + to: string; + data: string; + }; await subPod.propose(await superPod.propose(mint, orcanautPod.members[0]), artNautPod.members[0]); expect(create).toHaveBeenNthCalledWith(1, { diff --git a/test/pod.test.ts b/test/pod.test.ts index 513af8f..932245f 100644 --- a/test/pod.test.ts +++ b/test/pod.test.ts @@ -27,10 +27,12 @@ function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { }, Safe: { address: orcanautPod.safe, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: orcanautPod.id, Name: { name: orcanautPod.ensName }, @@ -38,7 +40,7 @@ function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { } const provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); beforeAll(async () => { @@ -149,10 +151,12 @@ test('Pod object should be able to fetch member pods via async call', async () = Controller: { podAdmin: jest.fn().mockResolvedValueOnce(artNautPod.admin) }, Safe: { address: artNautPod.safe, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: artNautPod.id, Name: { name: artNautPod.ensName }, @@ -179,10 +183,12 @@ test('Pod.getMembers() should include member pods in its list', async () => { Controller: { podAdmin: jest.fn().mockResolvedValueOnce(artNautPod.admin) }, Safe: { address: artNautPod.safe, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: artNautPod.id, Name: { name: artNautPod.ensName }, @@ -380,9 +386,9 @@ describe('Pod.migratePodToLatest', () => { // jest.mock('@orcaprotocol/contracts', () => ({ // getDeployment: jest.fn().mockReturnValue({ address: '0xDE69E7C2184599093a9E0Bbc5923fa462fdf0302' }), // })); - jest - .spyOn(contracts, 'getDeployment') - .mockReturnValue({ address: '0xDE69E7C2184599093a9E0Bbc5923fa462fdf0302' }); + jest.spyOn(contracts, 'getDeployment').mockReturnValue({ + address: '0xDE69E7C2184599093a9E0Bbc5923fa462fdf0302', + }); jest .spyOn(utils, 'getPreviousModule') .mockResolvedValueOnce('0x0000000000000000000000000000000000000001'); @@ -398,9 +404,9 @@ describe('Pod.migratePodToLatest', () => { test('Previous module should handle if a module was added after the Controller', async () => { mockGetPodFetchersByAddress(); const fakePreviousModule = '0x6636900672F411D7Cab64Aa30238DC2658D6Cbb5'; - jest - .spyOn(contracts, 'getDeployment') - .mockReturnValue({ address: '0xDE69E7C2184599093a9E0Bbc5923fa462fdf0302' }); + jest.spyOn(contracts, 'getDeployment').mockReturnValue({ + address: '0xDE69E7C2184599093a9E0Bbc5923fa462fdf0302', + }); jest.spyOn(utils, 'getPreviousModule').mockResolvedValueOnce(fakePreviousModule); const pod = await getPod(orcanautAddress); const result = await pod.migratePodToLatest(); diff --git a/test/proposal.test.ts b/test/proposal.test.ts index f74a879..bfcf1a5 100644 --- a/test/proposal.test.ts +++ b/test/proposal.test.ts @@ -17,10 +17,12 @@ function standardMock(fetchType?: string) { }, Safe: { address: '0x4d3ba1AdabA15796CC3d11E48e8EC28e3A5F7C41', - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 1) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 3) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 1), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 3), + }), }, podId: 5, // Arbitrary Name: { name: 'whatever.pod.eth' }, @@ -40,7 +42,7 @@ let provider; beforeAll(async () => { provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); provider.getSigner = () => { return { @@ -253,9 +255,9 @@ describe('Proposal approve/reject', () => { const mockSigner = { getAddress: jest.fn().mockResolvedValueOnce(userAddress), }; - const mockCreate = jest - .spyOn(txService, 'createRejectTransaction') - .mockResolvedValueOnce({ safe: '0x4d3ba1AdabA15796CC3d11E48e8EC28e3A5F7C41' }); + const mockCreate = jest.spyOn(txService, 'createRejectTransaction').mockResolvedValueOnce({ + safe: '0x4d3ba1AdabA15796CC3d11E48e8EC28e3A5F7C41', + }); const pod = await getPod('0x4d3ba1AdabA15796CC3d11E48e8EC28e3A5F7C41'); const proposal = (await pod.getProposals())[0]; diff --git a/test/token.test.ts b/test/token.test.ts index ced8d1b..b2d1a9a 100644 --- a/test/token.test.ts +++ b/test/token.test.ts @@ -32,10 +32,12 @@ function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { }, Safe: { address: orcanautAddress, - nonce: jest.fn().mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 5) }), - getThreshold: jest - .fn() - .mockResolvedValueOnce({ toNumber: jest.fn().mockImplementation(() => 10) }), + nonce: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 5), + }), + getThreshold: jest.fn().mockResolvedValueOnce({ + toNumber: jest.fn().mockImplementation(() => 10), + }), }, podId: orcanautPod.id, Name: { name: orcanautPod.ensName }, @@ -44,7 +46,7 @@ function mockGetPodFetchersByAddress(opts?: { overrideAdmin?: string }) { beforeAll(async () => { provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -73,7 +75,7 @@ describe('admin actions', () => { test('As an admin, I should be able to mint a member to a pod', async () => { provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/test/transaction-service.test.ts b/test/transaction-service.test.ts index 4813cb1..b10cc2f 100644 --- a/test/transaction-service.test.ts +++ b/test/transaction-service.test.ts @@ -6,7 +6,6 @@ import { populateDataDecoded, getSafeTxHash } from '../src/lib/services/transact import { getNextNonce } from '../src/lib/services/create-safe-transaction'; import { userAddress } from '../test/fixtures'; import { init } from '../src/config'; -import axios from 'axios'; import { ethers } from 'ethers'; test('populateDataDecoded should be able to decode an erc20 transfer function', async () => { @@ -40,7 +39,7 @@ test('populateDataDecoded should be able to decode an erc20 transfer function', describe('getSafeTxHash', () => { const provider = new ethers.providers.InfuraProvider('goerli', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); init({ provider, network: 5 }); diff --git a/test/user.test.ts b/test/user.test.ts index 9aa7b01..9680397 100644 --- a/test/user.test.ts +++ b/test/user.test.ts @@ -5,7 +5,7 @@ import { orcaCorePod, userAddress, gqlGetUserPods, gqlGetUserPodsEmpty } from '. beforeAll(async () => { const provider = new ethers.providers.InfuraProvider('mainnet', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); init({ provider, network: 1 }); }); @@ -73,7 +73,7 @@ describe('user memberships', () => { // test('getAdminPods should fetch Pod objects for all the pods an address is admin of', async () => { // const provider = new ethers.providers.InfuraProvider('mainnet', { -// infura: '69ecf3b10bc24c6a972972666fe950c8', +// infura: process.env.INFURA_KEY, // }); // init({ provider, network: 1 }); // const pods = await getAdminPods(userAddress); diff --git a/test/utils.test.ts b/test/utils.test.ts index 4fa029e..0fe2ca2 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -4,7 +4,7 @@ import { userAddress, constructGqlGetUsers, gqlGetUsers } from './fixtures'; import { encodeFunctionData, getPreviousModule } from '../src/lib/utils'; const provider = new ethers.providers.InfuraProvider('goerli', { - infura: '69ecf3b10bc24c6a972972666fe950c8', + infura: process.env.INFURA_KEY, }); test('encodeFunctionData should encode function data', () => {