@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,278 @@
1
+ import {
2
+ ImportCandidate,
3
+ importer,
4
+ UserImporterOptions
5
+ } from 'ipfs-unixfs-importer'
6
+ import fs from 'fs'
7
+ import { hrtime } from 'process'
8
+ import { promisify } from 'util'
9
+ import { Stream } from 'stream'
10
+ import type { Blockstore, Options } from 'interface-blockstore'
11
+ import type {
12
+ AwaitIterable,
13
+ Pair,
14
+ Batch,
15
+ Query,
16
+ KeyQuery
17
+ } from 'interface-store'
18
+ import type { CID } from 'multiformats/cid'
19
+
20
+ // Base functionality for only hash logic taken from https://github.com/alanshaw/ipfs-only-hash/blob/master/index.js
21
+
22
+ export type Content = ReadableStream | Buffer | string
23
+ export interface ImageHasher {
24
+ options: UserImporterOptions
25
+ content: ImportCandidate
26
+ }
27
+ export interface NonImageHasher {
28
+ options: UserImporterOptions
29
+ content: Uint8Array
30
+ }
31
+ export interface HashedImage {
32
+ path: string | undefined
33
+ cid: string
34
+ size: number
35
+ }
36
+
37
+ const block: Blockstore = {
38
+ get: async (key: CID, _options?: Options) => {
39
+ throw new Error(`unexpected block API get for ${key}`)
40
+ },
41
+ put: async (_key: CID, _val: Uint8Array, _options?: Options) => {
42
+ throw new Error('unexpected block API put')
43
+ },
44
+ open: async function (): Promise<void> {
45
+ throw new Error('Function not implemented.')
46
+ },
47
+ close: async function (): Promise<void> {
48
+ throw new Error('Function not implemented.')
49
+ },
50
+ has: async function (_key: CID, _options?: Options): Promise<boolean> {
51
+ throw new Error('Function not implemented.')
52
+ },
53
+ delete: async function (_key: CID, _options?: Options): Promise<void> {
54
+ throw new Error('Function not implemented.')
55
+ },
56
+ putMany: function (
57
+ _source: AwaitIterable<Pair<CID, Uint8Array>>,
58
+ _options?: Options
59
+ ): AsyncIterable<Pair<CID, Uint8Array>> {
60
+ throw new Error('Function not implemented.')
61
+ },
62
+ getMany: function (
63
+ _source: AwaitIterable<CID>,
64
+ _options?: Options
65
+ ): AsyncIterable<Uint8Array> {
66
+ throw new Error('Function not implemented.')
67
+ },
68
+ deleteMany: function (
69
+ _source: AwaitIterable<CID>,
70
+ _options?: Options
71
+ ): AsyncIterable<CID> {
72
+ throw new Error('Function not implemented.')
73
+ },
74
+ batch: function (): Batch<CID, Uint8Array> {
75
+ throw new Error('Function not implemented.')
76
+ },
77
+ query: function (
78
+ _query: Query<CID, Uint8Array>,
79
+ _options?: Options
80
+ ): AsyncIterable<Pair<CID, Uint8Array>> {
81
+ throw new Error('Function not implemented.')
82
+ },
83
+ queryKeys: function (
84
+ _query: KeyQuery<CID>,
85
+ _options?: Options
86
+ ): AsyncIterable<CID> {
87
+ throw new Error('Function not implemented.')
88
+ }
89
+ }
90
+
91
+ export const fileHasher = {
92
+ convertNanosToMillis(nanoSeconds: bigint) {
93
+ return nanoSeconds / BigInt(1000000)
94
+ },
95
+
96
+ /**
97
+ * Used to initalize the only hash fns. See Alan Shaw's reference code for more context.
98
+ */
99
+ initImageHasher(
100
+ content: ImportCandidate,
101
+ options: UserImporterOptions
102
+ ): ImageHasher {
103
+ options = options || {}
104
+ options.onlyHash = true
105
+ options.cidVersion = 0
106
+
107
+ return { options, content }
108
+ },
109
+
110
+ /**
111
+ * Used to iniitalize the only hash fns. See Alan Shaw's reference code for more context.
112
+ */
113
+ initNonImageHasher(
114
+ content: Uint8Array,
115
+ options: UserImporterOptions
116
+ ): NonImageHasher {
117
+ options = options || {}
118
+ options.onlyHash = true
119
+ options.cidVersion = 0
120
+
121
+ return { options, content }
122
+ },
123
+
124
+ /**
125
+ * Convert content to a buffer; used in `generateNonImageCid()`.
126
+ * @param {ReadStream|Buffer|string} content if string, should be file path
127
+ * @param {Object} logger
128
+ * @returns buffer version of content
129
+ */
130
+ async convertToBuffer(content: Content, logger: any): Promise<Buffer> {
131
+ if (Buffer.isBuffer(content)) return content
132
+
133
+ let buffer: any
134
+ try {
135
+ if (content instanceof Stream.Readable) {
136
+ await new Promise((resolve, reject) => {
137
+ content.on('data', (chunk: any) => buffer.push(chunk))
138
+ content.on('end', () => resolve(Buffer.concat(buffer)))
139
+ content.on('error', (err: any) => reject(err))
140
+ })
141
+ } else {
142
+ const fsReadFile = promisify(fs.readFile)
143
+ buffer = await fsReadFile(content as string)
144
+ }
145
+ } catch (e: any) {
146
+ const errMsg = `[fileHasher - convertToBuffer()] Could not convert content into buffer: ${e.toString()}`
147
+ logger.error(errMsg)
148
+ throw new Error(errMsg)
149
+ }
150
+
151
+ return buffer
152
+ },
153
+
154
+ /**
155
+ * Custom fn to generate the content-hashing logic
156
+ * @param content a buffer of the content
157
+ * @param options options for importer
158
+ * @returns the CID from content addressing logic
159
+ */
160
+ async hashNonImages(
161
+ content: Uint8Array,
162
+ options: UserImporterOptions = {}
163
+ ): Promise<string> {
164
+ ;({ options, content } = fileHasher.initNonImageHasher(content, options))
165
+
166
+ let lastCid: string = ''
167
+ for await (const { cid } of importer([{ content }], block, options)) {
168
+ lastCid = `${cid}`
169
+ }
170
+
171
+ return lastCid
172
+ },
173
+
174
+ /**
175
+ * Custom fn to generate the content-hashing logic
176
+ * @param content an Object[] with the structure [{ path: string, content: buffer }, ...]
177
+ * @param options options for importer
178
+ * @returns an Object[] with the structure [{path: <string>, cid: <string>, size: <number>}]
179
+ *
180
+ * Example with adding a profile picture:
181
+ * [
182
+ {
183
+ "cid": "QmSRyKvnXwoxPZ9UxqxXPR8NXjcPYBEf1qbNrXyo5USqLL",
184
+ "path": "blob/150x150.jpg",
185
+ "size": 3091
186
+ },
187
+ {
188
+ "cid": "QmQQMV9TXxRmDKafZiRvMVkqUNtUu9WGAfukUBS1yCk2ht",
189
+ "path": "blob/480x480.jpg",
190
+ "size": 20743
191
+ },
192
+ {
193
+ "cid": "Qmd8cDdDGcWVaLEoJPVFtkKhYMqvHXZTvXcisYjubFxv1F",
194
+ "path": "blob/1000x1000.jpg",
195
+ "size": 72621
196
+ },
197
+ {
198
+ "cid": "QmaYCPUH8G14yxetsMgW5J5tpTqPaTp3HMd3EAyffZKSvm",
199
+ "path": "blob/original.jpg",
200
+ "size": 185844
201
+ },
202
+ {
203
+ "cid": "QmW8FUFhvaxv1MZmVcUcmR7Tg9WZhGf8xDNBesT9XepwrK",
204
+ "path": "blob",
205
+ "size": 282525
206
+ }
207
+ ]
208
+ */
209
+ async hashImages(
210
+ content: ImportCandidate,
211
+ options: UserImporterOptions = {}
212
+ ): Promise<HashedImage[]> {
213
+ ;({ options, content } = fileHasher.initImageHasher(content, options))
214
+
215
+ const result: HashedImage[] = []
216
+ for await (const file of importer(content, block, options)) {
217
+ result.push({
218
+ path: file.path,
219
+ cid: `${file.cid}`,
220
+ size: file.size
221
+ })
222
+ }
223
+
224
+ // Note: According to https://github.com/ipfs/js-ipfs-unixfs/tree/master/packages/ipfs-unixfs-importer#example,
225
+ // the importer will return the root as the last file resp. This means that the dir should always be the last index.
226
+ // (As we need it to be in resizeImage.js)
227
+ return result
228
+ },
229
+
230
+ /**
231
+ * Generates CID for a non-image file (track segment, track transcode, metadata)
232
+ * @param {Buffer|ReadStream|string} content a single Buffer, a ReadStream, or path to an existing file
233
+ * @param {Object?} logger
234
+ * @returns {string} only hash response cid
235
+ */
236
+ async generateNonImageCid(
237
+ content: Content,
238
+ logger: any = console
239
+ ): Promise<string> {
240
+ const buffer = await fileHasher.convertToBuffer(content, logger)
241
+
242
+ const startHashing: bigint = hrtime.bigint()
243
+ const cid = await fileHasher.hashNonImages(buffer)
244
+
245
+ const hashDurationMs = fileHasher.convertNanosToMillis(
246
+ hrtime.bigint() - startHashing
247
+ )
248
+
249
+ logger.info(
250
+ `[fileHasher - generateNonImageCid()] CID=${cid} hashDurationMs=${hashDurationMs}ms`
251
+ )
252
+
253
+ return cid
254
+ },
255
+
256
+ /**
257
+ * Wrapper that generates multihashes for image files
258
+ * @param {Object[]} content an Object[] with the structure [{ path: string, content: buffer }, ...]
259
+ * @param {Object?} logger
260
+ * @returns {HashedImage[]} only hash responses with the structure [{path: <string>, cid: <string>, size: <number>}]
261
+ */
262
+ async generateImageCids(
263
+ content: ImportCandidate,
264
+ logger: any = console
265
+ ): Promise<HashedImage[]> {
266
+ const startHashing: bigint = hrtime.bigint()
267
+ const hashedImages: HashedImage[] = await fileHasher.hashImages(content)
268
+ const hashDurationMs = fileHasher.convertNanosToMillis(
269
+ hrtime.bigint() - startHashing
270
+ )
271
+
272
+ const hashedImagesStr = JSON.stringify(hashedImages)
273
+ logger.info(
274
+ `[fileHasher - generateImageCids()] hashedImages=${hashedImagesStr} hashImagesDurationMs=${hashDurationMs}ms`
275
+ )
276
+ return hashedImages
277
+ }
278
+ }
@@ -0,0 +1,9 @@
1
+ import type { AbiItem } from 'web3-utils'
2
+
3
+ export type ContractABI = {
4
+ abi: AbiItem[]
5
+ contractName: string
6
+ }
7
+
8
+ export const importDataContractABIs: (pathStr: string) => ContractABI
9
+ export const importEthContractABIs: (pathStr: string) => ContractABI
@@ -0,0 +1,19 @@
1
+ const importDataContractABIs = (pathStr) => {
2
+ // need to specify part of path here because of https://github.com/webpack/webpack/issues/4921#issuecomment-357147299
3
+ const importFile = require(`../../data-contracts/ABIs/${pathStr}`)
4
+
5
+ if (importFile) return importFile
6
+ else throw new Error(`Data contract ABI not found ${pathStr}`)
7
+ }
8
+
9
+ const importEthContractABIs = (pathStr) => {
10
+ // need to specify part of path here because of https://github.com/webpack/webpack/issues/4921#issuecomment-357147299
11
+ const importFile = require(`../../eth-contracts/ABIs/${pathStr}`)
12
+
13
+ if (importFile) return importFile
14
+ else throw new Error(`Eth contract ABI not found ${pathStr}`)
15
+ }
16
+
17
+ module.exports = {
18
+ importDataContractABIs, importEthContractABIs
19
+ }
@@ -0,0 +1,11 @@
1
+ export * from './utils'
2
+ export * from './apiSigning'
3
+ export * from './captcha'
4
+ export * from './estimateGas'
5
+ export * from './multiProvider'
6
+ export * from './promiseFight'
7
+ export * from './signatures'
8
+ export * from './uuid'
9
+ export * from './network'
10
+ export * from './importContractABI'
11
+ export * from './types'
@@ -0,0 +1,72 @@
1
+ import { callbackify, promisify } from 'util'
2
+ import Web3 from '../web3'
3
+ import { shuffle } from 'lodash'
4
+ import type { HttpProvider, AbstractProvider } from 'web3-core'
5
+ import type { JsonRpcPayload } from 'web3-core-helpers'
6
+
7
+ const getSendMethod = (provider: HttpProvider | AbstractProvider) => {
8
+ if ('sendAsync' in provider) {
9
+ return provider.sendAsync
10
+ }
11
+ return provider.send
12
+ }
13
+
14
+ type Providers = [HttpProvider, ...Array<HttpProvider | AbstractProvider>]
15
+
16
+ /**
17
+ * web3 consumes a provider object on initialization
18
+ * ref: https://github.com/ChainSafe/web3.js/blob/1.x/packages/web3/types/index.d.ts#L31
19
+ * which references: https://github.com/ChainSafe/web3.js/blob/1.x/packages/web3-core/types/index.d.ts#L436
20
+ * MultiProvider implements HttpProvider which can be consumed by web3
21
+ * ref for HttpProvider: https://github.com/ChainSafe/web3.js/blob/1.x/packages/web3-providers-http/types/index.d.ts#L46-L66
22
+ */
23
+ export class MultiProvider extends Web3.providers.HttpProvider {
24
+ providers: Providers
25
+ /**
26
+ * Creates a MultiProvider
27
+ * @param {Array<string | Provider> | string} - The providers to use.
28
+ */
29
+ constructor(providers: string[] | string) {
30
+ let web3Providers: string[]
31
+ if (typeof providers === 'string') {
32
+ web3Providers = providers.split(',')
33
+ } else if (!Array.isArray(providers)) {
34
+ web3Providers = [providers]
35
+ } else {
36
+ web3Providers = providers
37
+ }
38
+
39
+ // The below line ensures that we support different types of providers i.e. comma separated strings, an array of strings or an array of providers.
40
+ const web3ProviderInstances = web3Providers.map(
41
+ (provider) => new Web3(provider).eth.currentProvider
42
+ ) as Providers
43
+ super(web3ProviderInstances[0]?.host)
44
+
45
+ if (!web3ProviderInstances.every(getSendMethod)) {
46
+ throw new Error('Some providers do not have a send method to use.')
47
+ }
48
+
49
+ this.providers = web3ProviderInstances
50
+
51
+ // We replace HttpProvider.send with a custom function that supports fallback providers.
52
+ this.send = callbackify(this._send.bind(this)) // web3 only supports callback functions and not async
53
+ }
54
+
55
+ /**
56
+ * @method _send
57
+ * @param {Object} payload
58
+ */
59
+ async _send(payload: JsonRpcPayload) {
60
+ for (const provider of shuffle(this.providers)) {
61
+ try {
62
+ const send = promisify(getSendMethod(provider).bind(provider))
63
+ const result = await send(payload)
64
+ return result
65
+ } catch (e) {
66
+ console.log(e)
67
+ }
68
+ }
69
+
70
+ throw new Error('All requests failed')
71
+ }
72
+ }
@@ -0,0 +1,127 @@
1
+ import assert from 'assert'
2
+ import nock from 'nock'
3
+
4
+ import { timeRequests } from './network'
5
+
6
+ const setupRequest = (
7
+ url: string,
8
+ delay: number,
9
+ version: string,
10
+ status = 200
11
+ ) => {
12
+ const req = { url }
13
+ nock(req.url).get('/').delay(delay).reply(status, {
14
+ data: {
15
+ version
16
+ }
17
+ })
18
+ return req
19
+ }
20
+
21
+ describe('timeRequests()', () => {
22
+ it('sortByVersion = true', async () => {
23
+ const requests = [
24
+ setupRequest('https://fastest.audius.co', 50, '1.2.3'),
25
+ setupRequest('https://fastAndAhead.audius.co', 100, '1.2.4'),
26
+ setupRequest('https://behind.audius.co', 100, '1.2.2'),
27
+ setupRequest('https://slow.audius.co', 500, '1.2.3'),
28
+ setupRequest('https://error.audius.co', 500, '1.2.3', 404)
29
+ ]
30
+
31
+ const res = await timeRequests({
32
+ requests,
33
+ sortByVersion: true
34
+ })
35
+
36
+ assert.strictEqual(res[0]?.request.url, 'https://fastAndAhead.audius.co')
37
+ assert.strictEqual(res[1]?.request.url, 'https://fastest.audius.co')
38
+ assert.strictEqual(res[2]?.request.url, 'https://slow.audius.co')
39
+ assert.strictEqual(res[3]?.request.url, 'https://behind.audius.co')
40
+ assert.strictEqual(res[4]?.request.url, 'https://error.audius.co')
41
+ })
42
+
43
+ it('sortByVersion = false', async () => {
44
+ const requests = [
45
+ setupRequest('https://fastest.audius.co', 50, '1.2.3'),
46
+ setupRequest('https://fastAndAhead.audius.co', 100, '1.2.4'),
47
+ setupRequest('https://fastAndBehind.audius.co', 100, '1.2.2'),
48
+ setupRequest('https://slow.audius.co', 500, '1.2.3'),
49
+ setupRequest('https://slowAndError.audius.co', 500, '1.2.3', 404)
50
+ ]
51
+
52
+ const res = await timeRequests({
53
+ requests,
54
+ sortByVersion: false,
55
+ currentVersion: '1.2.3'
56
+ })
57
+
58
+ // All healthy nodes with valid version should be sorted by request duration, remaining by version then duration
59
+ assert.strictEqual(res[0]?.request.url, 'https://fastest.audius.co')
60
+ assert.strictEqual(res[1]?.request.url, 'https://fastAndAhead.audius.co')
61
+ assert.strictEqual(res[2]?.request.url, 'https://slow.audius.co')
62
+ assert.strictEqual(res[3]?.request.url, 'https://fastAndBehind.audius.co')
63
+ assert.strictEqual(res[4]?.request.url, 'https://slowAndError.audius.co')
64
+ })
65
+
66
+ it('respects an equivalency delta', async () => {
67
+ const allResults: string[] = []
68
+ for (let i = 0; i < 20; ++i) {
69
+ const requests = [
70
+ setupRequest('https://cohort1a.audius.co', 1, '1.2.3'),
71
+ setupRequest('https://cohort1b.audius.co', 1, '1.2.3'),
72
+ setupRequest('https://cohort1c.audius.co', 1, '1.2.3'),
73
+
74
+ setupRequest('https://cohort2a.audius.co', 100, '1.2.3'),
75
+ setupRequest('https://cohort2b.audius.co', 101, '1.2.3'),
76
+ setupRequest('https://cohort2c.audius.co', 102, '1.2.3'),
77
+
78
+ setupRequest('https://cohort3a.audius.co', 200, '1.2.3'),
79
+ setupRequest('https://cohort3b.audius.co', 220, '1.2.3'),
80
+ setupRequest('https://cohort3c.audius.co', 205, '1.2.3')
81
+ ]
82
+ const res = await timeRequests({
83
+ requests,
84
+ sortByVersion: true,
85
+ equivalencyDelta: 50
86
+ })
87
+ allResults.push(res.map((r) => r.request.url).join(''))
88
+
89
+ // Ensure that each round of testing separates by cohors
90
+ assert(res[0]?.request.url.startsWith('https://cohort1'))
91
+ assert(res[1]?.request.url.startsWith('https://cohort1'))
92
+ assert(res[2]?.request.url.startsWith('https://cohort1'))
93
+
94
+ assert(res[3]?.request.url.startsWith('https://cohort2'))
95
+ assert(res[4]?.request.url.startsWith('https://cohort2'))
96
+ assert(res[5]?.request.url.startsWith('https://cohort2'))
97
+
98
+ assert(res[6]?.request.url.startsWith('https://cohort3'))
99
+ assert(res[7]?.request.url.startsWith('https://cohort3'))
100
+ assert(res[8]?.request.url.startsWith('https://cohort3'))
101
+ }
102
+
103
+ // Make sure there is some variance
104
+ assert(!allResults.every((val) => val === allResults[0]))
105
+ }).timeout(10000)
106
+
107
+ it('filterNonResponsive = true', async () => {
108
+ const requests = [
109
+ setupRequest('https://fastest.audius.co', 50, '1.2.3'),
110
+ setupRequest('https://fast.audius.co', 100, '1.2.3'),
111
+ setupRequest('https://fastAndBehind.audius.co', 100, '1.2.2'),
112
+ setupRequest('https://slow.audius.co', 500, '1.2.3'),
113
+ setupRequest('https://slowAndError.audius.co', 500, '1.2.3', 404)
114
+ ]
115
+
116
+ const res = await timeRequests({
117
+ requests,
118
+ sortByVersion: true,
119
+ filterNonResponsive: true,
120
+ timeout: 150
121
+ })
122
+
123
+ assert.strictEqual(res[0]?.request.url, 'https://fastest.audius.co')
124
+ assert.strictEqual(res[1]?.request.url, 'https://fast.audius.co')
125
+ assert.strictEqual(res[2]?.request.url, 'https://fastAndBehind.audius.co')
126
+ })
127
+ })