@audius/sdk 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/.eslintrc +38 -0
  2. package/.prettierrc.js +1 -0
  3. package/.python-version +1 -0
  4. package/Dockerfile +15 -0
  5. package/README.md +3 -0
  6. package/babel.config.js +3 -0
  7. package/data-contracts/ABIs/AdminUpgradeabilityProxy.json +132 -0
  8. package/data-contracts/ABIs/BaseAdminUpgradeabilityProxy.json +113 -0
  9. package/data-contracts/ABIs/BaseUpgradeabilityProxy.json +22 -0
  10. package/data-contracts/ABIs/DiscoveryProviderFactory.json +189 -0
  11. package/data-contracts/ABIs/DiscoveryProviderFactoryInterface.json +61 -0
  12. package/data-contracts/ABIs/DiscoveryProviderStorage.json +205 -0
  13. package/data-contracts/ABIs/DiscoveryProviderStorageInterface.json +65 -0
  14. package/data-contracts/ABIs/ECDSA.json +4 -0
  15. package/data-contracts/ABIs/IPLDBlacklistFactory.json +168 -0
  16. package/data-contracts/ABIs/Initializable.json +4 -0
  17. package/data-contracts/ABIs/Migrations.json +67 -0
  18. package/data-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
  19. package/data-contracts/ABIs/Ownable.json +79 -0
  20. package/data-contracts/ABIs/PlaylistFactory.json +669 -0
  21. package/data-contracts/ABIs/PlaylistFactoryInterface.json +42 -0
  22. package/data-contracts/ABIs/PlaylistStorage.json +250 -0
  23. package/data-contracts/ABIs/PlaylistStorageInterface.json +129 -0
  24. package/data-contracts/ABIs/Proxy.json +10 -0
  25. package/data-contracts/ABIs/Registry.json +240 -0
  26. package/data-contracts/ABIs/RegistryContract.json +102 -0
  27. package/data-contracts/ABIs/RegistryContractInterface.json +28 -0
  28. package/data-contracts/ABIs/RegistryInterface.json +66 -0
  29. package/data-contracts/ABIs/SigningLogic.json +43 -0
  30. package/data-contracts/ABIs/SigningLogicInitializable.json +46 -0
  31. package/data-contracts/ABIs/SocialFeatureFactory.json +460 -0
  32. package/data-contracts/ABIs/SocialFeatureStorage.json +225 -0
  33. package/data-contracts/ABIs/SocialFeatureStorageInterface.json +123 -0
  34. package/data-contracts/ABIs/TestContract.json +135 -0
  35. package/data-contracts/ABIs/TestContractInterface.json +19 -0
  36. package/data-contracts/ABIs/TestContractWithStorage.json +165 -0
  37. package/data-contracts/ABIs/TestContractWithStorageInterface.json +24 -0
  38. package/data-contracts/ABIs/TestStorage.json +144 -0
  39. package/data-contracts/ABIs/TestStorageInterface.json +42 -0
  40. package/data-contracts/ABIs/TestUserReplicaSetManager.json +432 -0
  41. package/data-contracts/ABIs/TrackFactory.json +391 -0
  42. package/data-contracts/ABIs/TrackFactoryInterface.json +73 -0
  43. package/data-contracts/ABIs/TrackStorage.json +223 -0
  44. package/data-contracts/ABIs/TrackStorageInterface.json +121 -0
  45. package/data-contracts/ABIs/UpgradeabilityProxy.json +37 -0
  46. package/data-contracts/ABIs/UserFactory.json +657 -0
  47. package/data-contracts/ABIs/UserFactoryInterface.json +65 -0
  48. package/data-contracts/ABIs/UserLibraryFactory.json +334 -0
  49. package/data-contracts/ABIs/UserReplicaSetManager.json +418 -0
  50. package/data-contracts/ABIs/UserStorage.json +233 -0
  51. package/data-contracts/ABIs/UserStorageInterface.json +93 -0
  52. package/data-contracts/signatureSchemas.ts +1236 -0
  53. package/dist/core.d.ts +446 -0
  54. package/dist/core.js +769 -0
  55. package/dist/core.js.map +1 -0
  56. package/dist/index.d.ts +689 -0
  57. package/dist/index.js +72850 -0
  58. package/dist/index.js.map +1 -0
  59. package/eth-contracts/ABIs/Address.json +4 -0
  60. package/eth-contracts/ABIs/AudiusAdminUpgradeabilityProxy.json +105 -0
  61. package/eth-contracts/ABIs/AudiusClaimDistributor.json +4968 -0
  62. package/eth-contracts/ABIs/AudiusToken.json +724 -0
  63. package/eth-contracts/ABIs/BaseUpgradeabilityProxy.json +23 -0
  64. package/eth-contracts/ABIs/Checkpointing.json +4 -0
  65. package/eth-contracts/ABIs/ClaimsManager.json +539 -0
  66. package/eth-contracts/ABIs/Context.json +11 -0
  67. package/eth-contracts/ABIs/DelegateManager.json +989 -0
  68. package/eth-contracts/ABIs/DelegateManagerV2.json +1049 -0
  69. package/eth-contracts/ABIs/DelegateManagerV2Bad.json +1049 -0
  70. package/eth-contracts/ABIs/ERC20.json +252 -0
  71. package/eth-contracts/ABIs/ERC20Burnable.json +287 -0
  72. package/eth-contracts/ABIs/ERC20Detailed.json +270 -0
  73. package/eth-contracts/ABIs/ERC20Mintable.json +364 -0
  74. package/eth-contracts/ABIs/ERC20Pausable.json +397 -0
  75. package/eth-contracts/ABIs/EthRewardsManager.json +174 -0
  76. package/eth-contracts/ABIs/Governance.json +938 -0
  77. package/eth-contracts/ABIs/GovernanceUpgraded.json +953 -0
  78. package/eth-contracts/ABIs/GovernanceV2.json +938 -0
  79. package/eth-contracts/ABIs/IERC20.json +200 -0
  80. package/eth-contracts/ABIs/Initializable.json +4 -0
  81. package/eth-contracts/ABIs/InitializableV2.json +14 -0
  82. package/eth-contracts/ABIs/Migrations.json +71 -0
  83. package/eth-contracts/ABIs/MinterRole.json +91 -0
  84. package/eth-contracts/ABIs/MockAccount.json +62 -0
  85. package/eth-contracts/ABIs/MockDelegateManager.json +55 -0
  86. package/eth-contracts/ABIs/MockStakingCaller.json +259 -0
  87. package/eth-contracts/ABIs/MockWormhole.json +106 -0
  88. package/eth-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
  89. package/eth-contracts/ABIs/Ownable.json +93 -0
  90. package/eth-contracts/ABIs/Pausable.json +150 -0
  91. package/eth-contracts/ABIs/PauserRole.json +91 -0
  92. package/eth-contracts/ABIs/Proxy.json +10 -0
  93. package/eth-contracts/ABIs/Registry.json +288 -0
  94. package/eth-contracts/ABIs/Roles.json +4 -0
  95. package/eth-contracts/ABIs/SafeERC20.json +4 -0
  96. package/eth-contracts/ABIs/SafeMath.json +4 -0
  97. package/eth-contracts/ABIs/ServiceProviderFactory.json +1153 -0
  98. package/eth-contracts/ABIs/ServiceTypeManager.json +337 -0
  99. package/eth-contracts/ABIs/Staking.json +555 -0
  100. package/eth-contracts/ABIs/StakingUpgraded.json +570 -0
  101. package/eth-contracts/ABIs/TestContract.json +44 -0
  102. package/eth-contracts/ABIs/TrustedNotifierManager.json +265 -0
  103. package/eth-contracts/ABIs/Uint256Helpers.json +4 -0
  104. package/eth-contracts/ABIs/UpgradeabilityProxy.json +40 -0
  105. package/eth-contracts/ABIs/Wormhole.json +45 -0
  106. package/eth-contracts/ABIs/WormholeClient.json +155 -0
  107. package/examples/file.mp3 +0 -0
  108. package/examples/initAudiusLibs.js +86 -0
  109. package/examples/initializeVersions.js +95 -0
  110. package/examples/pic.jpg +0 -0
  111. package/initScripts/configureLocalDiscProv.js +167 -0
  112. package/initScripts/helpers/claim.js +43 -0
  113. package/initScripts/helpers/distributeTokens.js +24 -0
  114. package/initScripts/helpers/spRegistration.js +138 -0
  115. package/initScripts/helpers/utils.js +34 -0
  116. package/initScripts/helpers/version.js +93 -0
  117. package/initScripts/local.js +617 -0
  118. package/initScripts/mainnet.js +131 -0
  119. package/initScripts/manageProdRelayerWallets.js +191 -0
  120. package/package.json +125 -0
  121. package/rollup.config.js +164 -0
  122. package/scripts/AudiusClaimDistributor.json +4968 -0
  123. package/scripts/Wormhole.json +155 -0
  124. package/scripts/addCIDToIpldBlacklist.js +124 -0
  125. package/scripts/circleci-test.sh +53 -0
  126. package/scripts/communityRewards/transferCommunityRewardsToSolana.js +222 -0
  127. package/scripts/ipfs.sh +58 -0
  128. package/scripts/migrate_contracts.sh +25 -0
  129. package/scripts/reset.sh +65 -0
  130. package/scripts/test.sh +77 -0
  131. package/src/api/account.js +670 -0
  132. package/src/api/base.js +122 -0
  133. package/src/api/file.js +168 -0
  134. package/src/api/playlist.js +328 -0
  135. package/src/api/rewards.d.ts +4 -0
  136. package/src/api/rewards.js +682 -0
  137. package/src/api/serviceProvider.js +154 -0
  138. package/src/api/track.js +604 -0
  139. package/src/api/user.js +888 -0
  140. package/src/api/user.test.js +172 -0
  141. package/src/constants.ts +7 -0
  142. package/src/core.ts +3 -0
  143. package/src/index.js +6 -0
  144. package/src/libs.d.ts +3 -0
  145. package/src/libs.js +619 -0
  146. package/src/sanityChecks/addSecondaries.js +40 -0
  147. package/src/sanityChecks/assignReplicaSetIfNecessary.js +10 -0
  148. package/src/sanityChecks/index.d.ts +9 -0
  149. package/src/sanityChecks/index.js +31 -0
  150. package/src/sanityChecks/isCreator.js +73 -0
  151. package/src/sanityChecks/needsRecoveryEmail.js +20 -0
  152. package/src/sanityChecks/rolloverNodes.js +74 -0
  153. package/src/sanityChecks/sanitizeNodes.js +24 -0
  154. package/src/sanityChecks/syncNodes.js +28 -0
  155. package/src/sdk/constants.ts +10 -0
  156. package/src/sdk/index.ts +1 -0
  157. package/src/sdk/oauth/Oauth.ts +265 -0
  158. package/src/sdk/oauth/index.ts +1 -0
  159. package/src/sdk/sdk.ts +102 -0
  160. package/src/service-selection/ServiceSelection.test.ts +320 -0
  161. package/src/service-selection/ServiceSelection.ts +460 -0
  162. package/src/service-selection/constants.ts +14 -0
  163. package/src/service-selection/index.ts +1 -0
  164. package/src/services/ABIDecoder/AudiusABIDecoder.ts +71 -0
  165. package/src/services/ABIDecoder/index.ts +1 -0
  166. package/src/services/comstock/Comstock.ts +39 -0
  167. package/src/services/comstock/index.ts +1 -0
  168. package/src/services/contracts/ContractClient.ts +227 -0
  169. package/src/services/contracts/GovernedContractClient.ts +53 -0
  170. package/src/services/contracts/ProviderSelection.ts +42 -0
  171. package/src/services/creatorNode/CreatorNode.ts +1065 -0
  172. package/src/services/creatorNode/CreatorNodeSelection.test.ts +997 -0
  173. package/src/services/creatorNode/CreatorNodeSelection.ts +488 -0
  174. package/src/services/creatorNode/constants.ts +10 -0
  175. package/src/services/creatorNode/index.ts +2 -0
  176. package/src/services/dataContracts/AudiusContracts.ts +234 -0
  177. package/src/services/dataContracts/IPLDBlacklistFactoryClient.ts +73 -0
  178. package/src/services/dataContracts/PlaylistFactoryClient.ts +370 -0
  179. package/src/services/dataContracts/RegistryClient.ts +95 -0
  180. package/src/services/dataContracts/SocialFeatureFactoryClient.ts +196 -0
  181. package/src/services/dataContracts/TrackFactoryClient.ts +131 -0
  182. package/src/services/dataContracts/UserFactoryClient.ts +351 -0
  183. package/src/services/dataContracts/UserLibraryFactoryClient.ts +115 -0
  184. package/src/services/dataContracts/UserReplicaSetManagerClient.ts +206 -0
  185. package/src/services/dataContracts/index.ts +1 -0
  186. package/src/services/discoveryProvider/DiscoveryProvider.ts +1168 -0
  187. package/src/services/discoveryProvider/DiscoveryProviderSelection.test.ts +536 -0
  188. package/src/services/discoveryProvider/DiscoveryProviderSelection.ts +383 -0
  189. package/src/services/discoveryProvider/constants.ts +13 -0
  190. package/src/services/discoveryProvider/index.ts +1 -0
  191. package/src/services/discoveryProvider/requests.ts +629 -0
  192. package/src/services/ethContracts/AudiusTokenClient.ts +163 -0
  193. package/src/services/ethContracts/ClaimDistributionClient.ts +45 -0
  194. package/src/services/ethContracts/ClaimsManagerClient.ts +102 -0
  195. package/src/services/ethContracts/DelegateManagerClient.ts +480 -0
  196. package/src/services/ethContracts/EthContracts.ts +359 -0
  197. package/src/services/ethContracts/EthRewardsManagerClient.ts +33 -0
  198. package/src/services/ethContracts/GovernanceClient.ts +451 -0
  199. package/src/services/ethContracts/RegistryClient.ts +33 -0
  200. package/src/services/ethContracts/ServiceProviderFactoryClient.ts +691 -0
  201. package/src/services/ethContracts/ServiceTypeManagerClient.ts +112 -0
  202. package/src/services/ethContracts/StakingProxyClient.ts +97 -0
  203. package/src/services/ethContracts/TrustedNotifierManagerClient.ts +101 -0
  204. package/src/services/ethContracts/WormholeClient.ts +97 -0
  205. package/src/services/ethContracts/index.ts +1 -0
  206. package/src/services/ethWeb3Manager/EthWeb3Manager.ts +239 -0
  207. package/src/services/ethWeb3Manager/index.ts +1 -0
  208. package/src/services/hedgehog/Hedgehog.ts +96 -0
  209. package/src/services/hedgehog/index.ts +1 -0
  210. package/src/services/identity/IdentityService.ts +551 -0
  211. package/src/services/identity/index.ts +1 -0
  212. package/src/services/identity/requests.ts +65 -0
  213. package/src/services/schemaValidator/SchemaValidator.ts +105 -0
  214. package/src/services/schemaValidator/index.ts +1 -0
  215. package/src/services/schemaValidator/schemas/trackSchema.json +267 -0
  216. package/src/services/schemaValidator/schemas/userSchema.json +230 -0
  217. package/src/services/solanaAudiusData/errors.ts +20 -0
  218. package/src/services/solanaAudiusData/index.ts +1189 -0
  219. package/src/services/solanaWeb3Manager/errors.js +101 -0
  220. package/src/services/solanaWeb3Manager/index.d.ts +46 -0
  221. package/src/services/solanaWeb3Manager/index.js +655 -0
  222. package/src/services/solanaWeb3Manager/padBNToUint8Array.ts +7 -0
  223. package/src/services/solanaWeb3Manager/rewards.js +941 -0
  224. package/src/services/solanaWeb3Manager/rewardsAttester.ts +1093 -0
  225. package/src/services/solanaWeb3Manager/tokenAccount.js +149 -0
  226. package/src/services/solanaWeb3Manager/transactionHandler.js +345 -0
  227. package/src/services/solanaWeb3Manager/transfer.js +272 -0
  228. package/src/services/solanaWeb3Manager/userBank.js +160 -0
  229. package/src/services/solanaWeb3Manager/utils.d.ts +31 -0
  230. package/src/services/solanaWeb3Manager/utils.js +163 -0
  231. package/src/services/solanaWeb3Manager/wAudio.js +28 -0
  232. package/src/services/solanaWeb3Manager/wAudio.test.js +30 -0
  233. package/src/services/web3Manager/Web3Config.ts +14 -0
  234. package/src/services/web3Manager/Web3Manager.ts +360 -0
  235. package/src/services/web3Manager/XMLHttpRequest.ts +11 -0
  236. package/src/services/web3Manager/index.ts +2 -0
  237. package/src/services/wormhole/index.js +424 -0
  238. package/src/types.ts +8 -0
  239. package/src/userStateManager.ts +53 -0
  240. package/src/utils/apiSigning.ts +51 -0
  241. package/src/utils/captcha.ts +97 -0
  242. package/src/utils/estimateGas.ts +64 -0
  243. package/src/utils/fileHasher.ts +278 -0
  244. package/src/utils/importContractABI.d.ts +9 -0
  245. package/src/utils/importContractABI.js +19 -0
  246. package/src/utils/index.ts +11 -0
  247. package/src/utils/multiProvider.ts +72 -0
  248. package/src/utils/network.test.ts +127 -0
  249. package/src/utils/network.ts +308 -0
  250. package/src/utils/promiseFight.test.ts +87 -0
  251. package/src/utils/promiseFight.ts +36 -0
  252. package/src/utils/signatures.ts +139 -0
  253. package/src/utils/types.ts +34 -0
  254. package/src/utils/utils.test.ts +36 -0
  255. package/src/utils/utils.ts +235 -0
  256. package/src/utils/uuid.ts +14 -0
  257. package/src/web3.d.ts +9 -0
  258. package/src/web3.js +8 -0
  259. package/tests/assets/static_image.png +0 -0
  260. package/tests/assets/static_text.txt +1 -0
  261. package/tests/audiusTokenClientTest.js +37 -0
  262. package/tests/creatorNodeTest.js +19 -0
  263. package/tests/fileHasherTest.js +125 -0
  264. package/tests/governanceTest.js +382 -0
  265. package/tests/helpers.js +105 -0
  266. package/tests/index.js +14 -0
  267. package/tests/playlistClientTest.js +157 -0
  268. package/tests/providerSelectionTest.js +241 -0
  269. package/tests/registryClientTest.js +19 -0
  270. package/tests/rewardsAttesterTest.js +373 -0
  271. package/tests/serviceTypeManagerClientTest.js +33 -0
  272. package/tests/socialFeatureClientTest.js +79 -0
  273. package/tests/stakingTest.js +302 -0
  274. package/tests/trackClientTest.js +86 -0
  275. package/tests/userClientTest.js +121 -0
  276. package/tsconfig.json +10 -0
  277. package/types/@audius-hedgehog/index.d.ts +39 -0
  278. package/types/abi-decoder/index.d.ts +41 -0
