@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,604 @@
1
+ const { Base, Services } = require('./base')
2
+ const { CreatorNode } = require('../services/creatorNode')
3
+ const { Utils } = require('../utils')
4
+ const retry = require('async-retry')
5
+
6
+ const TRACK_PROPS = [
7
+ 'owner_id',
8
+ 'title',
9
+ 'length',
10
+ 'cover_art_sizes',
11
+ 'tags',
12
+ 'genre',
13
+ 'mood',
14
+ 'credits_splits',
15
+ 'release_date',
16
+ 'file_type'
17
+ ]
18
+ const TRACK_REQUIRED_PROPS = [
19
+ 'owner_id',
20
+ 'title'
21
+ ]
22
+
23
+ class Track extends Base {
24
+ constructor (...args) {
25
+ super(...args)
26
+ this.getTracks = this.getTracks.bind(this)
27
+ this.getTracksIncludingUnlisted = this.getTracksIncludingUnlisted.bind(this)
28
+ this.getRandomTracks = this.getRandomTracks.bind(this)
29
+ this.getStemsForTrack = this.getStemsForTrack.bind(this)
30
+ this.getRemixesOfTrack = this.getRemixesOfTrack.bind(this)
31
+ this.getRemixTrackParents = this.getRemixTrackParents.bind(this)
32
+ this.getSavedTracks = this.getSavedTracks.bind(this)
33
+ this.getTrendingTracks = this.getTrendingTracks.bind(this)
34
+ this.getTrackListens = this.getTrackListens.bind(this)
35
+ this.getSaversForTrack = this.getSaversForTrack.bind(this)
36
+ this.getSaversForPlaylist = this.getSaversForPlaylist.bind(this)
37
+ this.getRepostersForTrack = this.getRepostersForTrack.bind(this)
38
+ this.getRepostersForPlaylist = this.getRepostersForPlaylist.bind(this)
39
+ this.getListenHistoryTracks = this.getListenHistoryTracks.bind(this)
40
+ this.checkIfDownloadAvailable = this.checkIfDownloadAvailable.bind(this)
41
+ this.uploadTrack = this.uploadTrack.bind(this)
42
+ this.uploadTrackContentToCreatorNode = this.uploadTrackContentToCreatorNode.bind(this)
43
+ this.addTracksToChainAndCnode = this.addTracksToChainAndCnode.bind(this)
44
+ this.updateTrack = this.updateTrack.bind(this)
45
+ this.logTrackListen = this.logTrackListen.bind(this)
46
+ this.addTrackRepost = this.addTrackRepost.bind(this)
47
+ this.deleteTrackRepost = this.deleteTrackRepost.bind(this)
48
+ this.addTrackSave = this.addTrackSave.bind(this)
49
+ this.deleteTrackSave = this.deleteTrackSave.bind(this)
50
+ this.deleteTrack = this.deleteTrack.bind(this)
51
+ }
52
+ /* ------- GETTERS ------- */
53
+
54
+ /**
55
+ * get tracks with all relevant track data
56
+ * can be filtered by providing an integer array of ids
57
+ * @param {number} limit
58
+ * @param {number} offset
59
+ * @param {Object} idsArray
60
+ * @param {number} targetUserId the owner of the tracks being queried
61
+ * @param {string} sort a string of form eg. blocknumber:asc,timestamp:desc describing a sort path
62
+ * @param {number} minBlockNumber The min block number
63
+ * @param {boolean} filterDeleted If set to true filters out deleted tracks
64
+ * @returns {Object} {Array of track metadata Objects}
65
+ * additional metadata fields on track objects:
66
+ * {Integer} repost_count - repost count for given track
67
+ * {Integer} save_count - save count for given track
68
+ * {Array} followee_reposts - followees of current user that have reposted given track
69
+ * {Boolean} has_current_user_reposted - has current user reposted given track
70
+ * {Boolean} has_current_user_saved - has current user saved given track
71
+ * @example
72
+ * await getTracks()
73
+ * await getTracks(100, 0, [3,2,6]) - Invalid track ids will not be accepted
74
+ */
75
+ async getTracks (limit = 100, offset = 0, idsArray = null, targetUserId = null, sort = null, minBlockNumber = null, filterDeleted = null, withUsers = false) {
76
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
77
+ return this.discoveryProvider.getTracks(limit, offset, idsArray, targetUserId, sort, minBlockNumber, filterDeleted, withUsers)
78
+ }
79
+
80
+ /**
81
+ * Gets tracks by their slug and owner handle
82
+ * @param {string} handle the owner's handle
83
+ * @param {string} slug the track's slug, including collision identifiers
84
+ */
85
+ async getTracksByHandleAndSlug (handle, slug) {
86
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
87
+ return this.discoveryProvider.getTracksByHandleAndSlug(handle, slug)
88
+ }
89
+
90
+ /**
91
+ * @typedef {Object} getTracksIdentifier
92
+ * @property {string} handle
93
+ * @property {number} id
94
+ * @property {string} url_title
95
+ */
96
+
97
+ /**
98
+ * gets all tracks matching identifiers, including unlisted.
99
+ *
100
+ * @param {getTracksIdentifier[]} identifiers
101
+ * @returns {(Array)} track
102
+ */
103
+ async getTracksIncludingUnlisted (identifiers, withUsers = false) {
104
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
105
+ return this.discoveryProvider.getTracksIncludingUnlisted(identifiers, withUsers)
106
+ }
107
+
108
+ /**
109
+ * Gets random tracks from trending tracks for a given genre.
110
+ * If genre not given, will return trending tracks across all genres.
111
+ * Excludes specified track ids.
112
+ *
113
+ * @param {string} genre
114
+ * @param {number} limit
115
+ * @param {number[]} exclusionList
116
+ * @param {string} time
117
+ * @returns {(Array)} track
118
+ */
119
+ async getRandomTracks (genre, limit, exclusionList, time) {
120
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
121
+ return this.discoveryProvider.getRandomTracks(genre, limit, exclusionList, time)
122
+ }
123
+
124
+ /**
125
+ * Gets all stems for a given trackId as an array of tracks.
126
+ * @param {number} trackId
127
+ * @returns {(Array)} track
128
+ */
129
+ async getStemsForTrack (trackId) {
130
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
131
+ return this.discoveryProvider.getStemsForTrack(trackId)
132
+ }
133
+
134
+ /**
135
+ * Gets all the remixes of a given trackId as an array of tracks.
136
+ * @param {number} trackId
137
+ * @param {number} limit
138
+ * @param {number} offset
139
+ * @returns {(Array)} track
140
+ */
141
+ async getRemixesOfTrack (trackId, limit = null, offset = null) {
142
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
143
+ return this.discoveryProvider.getRemixesOfTrack(trackId, limit, offset)
144
+ }
145
+
146
+ /**
147
+ * Gets the remix parents of a given trackId as an array of tracks.
148
+ * @param {number} trackId
149
+ * @param {number} limit
150
+ * @param {number} offset
151
+ * @returns {(Array)} track
152
+ * @returns {(Array)} track
153
+ */
154
+ async getRemixTrackParents (trackId, limit = null, offset = null) {
155
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
156
+ return this.discoveryProvider.getRemixTrackParents(trackId, limit, offset)
157
+ }
158
+
159
+ /**
160
+ * Return saved tracks for current user
161
+ * NOTE in returned JSON, SaveType string one of track, playlist, album
162
+ * @param {number} limit - max # of items to return
163
+ * @param {number} offset - offset into list to return from (for pagination)
164
+ */
165
+ async getSavedTracks (limit = 100, offset = 0, withUsers = false) {
166
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
167
+ return this.discoveryProvider.getSavedTracks(limit, offset, withUsers)
168
+ }
169
+
170
+ /**
171
+ * Gets tracks trending on Audius.
172
+ * @param {string} genre
173
+ * @param {string} timeFrame one of day, week, month, or year
174
+ * @param {?Array<number>} idsArray track ids
175
+ * @param {?number} limit
176
+ * @param {?number} offset
177
+ * @returns {{listenCounts: Array<{trackId:number, listens:number}>}}
178
+ */
179
+ async getTrendingTracks (genre = null, time = null, idsArray = null, limit = null, offset = null, withUsers = false) {
180
+ this.REQUIRES(Services.IDENTITY_SERVICE)
181
+ return this.discoveryProvider.getTrendingTracks(genre, time, idsArray, limit, offset)
182
+ }
183
+
184
+ /**
185
+ * Gets listens for tracks bucketted by timeFrame.
186
+ * @param {string} timeFrame one of day, week, month, or year
187
+ * @param {?Array<number>} idsArray track ids
188
+ * @param {?string} startTime parseable by Date.parse
189
+ * @param {?string} endTime parseable by Date.parse
190
+ * @param {?number} limit
191
+ * @param {?number} offset
192
+ * @returns {{bucket:Array<{trackId:number, date:bucket, listens:number}>}}
193
+ */
194
+ async getTrackListens (timeFrame = null, idsArray = null, startTime = null, endTime = null, limit = null, offset = null) {
195
+ this.REQUIRES(Services.IDENTITY_SERVICE)
196
+ return this.identityService.getTrackListens(timeFrame, idsArray, startTime, endTime, limit, offset)
197
+ }
198
+
199
+ /**
200
+ * get users that saved saveTrackId, sorted by follower count descending
201
+ * @param {number} saveTrackId
202
+ * @return {Array} array of user objects
203
+ * additional metadata fields on user objects:
204
+ * {Integer} follower_count - follower count of given user
205
+ * @example
206
+ * getSaversForTrack(100, 0, 1) - ID must be valid
207
+ */
208
+ async getSaversForTrack (limit = 100, offset = 0, saveTrackId) {
209
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
210
+ return this.discoveryProvider.getSaversForTrack(limit, offset, saveTrackId)
211
+ }
212
+
213
+ /**
214
+ * get users that saved savePlaylistId, sorted by follower count descending
215
+ * @param {number} savePlaylistId
216
+ * @return {Array} array of user objects
217
+ * additional metadata fields on user objects:
218
+ * {Integer} follower_count - follower count of given user
219
+ * @example
220
+ * getSaversForPlaylist(100, 0, 1) - ID must be valid
221
+ */
222
+ async getSaversForPlaylist (limit = 100, offset = 0, savePlaylistId) {
223
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
224
+ return this.discoveryProvider.getSaversForPlaylist(limit, offset, savePlaylistId)
225
+ }
226
+
227
+ /**
228
+ * get users that reposted repostTrackId, sorted by follower count descending
229
+ * @param {number} repostTrackId
230
+ * @return {Array} array of user objects
231
+ * additional metadata fields on user objects:
232
+ * {Integer} follower_count - follower count of given user
233
+ * @example
234
+ * getRepostersForTrack(100, 0, 1) - ID must be valid
235
+ */
236
+ async getRepostersForTrack (limit = 100, offset = 0, repostTrackId) {
237
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
238
+ return this.discoveryProvider.getRepostersForTrack(limit, offset, repostTrackId)
239
+ }
240
+
241
+ /**
242
+ * get users that reposted repostPlaylistId, sorted by follower count descending
243
+ * @param {number} repostPlaylistId
244
+ * @return {Array} array of user objects
245
+ * additional metadata fields on user objects:
246
+ * {Integer} follower_count - follower count of given user
247
+ * @example
248
+ * getRepostersForPlaylist(100, 0, 1) - ID must be valid
249
+ */
250
+ async getRepostersForPlaylist (limit = 100, offset = 0, repostPlaylistId) {
251
+ this.REQUIRES(Services.DISCOVERY_PROVIDER)
252
+ return this.discoveryProvider.getRepostersForPlaylist(limit, offset, repostPlaylistId)
253
+ }
254
+
255
+ /**
256
+ * Return saved tracks for current user
257
+ * NOTE in returned JSON, SaveType string one of track, playlist, album
258
+ * @param {number} limit - max # of items to return
259
+ * @param {number} offset - offset into list to return from (for pagination)
260
+ */
261
+ async getListenHistoryTracks (limit = 100, offset = 0) {
262
+ this.REQUIRES(Services.IDENTITY_SERVICE)
263
+ const userId = this.userStateManager.getCurrentUserId()
264
+ return this.identityService.getListenHistoryTracks(userId, limit, offset)
265
+ }
266
+
267
+ /**
268
+ * Checks if a download is available from provided creator node endpoints
269
+ * @param {string} creatorNodeEndpoints creator node endpoints
270
+ * @param {number} trackId
271
+ */
272
+ async checkIfDownloadAvailable (trackId, creatorNodeEndpoints) {
273
+ return CreatorNode.checkIfDownloadAvailable(trackId, creatorNodeEndpoints)
274
+ }
275
+
276
+ /* ------- SETTERS ------- */
277
+
278
+ /**
279
+ * Takes in a readable stream if isServer is true, or a file reference if isServer is
280
+ * false.
281
+ * Uploads file, retrieves multihash, adds multihash to input metadata object,
282
+ * uploads metadata, and finally returns metadata multihash
283
+ * Wraps the stateless function in AudiusLib.
284
+ *
285
+ * @param {File} trackFile ReadableStream from server, or File handle on client
286
+ * @param {File} coverArtFile ReadableStream from server, or File handle on client
287
+ * @param {Object} metadata json of the track metadata with all fields, missing fields will error
288
+ * @param {function} onProgress callback fired with (loaded, total) on byte upload progress
289
+ */
290
+ async uploadTrack (
291
+ trackFile,
292
+ coverArtFile,
293
+ metadata,
294
+ onProgress
295
+ ) {
296
+ this.REQUIRES(Services.CREATOR_NODE)
297
+ this.FILE_IS_VALID(trackFile)
298
+
299
+ const phases = {
300
+ GETTING_USER: 'GETTING_USER',
301
+ UPLOADING_TRACK_CONTENT: 'UPLOADING_TRACK_CONTENT',
302
+ ADDING_TRACK: 'ADDING_TRACK',
303
+ ASSOCIATING_TRACK: 'ASSOCIATING_TRACK'
304
+ }
305
+
306
+ let phase = phases.GETTING_USER
307
+
308
+ try {
309
+ if (coverArtFile) this.FILE_IS_VALID(coverArtFile)
310
+
311
+ this.IS_OBJECT(metadata)
312
+
313
+ const ownerId = this.userStateManager.getCurrentUserId()
314
+ if (!ownerId) {
315
+ return {
316
+ error: 'No users loaded for this wallet',
317
+ phase
318
+ }
319
+ }
320
+
321
+ metadata.owner_id = ownerId
322
+ this._validateTrackMetadata(metadata)
323
+
324
+ phase = phases.UPLOADING_TRACK_CONTENT
325
+
326
+ // Upload metadata
327
+ const {
328
+ metadataMultihash,
329
+ metadataFileUUID,
330
+ transcodedTrackUUID,
331
+ transcodedTrackCID
332
+ } = await retry(async (bail, num) => {
333
+ return this.creatorNode.uploadTrackContent(
334
+ trackFile,
335
+ coverArtFile,
336
+ metadata,
337
+ onProgress
338
+ )
339
+ }, {
340
+ // Retry function 3x
341
+ // 1st retry delay = 500ms, 2nd = 1500ms, 3rd...nth retry = 4000 ms (capped)
342
+ minTimeout: 500,
343
+ maxTimeout: 4000,
344
+ factor: 3,
345
+ retries: 3,
346
+ onRetry: (err, i) => {
347
+ if (err) {
348
+ console.log('uploadTrackContent retry error: ', err)
349
+ }
350
+ }
351
+ })
352
+
353
+ phase = phases.ADDING_TRACK
354
+
355
+ // Write metadata to chain
356
+ const multihashDecoded = Utils.decodeMultihash(metadataMultihash)
357
+ const { txReceipt, trackId } = await this.contracts.TrackFactoryClient.addTrack(
358
+ ownerId,
359
+ multihashDecoded.digest,
360
+ multihashDecoded.hashFn,
361
+ multihashDecoded.size
362
+ )
363
+
364
+ phase = phases.ASSOCIATING_TRACK
365
+ // Associate the track id with the file metadata and block number
366
+ await this.creatorNode.associateTrack(
367
+ trackId,
368
+ metadataFileUUID,
369
+ txReceipt.blockNumber,
370
+ transcodedTrackUUID
371
+ )
372
+ return { blockHash: txReceipt.blockHash, blockNumber: txReceipt.blockNumber, trackId, transcodedTrackCID, error: false }
373
+ } catch (e) {
374
+ return {
375
+ error: e.message,
376
+ phase
377
+ }
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Takes in a readable stream if isServer is true, or a file reference if isServer is
383
+ * false.
384
+ * WARNING: Uploads file to creator node, but does not call contracts
385
+ * Please pair this with the addTracksToChainAndCnode
386
+ */
387
+ async uploadTrackContentToCreatorNode (
388
+ trackFile,
389
+ coverArtFile,
390
+ metadata,
391
+ onProgress
392
+ ) {
393
+ this.REQUIRES(Services.CREATOR_NODE)
394
+ this.FILE_IS_VALID(trackFile)
395
+
396
+ if (coverArtFile) this.FILE_IS_VALID(coverArtFile)
397
+
398
+ this.IS_OBJECT(metadata)
399
+
400
+ const ownerId = this.userStateManager.getCurrentUserId()
401
+ if (!ownerId) {
402
+ throw new Error('No users loaded for this wallet')
403
+ }
404
+
405
+ metadata.owner_id = ownerId
406
+ this._validateTrackMetadata(metadata)
407
+
408
+ // Upload metadata
409
+ const { metadataMultihash, metadataFileUUID, transcodedTrackCID, transcodedTrackUUID } = await retry(async (bail, num) => {
410
+ return this.creatorNode.uploadTrackContent(
411
+ trackFile,
412
+ coverArtFile,
413
+ metadata,
414
+ onProgress
415
+ )
416
+ }, {
417
+ // Retry function 3x
418
+ // 1st retry delay = 500ms, 2nd = 1500ms, 3rd...nth retry = 4000 ms (capped)
419
+ minTimeout: 500,
420
+ maxTimeout: 4000,
421
+ factor: 3,
422
+ retries: 3,
423
+ onRetry: (err, i) => {
424
+ if (err) {
425
+ console.log('uploadTrackContentToCreatorNode retry error: ', err)
426
+ }
427
+ }
428
+ })
429
+ return { metadataMultihash, metadataFileUUID, transcodedTrackCID, transcodedTrackUUID }
430
+ }
431
+
432
+ /**
433
+ * Takes an array of [{metadataMultihash, metadataFileUUID}, {}, ]
434
+ * Adds tracks to chain for this user
435
+ * Associates tracks with user on creatorNode
436
+ */
437
+ async addTracksToChainAndCnode (trackMultihashAndUUIDList) {
438
+ this.REQUIRES(Services.CREATOR_NODE)
439
+ const ownerId = this.userStateManager.getCurrentUserId()
440
+ if (!ownerId) {
441
+ throw new Error('No users loaded for this wallet')
442
+ }
443
+
444
+ const addedToChain = []
445
+ let requestFailed = false
446
+ await Promise.all(
447
+ trackMultihashAndUUIDList.map(async (trackInfo, i) => {
448
+ try {
449
+ const { metadataMultihash, metadataFileUUID, transcodedTrackUUID } = trackInfo
450
+
451
+ // Write metadata to chain
452
+ const multihashDecoded = Utils.decodeMultihash(metadataMultihash)
453
+ const { txReceipt, trackId } = await this.contracts.TrackFactoryClient.addTrack(
454
+ ownerId,
455
+ multihashDecoded.digest,
456
+ multihashDecoded.hashFn,
457
+ multihashDecoded.size
458
+ )
459
+
460
+ addedToChain[i] = { trackId, metadataFileUUID, transcodedTrackUUID, txReceipt }
461
+ } catch (e) {
462
+ requestFailed = true
463
+ console.error(e)
464
+ }
465
+ })
466
+ )
467
+
468
+ // Any failures in addTrack to the blockchain will prevent further progress
469
+ // The list of successful track uploads is returned for revert operations by caller
470
+ if (requestFailed || (addedToChain.filter(Boolean).length !== trackMultihashAndUUIDList.length)) {
471
+ return { error: true, trackIds: addedToChain.filter(Boolean).map(x => x.trackId) }
472
+ }
473
+
474
+ const associatedWithCreatorNode = []
475
+ try {
476
+ await Promise.all(
477
+ addedToChain.map(async chainTrackInfo => {
478
+ const metadataFileUUID = chainTrackInfo.metadataFileUUID
479
+ const transcodedTrackUUID = chainTrackInfo.transcodedTrackUUID
480
+ const trackId = chainTrackInfo.trackId
481
+ await this.creatorNode.associateTrack(
482
+ trackId,
483
+ metadataFileUUID,
484
+ chainTrackInfo.txReceipt.blockNumber,
485
+ transcodedTrackUUID
486
+ )
487
+ associatedWithCreatorNode.push(trackId)
488
+ })
489
+ )
490
+ } catch (e) {
491
+ // Any single failure to associate also prevents further progress
492
+ // Returning error code along with associated track ids allows caller to revert
493
+ return { error: true, trackIds: addedToChain.map(x => x.trackId) }
494
+ }
495
+
496
+ return { error: false, trackIds: addedToChain.map(x => x.trackId) }
497
+ }
498
+
499
+ /**
500
+ * Updates an existing track given metadata. This function expects that all associated files
501
+ * such as track content, cover art are already on creator node.
502
+ * @param {Object} metadata json of the track metadata with all fields, missing fields will error
503
+ */
504
+ async updateTrack (metadata) {
505
+ this.REQUIRES(Services.CREATOR_NODE)
506
+ this.IS_OBJECT(metadata)
507
+
508
+ const ownerId = this.userStateManager.getCurrentUserId()
509
+
510
+ if (!ownerId) {
511
+ throw new Error('No users loaded for this wallet')
512
+ }
513
+ metadata.owner_id = ownerId
514
+ this._validateTrackMetadata(metadata)
515
+
516
+ // Upload new metadata
517
+ const { metadataMultihash, metadataFileUUID } = await this.creatorNode.uploadTrackMetadata(
518
+ metadata
519
+ )
520
+ // Write the new metadata to chain
521
+ const multihashDecoded = Utils.decodeMultihash(metadataMultihash)
522
+ const trackId = metadata.track_id
523
+ const { txReceipt } = await this.contracts.TrackFactoryClient.updateTrack(
524
+ trackId,
525
+ ownerId,
526
+ multihashDecoded.digest,
527
+ multihashDecoded.hashFn,
528
+ multihashDecoded.size
529
+ )
530
+ // Re-associate the track id with the new metadata
531
+ await this.creatorNode.associateTrack(trackId, metadataFileUUID, txReceipt.blockNumber)
532
+ return { blockHash: txReceipt.blockHash, blockNumber: txReceipt.blockNumber, trackId }
533
+ }
534
+
535
+ /**
536
+ * Logs a track listen for a given user id.
537
+ * @param {string} unauthUuid account for those not logged in
538
+ * @param {number} trackId listened to
539
+ */
540
+ async logTrackListen (trackId, unauthUuid, solanaListen = false) {
541
+ this.REQUIRES(Services.IDENTITY_SERVICE)
542
+ const accountId = this.userStateManager.getCurrentUserId()
543
+
544
+ const userId = accountId || unauthUuid
545
+ return this.identityService.logTrackListen(
546
+ trackId,
547
+ userId,
548
+ null,
549
+ null,
550
+ solanaListen
551
+ )
552
+ }
553
+
554
+ /** Adds a repost for a given user and track
555
+ * @param {number} trackId track being reposted
556
+ */
557
+ async addTrackRepost (trackId) {
558
+ const userId = this.userStateManager.getCurrentUserId()
559
+ return this.contracts.SocialFeatureFactoryClient.addTrackRepost(userId, trackId)
560
+ }
561
+
562
+ /**
563
+ * Deletes a repost for a given user and track
564
+ * @param {number} track id of deleted repost
565
+ */
566
+ async deleteTrackRepost (trackId) {
567
+ const userId = this.userStateManager.getCurrentUserId()
568
+ return this.contracts.SocialFeatureFactoryClient.deleteTrackRepost(userId, trackId)
569
+ }
570
+
571
+ /**
572
+ * Adds a track save for a given user and track
573
+ * @param {number} trackId track being saved
574
+ */
575
+ async addTrackSave (trackId) {
576
+ const userId = this.userStateManager.getCurrentUserId()
577
+ return this.contracts.UserLibraryFactoryClient.addTrackSave(userId, trackId)
578
+ }
579
+
580
+ /**
581
+ * Delete a track save for a given user and track
582
+ * @param {number} track save being removed
583
+ */
584
+ async deleteTrackSave (trackId) {
585
+ const userId = this.userStateManager.getCurrentUserId()
586
+ return this.contracts.UserLibraryFactoryClient.deleteTrackSave(userId, trackId)
587
+ }
588
+
589
+ /**
590
+ * Marks a tracks as deleted
591
+ * @param {number} trackId
592
+ */
593
+ async deleteTrack (trackId) {
594
+ return this.contracts.TrackFactoryClient.deleteTrack(trackId)
595
+ }
596
+
597
+ /* ------- PRIVATE ------- */
598
+
599
+ _validateTrackMetadata (metadata) {
600
+ this.OBJECT_HAS_PROPS(metadata, TRACK_PROPS, TRACK_REQUIRED_PROPS)
601
+ }
602
+ }
603
+
604
+ module.exports = Track