@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,96 @@
1
+ import { Hedgehog as HedgehogBase, WalletManager } from '@audius/hedgehog'
2
+ import type { IdentityService } from '../identity'
3
+
4
+ export type HedgehogConfig = {
5
+ identityService: IdentityService
6
+ useLocalStorage?: boolean
7
+ }
8
+ export class Hedgehog {
9
+ identityService: IdentityService
10
+ getFn: IdentityService['getFn']
11
+ setAuthFn: IdentityService['setAuthFn']
12
+ setUserFn: IdentityService['setUserFn']
13
+ instance: HedgehogBase
14
+
15
+ // TODO - update this comment
16
+
17
+ // This is some black magic going on here. The audiusServiceEndpoint is passed in along with the
18
+ // requestToAudiusService function reference. When setFn and getFn call self.requestToAudiusService,
19
+ // the context of `this` that's used is the HedgehogWrapper class, not the AudiusWeb3 class.
20
+ // Therefore, we need to define this.audiusServiceEndpoint, to satisfy all the deps of the
21
+ // requestToAudiusService and make it execute correctly
22
+
23
+ constructor({ identityService, useLocalStorage = true }: HedgehogConfig) {
24
+ this.identityService = identityService
25
+
26
+ this.getFn = async (obj) => {
27
+ return await this.identityService.getFn(obj)
28
+ }
29
+
30
+ this.setAuthFn = async (obj) => {
31
+ return await this.identityService.setAuthFn(obj)
32
+ }
33
+
34
+ this.setUserFn = async (obj) => {
35
+ return await this.identityService.setUserFn(obj)
36
+ }
37
+
38
+ const hedgehog = new HedgehogBase(
39
+ this.getFn,
40
+ this.setAuthFn,
41
+ this.setUserFn,
42
+ useLocalStorage
43
+ )
44
+
45
+ // we override the login function here because getFn needs both lookupKey and email
46
+ // in identity service, but hedgehog only sends lookupKey
47
+ hedgehog.login = async (email, password) => {
48
+ const lookupKey = await WalletManager.createAuthLookupKey(email, password)
49
+
50
+ // hedgehog property is called username so being consistent instead of calling it email
51
+ const data = await this.getFn({ lookupKey: lookupKey, username: email })
52
+
53
+ if (data?.iv && data.cipherText) {
54
+ const { walletObj, entropy } =
55
+ await WalletManager.decryptCipherTextAndRetrieveWallet(
56
+ password,
57
+ data.iv,
58
+ data.cipherText
59
+ )
60
+
61
+ // set wallet property on the class
62
+ hedgehog.wallet = walletObj
63
+
64
+ // set entropy in localStorage
65
+ WalletManager.setEntropyInLocalStorage(entropy)
66
+ return walletObj
67
+ } else {
68
+ throw new Error('No account record for user')
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Generate secure credentials to allow login
74
+ * @param username username
75
+ */
76
+ hedgehog.generateRecoveryInfo = async () => {
77
+ const entropy = await WalletManager.getEntropyFromLocalStorage()
78
+ if (entropy === null) {
79
+ throw new Error('generateRecoveryLink - missing entropy')
80
+ }
81
+ let btoa // binary to base64 ASCII conversion
82
+ let currentHost
83
+ if (typeof window !== 'undefined' && window && window.btoa) {
84
+ btoa = window.btoa
85
+ currentHost = window.location.origin
86
+ } else {
87
+ btoa = (str: string) => Buffer.from(str, 'binary').toString('base64')
88
+ currentHost = 'localhost'
89
+ }
90
+ const recoveryInfo = { login: btoa(entropy), host: currentHost }
91
+ return recoveryInfo
92
+ }
93
+
94
+ this.instance = hedgehog
95
+ }
96
+ }
@@ -0,0 +1 @@
1
+ export * from './Hedgehog'
@@ -0,0 +1,551 @@
1
+ import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AuthHeaders } from '../../constants'
3
+ import { uuid } from '../../utils/uuid'
4
+ import type { Captcha } from '../../utils'
5
+
6
+ import { getTrackListens, TimeFrame } from './requests'
7
+ import type { Web3Manager } from '../web3Manager'
8
+ import type { TransactionReceipt } from 'web3-core'
9
+ import type Wallet from 'ethereumjs-wallet'
10
+
11
+ type Data = Record<string, unknown>
12
+
13
+ export type RelayTransaction = {
14
+ resp: {
15
+ txHash: string
16
+ txParams: {
17
+ data: string
18
+ gasLimit: string
19
+ gasPrice: number
20
+ nonce: string
21
+ to: string
22
+ value: string
23
+ }
24
+ }
25
+ }
26
+
27
+ type TransactionData = {
28
+ recentBlockhash: string
29
+ secpInstruction?: {
30
+ publicKey: string
31
+ message: string
32
+ signature: any
33
+ recoveryId: number
34
+ }
35
+ instruction: {
36
+ keys: Array<{
37
+ pubkey: string
38
+ isSigner?: boolean
39
+ isWritable?: boolean
40
+ }>
41
+ programId: string
42
+ data: Record<string, unknown>
43
+ }
44
+ }
45
+
46
+ type AttestationResult = {
47
+ status: string
48
+ userId: string
49
+ challengeId: string
50
+ amount: number
51
+ source: string
52
+ specifier: string
53
+ error?: string
54
+ phase?: string
55
+ reason?: string
56
+ }
57
+
58
+ // Only probabilistically capture 50% of relay captchas
59
+ const RELAY_CAPTCHA_SAMPLE_RATE = 0.5
60
+
61
+ type IdentityServiceConfig = {
62
+ identityServiceEndpoint: string
63
+ captcha?: Captcha
64
+ }
65
+
66
+ export class IdentityService {
67
+ identityServiceEndpoint: string
68
+ captcha: Captcha | undefined
69
+ web3Manager: Web3Manager | null
70
+
71
+ constructor({ identityServiceEndpoint, captcha }: IdentityServiceConfig) {
72
+ this.identityServiceEndpoint = identityServiceEndpoint
73
+ this.captcha = captcha
74
+ this.web3Manager = null
75
+ }
76
+
77
+ setWeb3Manager(web3Manager: Web3Manager) {
78
+ this.web3Manager = web3Manager
79
+ }
80
+
81
+ /* ------- HEDGEHOG AUTH ------- */
82
+
83
+ async getFn(params: {
84
+ lookupKey: string
85
+ username: string
86
+ }): Promise<{ iv: string; cipherText: string }> {
87
+ return await this._makeRequest({
88
+ url: '/authentication',
89
+ method: 'get',
90
+ params
91
+ })
92
+ }
93
+
94
+ async setAuthFn(obj: Data) {
95
+ return await this._makeRequest({
96
+ url: '/authentication',
97
+ method: 'post',
98
+ data: obj
99
+ })
100
+ }
101
+
102
+ async setUserFn(obj: Data & { token?: string }) {
103
+ if (this.captcha) {
104
+ try {
105
+ const token = await this.captcha.generate('identity/user')
106
+ obj.token = token
107
+ } catch (e) {
108
+ console.warn(
109
+ 'CAPTCHA (user) - Recaptcha failed to generate token in :',
110
+ e
111
+ )
112
+ }
113
+ }
114
+
115
+ return await this._makeRequest({
116
+ url: '/user',
117
+ method: 'post',
118
+ data: obj
119
+ })
120
+ }
121
+
122
+ async getUserEvents(walletAddress: string) {
123
+ return await this._makeRequest({
124
+ url: '/userEvents',
125
+ method: 'get',
126
+ params: { walletAddress }
127
+ })
128
+ }
129
+
130
+ async sendRecoveryInfo(obj: Record<string, unknown>) {
131
+ return await this._makeRequest({
132
+ url: '/recovery',
133
+ method: 'post',
134
+ data: obj
135
+ })
136
+ }
137
+
138
+ /**
139
+ * Check if an email address has been previously registered.
140
+ */
141
+ async checkIfEmailRegistered(email: string) {
142
+ return await this._makeRequest<{ exists: boolean }>({
143
+ url: '/users/check',
144
+ method: 'get',
145
+ params: {
146
+ email: email
147
+ }
148
+ })
149
+ }
150
+
151
+ async getUserEmail() {
152
+ const headers = await this._signData()
153
+ if (headers[AuthHeaders.MESSAGE] && headers[AuthHeaders.SIGNATURE]) {
154
+ return await this._makeRequest<{ email: string | undefined | null }>({
155
+ url: '/user/email',
156
+ method: 'get',
157
+ headers
158
+ })
159
+ } else {
160
+ throw new Error('Cannot get user email - user is not authenticated')
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Associates a user with a twitter uuid.
166
+ * @param uuid from the Twitter API
167
+ * @param userId
168
+ * @param handle User handle
169
+ */
170
+ async associateTwitterUser(uuid: string, userId: number, handle: string) {
171
+ return await this._makeRequest({
172
+ url: '/twitter/associate',
173
+ method: 'post',
174
+ data: {
175
+ uuid,
176
+ userId,
177
+ handle
178
+ }
179
+ })
180
+ }
181
+
182
+ /**
183
+ * Associates a user with an instagram uuid.
184
+ * @param uuid from the Instagram API
185
+ * @param userId
186
+ * @param handle
187
+ */
188
+ async associateInstagramUser(uuid: string, userId: number, handle: string) {
189
+ return await this._makeRequest({
190
+ url: '/instagram/associate',
191
+ method: 'post',
192
+ data: {
193
+ uuid,
194
+ userId,
195
+ handle
196
+ }
197
+ })
198
+ }
199
+
200
+ /**
201
+ * Logs a track listen for a given user id.
202
+ * @param trackId
203
+ * @param userId
204
+ * @param listenerAddress if logging this listen on behalf of another IP address, pass through here
205
+ * @param signatureData if logging this listen via a 3p service, a signed piece of data proving authenticity
206
+ */
207
+ async logTrackListen(
208
+ trackId: number,
209
+ userId: number,
210
+ listenerAddress: string,
211
+ signatureData?: { signature: string; timestamp: string },
212
+ solanaListen = false
213
+ ) {
214
+ const data: {
215
+ userId: number
216
+ solanaListen: boolean
217
+ signature?: string
218
+ timestamp?: string
219
+ } = { userId, solanaListen }
220
+ if (signatureData) {
221
+ data.signature = signatureData.signature
222
+ data.timestamp = signatureData.timestamp
223
+ }
224
+ const request: AxiosRequestConfig = {
225
+ url: `/tracks/${trackId}/listen`,
226
+ method: 'post',
227
+ data
228
+ }
229
+
230
+ if (listenerAddress) {
231
+ request.headers = {
232
+ 'x-forwarded-for': listenerAddress
233
+ }
234
+ }
235
+ return await this._makeRequest(request)
236
+ }
237
+
238
+ /**
239
+ * Return listen history tracks for a given user id.
240
+ * @param userId - User ID
241
+ * @param limit - max # of items to return
242
+ * @param offset - offset into list to return from (for pagination)
243
+ */
244
+ async getListenHistoryTracks(userId: number, limit = 100, offset = 0) {
245
+ const req: AxiosRequestConfig = {
246
+ method: 'get',
247
+ url: '/tracks/history',
248
+ params: { userId, limit, offset }
249
+ }
250
+ return await this._makeRequest(req)
251
+ }
252
+
253
+ /**
254
+ * Looks up a Twitter account by handle.
255
+ * @returns twitter API response.
256
+ */
257
+ async lookupTwitterHandle(handle: string) {
258
+ if (handle) {
259
+ return await this._makeRequest({
260
+ url: '/twitter/handle_lookup',
261
+ method: 'get',
262
+ params: { handle: handle }
263
+ })
264
+ } else {
265
+ throw new Error('No handle passed into function lookupTwitterHandle')
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Gets tracks trending on Audius.
271
+ * @param timeFrame one of day, week, month, or year
272
+ * @param idsArray track ids
273
+ * @param limit
274
+ * @param offset
275
+ */
276
+ async getTrendingTracks(
277
+ timeFrame: string | null = null,
278
+ idsArray: number[] | null = null,
279
+ limit: number | null = null,
280
+ offset: number | null = null
281
+ ) {
282
+ let queryUrl = '/tracks/trending/'
283
+
284
+ if (timeFrame != null) {
285
+ switch (timeFrame) {
286
+ case 'day':
287
+ case 'week':
288
+ case 'month':
289
+ case 'year':
290
+ break
291
+ default:
292
+ throw new Error('Invalid timeFrame value provided')
293
+ }
294
+ queryUrl += timeFrame
295
+ }
296
+
297
+ const queryParams: { id?: number[]; limit?: number; offset?: number } = {}
298
+ if (idsArray !== null) {
299
+ queryParams.id = idsArray
300
+ }
301
+
302
+ if (limit !== null) {
303
+ queryParams.limit = limit
304
+ }
305
+
306
+ if (offset !== null) {
307
+ queryParams.offset = offset
308
+ }
309
+
310
+ return await this._makeRequest<{
311
+ listenCounts: Array<{ trackId: number; listens: number }>
312
+ }>({
313
+ url: queryUrl,
314
+ method: 'get',
315
+ params: queryParams
316
+ })
317
+ }
318
+
319
+ /**
320
+ * Gets listens for tracks bucketted by timeFrame.
321
+ * @param timeFrame one of day, week, month, or year
322
+ * @param idsArray track ids
323
+ * @param startTime parseable by Date.parse
324
+ * @param endTime parseable by Date.parse
325
+ * @param limit
326
+ * @param offset
327
+ */
328
+ async getTrackListens(
329
+ timeFrame: TimeFrame | null = null,
330
+ idsArray: number[] | null = null,
331
+ startTime: string | null = null,
332
+ endTime: string | null = null,
333
+ limit: number | null = null,
334
+ offset: number | null = null
335
+ ): Promise<{
336
+ bucket: Array<{ trackId: number; date: string; listens: number }>
337
+ }> {
338
+ const req = getTrackListens(
339
+ timeFrame,
340
+ idsArray,
341
+ startTime,
342
+ endTime,
343
+ limit,
344
+ offset
345
+ )
346
+ return await this._makeRequest(req)
347
+ }
348
+
349
+ async createUserRecord(email: string, walletAddress: string) {
350
+ return await this._makeRequest({
351
+ url: '/user',
352
+ method: 'post',
353
+ data: {
354
+ username: email,
355
+ walletAddress
356
+ }
357
+ })
358
+ }
359
+
360
+ async relay(
361
+ contractRegistryKey: string | null | undefined,
362
+ contractAddress: string | null | undefined,
363
+ senderAddress: string,
364
+ encodedABI: string,
365
+ gasLimit: number
366
+ ): Promise<{ receipt: TransactionReceipt }> {
367
+ const shouldCaptcha = Math.random() < RELAY_CAPTCHA_SAMPLE_RATE
368
+ let token
369
+ if (this.captcha && shouldCaptcha) {
370
+ try {
371
+ token = await this.captcha.generate('identity/relay')
372
+ } catch (e) {
373
+ console.warn('CAPTCHA (relay) - Recaptcha failed to generate token:', e)
374
+ }
375
+ }
376
+
377
+ return await this._makeRequest({
378
+ url: '/relay',
379
+ method: 'post',
380
+ data: {
381
+ contractRegistryKey,
382
+ contractAddress,
383
+ senderAddress,
384
+ encodedABI,
385
+ gasLimit,
386
+ token
387
+ }
388
+ })
389
+ }
390
+
391
+ async ethRelay(
392
+ contractAddress: string,
393
+ senderAddress: Wallet | string,
394
+ encodedABI: string,
395
+ gasLimit: string
396
+ ): Promise<RelayTransaction> {
397
+ return await this._makeRequest({
398
+ url: '/eth_relay',
399
+ method: 'post',
400
+ data: {
401
+ contractAddress,
402
+ senderAddress,
403
+ encodedABI,
404
+ gasLimit
405
+ }
406
+ })
407
+ }
408
+
409
+ async wormholeRelay({
410
+ senderAddress,
411
+ permit,
412
+ transferTokens
413
+ }: {
414
+ senderAddress: string
415
+ permit: string
416
+ transferTokens: string[]
417
+ }) {
418
+ return await this._makeRequest({
419
+ url: '/wormhole_relay',
420
+ method: 'post',
421
+ data: {
422
+ senderAddress,
423
+ permit,
424
+ transferTokens
425
+ }
426
+ })
427
+ }
428
+
429
+ /**
430
+ * Gets the correct wallet that will relay a txn for `senderAddress`
431
+ * @param senderAddress wallet
432
+ */
433
+ async getEthRelayer(senderAddress: string) {
434
+ return await this._makeRequest({
435
+ url: '/eth_relayer',
436
+ method: 'get',
437
+ params: {
438
+ wallet: senderAddress
439
+ }
440
+ })
441
+ }
442
+
443
+ async getRandomFeePayer() {
444
+ return await this._makeRequest({
445
+ url: '/solana/random_fee_payer',
446
+ method: 'get',
447
+ headers: {
448
+ 'Content-Type': 'application/json'
449
+ }
450
+ })
451
+ }
452
+
453
+ // Relays tx data through the solana relay endpoint
454
+ async solanaRelay(transactionData: TransactionData) {
455
+ const headers = await this._signData()
456
+
457
+ return await this._makeRequest({
458
+ url: '/solana/relay',
459
+ method: 'post',
460
+ data: transactionData,
461
+ headers
462
+ })
463
+ }
464
+
465
+ async solanaRelayRaw(transactionData: TransactionData) {
466
+ return await this._makeRequest({
467
+ url: '/solana/relay/raw',
468
+ method: 'post',
469
+ data: transactionData
470
+ })
471
+ }
472
+
473
+ async getMinimumDelegationAmount(wallet: string) {
474
+ return await this._makeRequest({
475
+ url: `/protocol/${wallet}/delegation/minimum`,
476
+ method: 'get'
477
+ })
478
+ }
479
+
480
+ async updateMinimumDelegationAmount(
481
+ wallet: string,
482
+ minimumDelegationAmount: number,
483
+ signedData: AxiosRequestConfig['headers']
484
+ ) {
485
+ return await this._makeRequest({
486
+ url: `/protocol/${wallet}/delegation/minimum`,
487
+ method: 'post',
488
+ headers: signedData,
489
+ data: { minimumDelegationAmount }
490
+ })
491
+ }
492
+
493
+ /**
494
+ * Sends an attestation result to identity.
495
+ *
496
+ */
497
+ async sendAttestationResult(data: AttestationResult) {
498
+ return await this._makeRequest({
499
+ url: '/rewards/attestation_result',
500
+ method: 'post',
501
+ data
502
+ })
503
+ }
504
+
505
+ /* ------- INTERNAL FUNCTIONS ------- */
506
+
507
+ async _makeRequest<T = unknown>(axiosRequestObj: AxiosRequestConfig) {
508
+ axiosRequestObj.baseURL = this.identityServiceEndpoint
509
+
510
+ const requestId = uuid()
511
+ axiosRequestObj.headers = {
512
+ ...(axiosRequestObj.headers || {}),
513
+ 'X-Request-ID': requestId
514
+ }
515
+
516
+ // Axios throws for non-200 responses
517
+ try {
518
+ const resp: AxiosResponse<T> = await axios(axiosRequestObj)
519
+ if (!resp.data) {
520
+ throw new Error(
521
+ `Identity response missing data field for url: ${axiosRequestObj.url}, req-id: ${requestId}`
522
+ )
523
+ }
524
+ return resp.data
525
+ } catch (e) {
526
+ const error = e as AxiosError
527
+ if (error.response?.data?.error) {
528
+ console.error(
529
+ `Server returned error for requestId ${requestId}: [${error.response.status.toString()}] ${
530
+ error.response.data.error
531
+ }`
532
+ )
533
+ }
534
+ throw error
535
+ }
536
+ }
537
+
538
+ async _signData() {
539
+ if (this.web3Manager) {
540
+ const unixTs = Math.round(new Date().getTime() / 1000) // current unix timestamp (sec)
541
+ const message = `Click sign to authenticate with identity service: ${unixTs}`
542
+ const signature = await this.web3Manager?.sign(message)
543
+ return {
544
+ [AuthHeaders.MESSAGE]: message,
545
+ [AuthHeaders.SIGNATURE]: signature
546
+ }
547
+ } else {
548
+ return {}
549
+ }
550
+ }
551
+ }
@@ -0,0 +1 @@
1
+ export * from './IdentityService'
@@ -0,0 +1,65 @@
1
+ import type { AxiosRequestConfig } from 'axios'
2
+
3
+ export type TimeFrame = 'day' | 'week' | 'month' | 'year' | 'millennium'
4
+
5
+ type QueryParams = {
6
+ id?: number[]
7
+ limit?: number
8
+ offset?: number
9
+ start?: string
10
+ end?: string
11
+ }
12
+
13
+ export const getTrackListens = (
14
+ timeFrame: TimeFrame | null = null,
15
+ idsArray: number[] | null = null,
16
+ startTime: string | null = null,
17
+ endTime: string | null = null,
18
+ limit: number | null = null,
19
+ offset: number | null = null
20
+ ) => {
21
+ let queryUrl = 'tracks/listens/'
22
+
23
+ if (timeFrame != null) {
24
+ switch (timeFrame) {
25
+ case 'day':
26
+ case 'week':
27
+ case 'month':
28
+ case 'year':
29
+ case 'millennium':
30
+ break
31
+ default:
32
+ throw new Error('Invalid timeFrame value provided')
33
+ }
34
+ queryUrl += timeFrame
35
+ }
36
+
37
+ const queryParams: QueryParams = {}
38
+
39
+ if (idsArray !== null) {
40
+ queryParams.id = idsArray
41
+ }
42
+
43
+ if (limit !== null) {
44
+ queryParams.limit = limit
45
+ }
46
+
47
+ if (offset !== null) {
48
+ queryParams.offset = offset
49
+ }
50
+
51
+ if (startTime != null) {
52
+ queryParams.start = startTime
53
+ }
54
+
55
+ if (endTime != null) {
56
+ queryParams.end = endTime
57
+ }
58
+
59
+ const req: AxiosRequestConfig = {
60
+ url: queryUrl,
61
+ method: 'get',
62
+ params: queryParams
63
+ }
64
+ return req
65
+ }