@@ -0,0 +1,451 @@
1
+ import { ContractClient, GetRegistryAddress } from '../contracts/ContractClient'
2
+ import { ContractABI, ContractMethod, Logger, Utils } from '../../utils'
3
+ import type { EthWeb3Manager } from '../ethWeb3Manager'
4
+ import type { AudiusTokenClient } from './AudiusTokenClient'
5
+ import type { StakingProxyClient } from './StakingProxyClient'
6
+ import type { EventLog } from 'web3-core'
7
+
8
+ type ProposalTxn = {
9
+ proposalId: string
10
+ proposer: string
11
+ submissionBlockNumber: string
12
+ targetContractRegistryKey: string
13
+ targetContractAddress: string
14
+ callValue: string
15
+ functionSignature: string
16
+ callData: string
17
+ outcome: string
18
+ numVotes: string
19
+ voteMagnitudeYes: string
20
+ voteMagnitudeNo: string
21
+ }
22
+
23
+ /**
24
+ * Transform a method name and its argument types into a string-composed
25
+ * signature, e.g. someMethod(bytes32, int32)
26
+ * @param methodName
27
+ * @param argumentTypes
28
+ */
29
+ const createMethodSignature = (methodName: string, argumentTypes: string[]) => {
30
+ return `${methodName}(${argumentTypes.join(',')})`
31
+ }
32
+
33
+ /**
34
+ * Represent an instance of a proposal vote.
35
+ */
36
+ export const Vote = Object.freeze({
37
+ no: 1,
38
+ yes: 2
39
+ })
40
+
41
+ export class GovernanceClient extends ContractClient {
42
+ audiusTokenClient: AudiusTokenClient
43
+ stakingProxyClient: StakingProxyClient
44
+ isDebug: boolean
45
+
46
+ constructor(
47
+ ethWeb3Manager: EthWeb3Manager,
48
+ contractABI: ContractABI['abi'],
49
+ contractRegistryKey: string,
50
+ getRegistryAddress: GetRegistryAddress,
51
+ audiusTokenClient: AudiusTokenClient,
52
+ stakingProxyClient: StakingProxyClient,
53
+ logger: Logger = console,
54
+ isDebug = false
55
+ ) {
56
+ super(
57
+ ethWeb3Manager,
58
+ contractABI,
59
+ contractRegistryKey,
60
+ getRegistryAddress,
61
+ logger
62
+ )
63
+ this.audiusTokenClient = audiusTokenClient
64
+ this.stakingProxyClient = stakingProxyClient
65
+ this.isDebug = isDebug
66
+ this.formatVote = this.formatVote.bind(this)
67
+ this.formatProposalEvent = this.formatProposalEvent.bind(this)
68
+ this.abiEncode = this.abiEncode.bind(this)
69
+ }
70
+
71
+ /**
72
+ * Gets the function signature and call data for a contract method.
73
+ * The signature and call data are passed to other contracts (like governance)
74
+ * as arguments.
75
+ * @param methodName
76
+ * @param contractMethod
77
+ */
78
+ getSignatureAndCallData(methodName: string, contractMethod: ContractMethod) {
79
+ const argumentTypes = contractMethod._method.inputs.map((i) => i.type)
80
+ const argumentValues = contractMethod.arguments
81
+
82
+ const signature = createMethodSignature(methodName, argumentTypes)
83
+ const callData = this.abiEncode(argumentTypes, argumentValues)
84
+
85
+ return { signature, callData }
86
+ }
87
+
88
+ async guardianExecuteTransaction(
89
+ contractRegistryKey: string,
90
+ functionSignature: string,
91
+ callData: string
92
+ ): Promise<ContractMethod> {
93
+ // 0 eth valued transaction. We don't anticipate needed to attach
94
+ // value to this txn, so default to 0.
95
+ const callValue0 = this.toBN('0')
96
+
97
+ const method = await this.getMethod(
98
+ 'guardianExecuteTransaction',
99
+ contractRegistryKey,
100
+ callValue0,
101
+ functionSignature,
102
+ callData
103
+ )
104
+ return method
105
+ }
106
+
107
+ async getVotingPeriod() {
108
+ const method = await this.getMethod('getVotingPeriod')
109
+ const period = await method.call()
110
+ return parseInt(period)
111
+ }
112
+
113
+ async setVotingPeriod(period: string) {
114
+ const methodName = 'setVotingPeriod'
115
+ const contractMethod = await this.getMethod(methodName, period)
116
+ const { signature, callData } = this.getSignatureAndCallData(
117
+ methodName,
118
+ contractMethod
119
+ )
120
+ const contractRegistryKey = this.web3Manager
121
+ .getWeb3()
122
+ .utils.utf8ToHex(this.contractRegistryKey)
123
+ const method = await this.guardianExecuteTransaction(
124
+ contractRegistryKey,
125
+ signature,
126
+ callData
127
+ )
128
+ return await this.web3Manager.sendTransaction(method)
129
+ }
130
+
131
+ async getVotingQuorumPercent() {
132
+ const method = await this.getMethod('getVotingQuorumPercent')
133
+ const percent = await method.call()
134
+ return parseInt(percent)
135
+ }
136
+
137
+ async getExecutionDelay() {
138
+ const method = await this.getMethod('getExecutionDelay')
139
+ const delay = await method.call()
140
+ return parseInt(delay)
141
+ }
142
+
143
+ async setExecutionDelay(delay: number) {
144
+ const methodName = 'setExecutionDelay'
145
+ const contractMethod = await this.getMethod(methodName, delay)
146
+ const { signature, callData } = this.getSignatureAndCallData(
147
+ methodName,
148
+ contractMethod
149
+ )
150
+ const contractRegistryKey = this.web3Manager
151
+ .getWeb3()
152
+ .utils.utf8ToHex(this.contractRegistryKey)
153
+ const method = await this.guardianExecuteTransaction(
154
+ contractRegistryKey,
155
+ signature,
156
+ callData
157
+ )
158
+ return await this.web3Manager.sendTransaction(method)
159
+ }
160
+
161
+ async getProposalById(id: number) {
162
+ const method = await this.getMethod('getProposalById', id)
163
+ const proposal = await method.call()
164
+ const formattedProposal = this.formatProposal(proposal)
165
+ return formattedProposal
166
+ }
167
+
168
+ async getProposalTargetContractHash(id: string) {
169
+ const method = await this.getMethod('getProposalTargetContractHash', id)
170
+ return method.call()
171
+ }
172
+
173
+ async getProposals(queryStartBlock = 0) {
174
+ const contract = await this.getContract()
175
+ const events = await contract.getPastEvents('ProposalSubmitted', {
176
+ fromBlock: queryStartBlock
177
+ })
178
+ return events?.map(this.formatProposalEvent)
179
+ }
180
+
181
+ async getProposalsForAddresses(addresses: string[], queryStartBlock = 0) {
182
+ const contract = await this.getContract()
183
+ const events = await contract.getPastEvents('ProposalSubmitted', {
184
+ fromBlock: queryStartBlock,
185
+ filter: {
186
+ _proposer: addresses
187
+ }
188
+ })
189
+ return events.map(this.formatProposalEvent)
190
+ }
191
+
192
+ async getProposalSubmission(proposalId: number, queryStartBlock = 0) {
193
+ const contract = await this.getContract()
194
+ const events = await contract.getPastEvents('ProposalSubmitted', {
195
+ fromBlock: queryStartBlock,
196
+ filter: {
197
+ _proposalId: proposalId
198
+ }
199
+ })
200
+ return this.formatProposalEvent(events[0] as EventLog)
201
+ }
202
+
203
+ async getInProgressProposals() {
204
+ const method = await this.getMethod('getInProgressProposals')
205
+ const ids = await method.call()
206
+ return ids
207
+ }
208
+
209
+ async submitProposal({
210
+ targetContractRegistryKey,
211
+ callValue,
212
+ functionSignature,
213
+ callData, // array of args, e.g. [slashAmount, targetAddress]
214
+ name,
215
+ description
216
+ }: {
217
+ targetContractRegistryKey: string
218
+ callValue: string
219
+ functionSignature: string
220
+ callData: string[] // array of args, e.g. [slashAmount, targetAddress]
221
+ name: string
222
+ description: string
223
+ }) {
224
+ const argumentTypes = functionSignature
225
+ .match(/.*\((?<args>.*)\)/)
226
+ ?.groups?.['args']?.split(',')
227
+ const encodedCallData = this.abiEncode(argumentTypes as string[], callData)
228
+
229
+ const method = await this.getMethod(
230
+ 'submitProposal',
231
+ targetContractRegistryKey,
232
+ callValue,
233
+ functionSignature,
234
+ encodedCallData,
235
+ name,
236
+ description
237
+ )
238
+ const tx = await this.web3Manager.sendTransaction(method)
239
+ const id = tx.events?.['ProposalSubmitted']?.returnValues?._proposalId
240
+ if (id) {
241
+ return id
242
+ }
243
+ throw new Error('submitProposal: txn malformed')
244
+ }
245
+
246
+ async submitVote({ proposalId, vote }: { proposalId: number; vote: string }) {
247
+ const method = await this.getMethod('submitVote', proposalId, vote)
248
+ await this.web3Manager.sendTransaction(method)
249
+ }
250
+
251
+ async updateVote({ proposalId, vote }: { proposalId: number; vote: string }) {
252
+ const method = await this.getMethod('updateVote', proposalId, vote)
253
+ await this.web3Manager.sendTransaction(method)
254
+ }
255
+
256
+ async evaluateProposalOutcome(proposalId: number) {
257
+ const method = await this.getMethod('evaluateProposalOutcome', proposalId)
258
+ const outcome = await this.web3Manager.sendTransaction(method)
259
+ return outcome
260
+ }
261
+
262
+ async getProposalEvaluation(proposalId: number, queryStartBlock = 0) {
263
+ const contract = await this.getContract()
264
+ const events = await contract.getPastEvents('ProposalOutcomeEvaluated', {
265
+ fromBlock: queryStartBlock,
266
+ filter: {
267
+ _proposalId: proposalId
268
+ }
269
+ })
270
+ return events
271
+ }
272
+
273
+ async getVotes({
274
+ proposalId,
275
+ queryStartBlock = 0
276
+ }: {
277
+ proposalId: number
278
+ queryStartBlock: number
279
+ }) {
280
+ const contract = await this.getContract()
281
+ const events = await contract.getPastEvents('ProposalVoteSubmitted', {
282
+ fromBlock: queryStartBlock,
283
+ filter: {
284
+ _proposalId: proposalId
285
+ }
286
+ })
287
+ return events.map(this.formatVote)
288
+ }
289
+
290
+ async getVoteUpdates({
291
+ proposalId,
292
+ queryStartBlock = 0
293
+ }: {
294
+ proposalId: number
295
+ queryStartBlock: number
296
+ }) {
297
+ const contract = await this.getContract()
298
+ const events = await contract.getPastEvents('ProposalVoteUpdated', {
299
+ fromBlock: queryStartBlock,
300
+ filter: {
301
+ _proposalId: proposalId
302
+ }
303
+ })
304
+ return events.map(this.formatVote)
305
+ }
306
+
307
+ async getVoteSubmissionsByAddress({
308
+ addresses,
309
+ queryStartBlock = 0
310
+ }: {
311
+ addresses: string[]
312
+ queryStartBlock: number
313
+ }) {
314
+ const contract = await this.getContract()
315
+ const events = await contract.getPastEvents('ProposalVoteSubmitted', {
316
+ fromBlock: queryStartBlock,
317
+ filter: {
318
+ _voter: addresses
319
+ }
320
+ })
321
+ return events.map(this.formatVote)
322
+ }
323
+
324
+ async getVoteUpdatesByAddress({
325
+ addresses,
326
+ queryStartBlock = 0
327
+ }: {
328
+ addresses: string[]
329
+ queryStartBlock: number
330
+ }) {
331
+ const contract = await this.getContract()
332
+ const events = await contract.getPastEvents('ProposalVoteUpdated', {
333
+ fromBlock: queryStartBlock,
334
+ filter: {
335
+ _voter: addresses
336
+ }
337
+ })
338
+ return events.map(this.formatVote)
339
+ }
340
+
341
+ async getVoteByProposalAndVoter({
342
+ proposalId,
343
+ voterAddress
344
+ }: {
345
+ proposalId: number[]
346
+ voterAddress: number
347
+ }) {
348
+ const method = await this.getMethod(
349
+ 'getVoteInfoByProposalAndVoter',
350
+ proposalId,
351
+ voterAddress
352
+ )
353
+ const result = await method.call()
354
+ return parseInt(result.vote)
355
+ }
356
+
357
+ // Helpers
358
+
359
+ /**
360
+ * ABI encodes argument types and values together into one encoded string
361
+ */
362
+ abiEncode(types: string[], values: string[]) {
363
+ return this.web3Manager.getWeb3().eth.abi.encodeParameters(types, values)
364
+ }
365
+
366
+ toBN(val: string) {
367
+ return this.web3Manager.getWeb3().utils.toBN(val)
368
+ }
369
+
370
+ /**
371
+ * Prune off extraneous fields from proposal returned by txn
372
+ */
373
+ formatProposal(proposal: ProposalTxn) {
374
+ return {
375
+ proposalId: parseInt(proposal.proposalId),
376
+ proposer: proposal.proposer,
377
+ submissionBlockNumber: parseInt(proposal.submissionBlockNumber),
378
+ targetContractRegistryKey: proposal.targetContractRegistryKey,
379
+ targetContractAddress: proposal.targetContractAddress,
380
+ callValue: parseInt(proposal.callValue),
381
+ functionSignature: proposal.functionSignature,
382
+ callData: proposal.callData,
383
+ outcome: parseInt(proposal.outcome),
384
+ numVotes: parseInt(proposal.numVotes),
385
+ voteMagnitudeYes: this.toBN(proposal.voteMagnitudeYes),
386
+ voteMagnitudeNo: this.toBN(proposal.voteMagnitudeNo)
387
+ }
388
+ }
389
+
390
+ /**
391
+ * Formats a proposal event
392
+ */
393
+ formatProposalEvent(proposalEvent: EventLog) {
394
+ const event = proposalEvent.returnValues
395
+ return {
396
+ proposalId: parseInt(event._proposalId),
397
+ proposer: event._proposer,
398
+ description: event._description,
399
+ name: event._name,
400
+ blockNumber: proposalEvent.blockNumber
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Prune off extraneous fields from vote event
406
+ */
407
+ formatVote(voteEvent: EventLog) {
408
+ const event = voteEvent.returnValues
409
+ return {
410
+ proposalId: parseInt(event._proposalId),
411
+ voter: event._voter,
412
+ vote: parseInt(event._vote),
413
+ voterStake: this.toBN(event._voterStake),
414
+ blockNumber: voteEvent.blockNumber
415
+ }
416
+ }
417
+
418
+ /**
419
+ *
420
+ * @param {Number} proposalId id of the governance proposal
421
+ * @returns {BN} amount of tokens in wei required to reach quorum
422
+ */
423
+ async calculateQuorum(proposalId: number) {
424
+ const { submissionBlockNumber } = await this.getProposalById(proposalId)
425
+
426
+ // represented as a value > 0, eg 5% is 5
427
+ const quoroumPercent = await this.getVotingQuorumPercent()
428
+
429
+ // retrieve stake at the time of proposal from Staking client
430
+ const totalStakeAtProposal = await this.stakingProxyClient.totalStakedAt(
431
+ submissionBlockNumber
432
+ )
433
+
434
+ // quorum = (total staked at proposal * quorum percent) / 100
435
+ // the divmod function returns an object with both the quotient (div) and the remainder (mod)
436
+ // { div, mod }
437
+ const quorumStakeDivMod = totalStakeAtProposal
438
+ .mul(Utils.toBN(quoroumPercent))
439
+ // @ts-expect-error divmod not in types for some reason
440
+ .divmod(Utils.toBN(100))
441
+
442
+ let quorumStake = quorumStakeDivMod.div
443
+
444
+ // if there's a non-zero remainder, round up
445
+ if (!quorumStakeDivMod.mod.isZero()) {
446
+ quorumStake = quorumStakeDivMod.div.add(Utils.toBN(1))
447
+ }
448
+
449
+ return quorumStake
450
+ }
451
+ }
@@ -0,0 +1,33 @@
1
+ import { Utils } from '../../utils'
2
+ import type { AbiItem } from 'web3-utils'
3
+ import type Web3 from 'web3'
4
+ import type { Contract } from 'web3-eth-contract'
5
+ import type { EthWeb3Manager } from '../ethWeb3Manager'
6
+
7
+ export class RegistryClient {
8
+ web3Manager: EthWeb3Manager
9
+ contractABI: AbiItem[]
10
+ contractAddress: string
11
+ web3: Web3
12
+ Registry: Contract
13
+
14
+ constructor(
15
+ web3Manager: EthWeb3Manager,
16
+ contractABI: AbiItem[],
17
+ contractAddress: string
18
+ ) {
19
+ this.web3Manager = web3Manager
20
+ this.contractABI = contractABI
21
+ this.contractAddress = contractAddress
22
+
23
+ this.web3 = this.web3Manager.getWeb3()
24
+ this.Registry = new this.web3.eth.Contract(contractABI, contractAddress)
25
+ }
26
+
27
+ async getContract(contractRegistryKey: string): Promise<string> {
28
+ Utils.checkStrLen(contractRegistryKey, 32)
29
+ return this.Registry.methods
30
+ .getContract(Utils.utf8ToHex(contractRegistryKey))
31
+ .call()
32
+ }
33
+ }