@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.
- package/.eslintrc +38 -0
- package/.prettierrc.js +1 -0
- package/.python-version +1 -0
- package/Dockerfile +15 -0
- package/README.md +3 -0
- package/babel.config.js +3 -0
- package/data-contracts/ABIs/AdminUpgradeabilityProxy.json +132 -0
- package/data-contracts/ABIs/BaseAdminUpgradeabilityProxy.json +113 -0
- package/data-contracts/ABIs/BaseUpgradeabilityProxy.json +22 -0
- package/data-contracts/ABIs/DiscoveryProviderFactory.json +189 -0
- package/data-contracts/ABIs/DiscoveryProviderFactoryInterface.json +61 -0
- package/data-contracts/ABIs/DiscoveryProviderStorage.json +205 -0
- package/data-contracts/ABIs/DiscoveryProviderStorageInterface.json +65 -0
- package/data-contracts/ABIs/ECDSA.json +4 -0
- package/data-contracts/ABIs/IPLDBlacklistFactory.json +168 -0
- package/data-contracts/ABIs/Initializable.json +4 -0
- package/data-contracts/ABIs/Migrations.json +67 -0
- package/data-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
- package/data-contracts/ABIs/Ownable.json +79 -0
- package/data-contracts/ABIs/PlaylistFactory.json +669 -0
- package/data-contracts/ABIs/PlaylistFactoryInterface.json +42 -0
- package/data-contracts/ABIs/PlaylistStorage.json +250 -0
- package/data-contracts/ABIs/PlaylistStorageInterface.json +129 -0
- package/data-contracts/ABIs/Proxy.json +10 -0
- package/data-contracts/ABIs/Registry.json +240 -0
- package/data-contracts/ABIs/RegistryContract.json +102 -0
- package/data-contracts/ABIs/RegistryContractInterface.json +28 -0
- package/data-contracts/ABIs/RegistryInterface.json +66 -0
- package/data-contracts/ABIs/SigningLogic.json +43 -0
- package/data-contracts/ABIs/SigningLogicInitializable.json +46 -0
- package/data-contracts/ABIs/SocialFeatureFactory.json +460 -0
- package/data-contracts/ABIs/SocialFeatureStorage.json +225 -0
- package/data-contracts/ABIs/SocialFeatureStorageInterface.json +123 -0
- package/data-contracts/ABIs/TestContract.json +135 -0
- package/data-contracts/ABIs/TestContractInterface.json +19 -0
- package/data-contracts/ABIs/TestContractWithStorage.json +165 -0
- package/data-contracts/ABIs/TestContractWithStorageInterface.json +24 -0
- package/data-contracts/ABIs/TestStorage.json +144 -0
- package/data-contracts/ABIs/TestStorageInterface.json +42 -0
- package/data-contracts/ABIs/TestUserReplicaSetManager.json +432 -0
- package/data-contracts/ABIs/TrackFactory.json +391 -0
- package/data-contracts/ABIs/TrackFactoryInterface.json +73 -0
- package/data-contracts/ABIs/TrackStorage.json +223 -0
- package/data-contracts/ABIs/TrackStorageInterface.json +121 -0
- package/data-contracts/ABIs/UpgradeabilityProxy.json +37 -0
- package/data-contracts/ABIs/UserFactory.json +657 -0
- package/data-contracts/ABIs/UserFactoryInterface.json +65 -0
- package/data-contracts/ABIs/UserLibraryFactory.json +334 -0
- package/data-contracts/ABIs/UserReplicaSetManager.json +418 -0
- package/data-contracts/ABIs/UserStorage.json +233 -0
- package/data-contracts/ABIs/UserStorageInterface.json +93 -0
- package/data-contracts/signatureSchemas.ts +1236 -0
- package/dist/core.d.ts +446 -0
- package/dist/core.js +769 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +689 -0
- package/dist/index.js +72850 -0
- package/dist/index.js.map +1 -0
- package/eth-contracts/ABIs/Address.json +4 -0
- package/eth-contracts/ABIs/AudiusAdminUpgradeabilityProxy.json +105 -0
- package/eth-contracts/ABIs/AudiusClaimDistributor.json +4968 -0
- package/eth-contracts/ABIs/AudiusToken.json +724 -0
- package/eth-contracts/ABIs/BaseUpgradeabilityProxy.json +23 -0
- package/eth-contracts/ABIs/Checkpointing.json +4 -0
- package/eth-contracts/ABIs/ClaimsManager.json +539 -0
- package/eth-contracts/ABIs/Context.json +11 -0
- package/eth-contracts/ABIs/DelegateManager.json +989 -0
- package/eth-contracts/ABIs/DelegateManagerV2.json +1049 -0
- package/eth-contracts/ABIs/DelegateManagerV2Bad.json +1049 -0
- package/eth-contracts/ABIs/ERC20.json +252 -0
- package/eth-contracts/ABIs/ERC20Burnable.json +287 -0
- package/eth-contracts/ABIs/ERC20Detailed.json +270 -0
- package/eth-contracts/ABIs/ERC20Mintable.json +364 -0
- package/eth-contracts/ABIs/ERC20Pausable.json +397 -0
- package/eth-contracts/ABIs/EthRewardsManager.json +174 -0
- package/eth-contracts/ABIs/Governance.json +938 -0
- package/eth-contracts/ABIs/GovernanceUpgraded.json +953 -0
- package/eth-contracts/ABIs/GovernanceV2.json +938 -0
- package/eth-contracts/ABIs/IERC20.json +200 -0
- package/eth-contracts/ABIs/Initializable.json +4 -0
- package/eth-contracts/ABIs/InitializableV2.json +14 -0
- package/eth-contracts/ABIs/Migrations.json +71 -0
- package/eth-contracts/ABIs/MinterRole.json +91 -0
- package/eth-contracts/ABIs/MockAccount.json +62 -0
- package/eth-contracts/ABIs/MockDelegateManager.json +55 -0
- package/eth-contracts/ABIs/MockStakingCaller.json +259 -0
- package/eth-contracts/ABIs/MockWormhole.json +106 -0
- package/eth-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
- package/eth-contracts/ABIs/Ownable.json +93 -0
- package/eth-contracts/ABIs/Pausable.json +150 -0
- package/eth-contracts/ABIs/PauserRole.json +91 -0
- package/eth-contracts/ABIs/Proxy.json +10 -0
- package/eth-contracts/ABIs/Registry.json +288 -0
- package/eth-contracts/ABIs/Roles.json +4 -0
- package/eth-contracts/ABIs/SafeERC20.json +4 -0
- package/eth-contracts/ABIs/SafeMath.json +4 -0
- package/eth-contracts/ABIs/ServiceProviderFactory.json +1153 -0
- package/eth-contracts/ABIs/ServiceTypeManager.json +337 -0
- package/eth-contracts/ABIs/Staking.json +555 -0
- package/eth-contracts/ABIs/StakingUpgraded.json +570 -0
- package/eth-contracts/ABIs/TestContract.json +44 -0
- package/eth-contracts/ABIs/TrustedNotifierManager.json +265 -0
- package/eth-contracts/ABIs/Uint256Helpers.json +4 -0
- package/eth-contracts/ABIs/UpgradeabilityProxy.json +40 -0
- package/eth-contracts/ABIs/Wormhole.json +45 -0
- package/eth-contracts/ABIs/WormholeClient.json +155 -0
- package/examples/file.mp3 +0 -0
- package/examples/initAudiusLibs.js +86 -0
- package/examples/initializeVersions.js +95 -0
- package/examples/pic.jpg +0 -0
- package/initScripts/configureLocalDiscProv.js +167 -0
- package/initScripts/helpers/claim.js +43 -0
- package/initScripts/helpers/distributeTokens.js +24 -0
- package/initScripts/helpers/spRegistration.js +138 -0
- package/initScripts/helpers/utils.js +34 -0
- package/initScripts/helpers/version.js +93 -0
- package/initScripts/local.js +617 -0
- package/initScripts/mainnet.js +131 -0
- package/initScripts/manageProdRelayerWallets.js +191 -0
- package/package.json +125 -0
- package/rollup.config.js +164 -0
- package/scripts/AudiusClaimDistributor.json +4968 -0
- package/scripts/Wormhole.json +155 -0
- package/scripts/addCIDToIpldBlacklist.js +124 -0
- package/scripts/circleci-test.sh +53 -0
- package/scripts/communityRewards/transferCommunityRewardsToSolana.js +222 -0
- package/scripts/ipfs.sh +58 -0
- package/scripts/migrate_contracts.sh +25 -0
- package/scripts/reset.sh +65 -0
- package/scripts/test.sh +77 -0
- package/src/api/account.js +670 -0
- package/src/api/base.js +122 -0
- package/src/api/file.js +168 -0
- package/src/api/playlist.js +328 -0
- package/src/api/rewards.d.ts +4 -0
- package/src/api/rewards.js +682 -0
- package/src/api/serviceProvider.js +154 -0
- package/src/api/track.js +604 -0
- package/src/api/user.js +888 -0
- package/src/api/user.test.js +172 -0
- package/src/constants.ts +7 -0
- package/src/core.ts +3 -0
- package/src/index.js +6 -0
- package/src/libs.d.ts +3 -0
- package/src/libs.js +619 -0
- package/src/sanityChecks/addSecondaries.js +40 -0
- package/src/sanityChecks/assignReplicaSetIfNecessary.js +10 -0
- package/src/sanityChecks/index.d.ts +9 -0
- package/src/sanityChecks/index.js +31 -0
- package/src/sanityChecks/isCreator.js +73 -0
- package/src/sanityChecks/needsRecoveryEmail.js +20 -0
- package/src/sanityChecks/rolloverNodes.js +74 -0
- package/src/sanityChecks/sanitizeNodes.js +24 -0
- package/src/sanityChecks/syncNodes.js +28 -0
- package/src/sdk/constants.ts +10 -0
- package/src/sdk/index.ts +1 -0
- package/src/sdk/oauth/Oauth.ts +265 -0
- package/src/sdk/oauth/index.ts +1 -0
- package/src/sdk/sdk.ts +102 -0
- package/src/service-selection/ServiceSelection.test.ts +320 -0
- package/src/service-selection/ServiceSelection.ts +460 -0
- package/src/service-selection/constants.ts +14 -0
- package/src/service-selection/index.ts +1 -0
- package/src/services/ABIDecoder/AudiusABIDecoder.ts +71 -0
- package/src/services/ABIDecoder/index.ts +1 -0
- package/src/services/comstock/Comstock.ts +39 -0
- package/src/services/comstock/index.ts +1 -0
- package/src/services/contracts/ContractClient.ts +227 -0
- package/src/services/contracts/GovernedContractClient.ts +53 -0
- package/src/services/contracts/ProviderSelection.ts +42 -0
- package/src/services/creatorNode/CreatorNode.ts +1065 -0
- package/src/services/creatorNode/CreatorNodeSelection.test.ts +997 -0
- package/src/services/creatorNode/CreatorNodeSelection.ts +488 -0
- package/src/services/creatorNode/constants.ts +10 -0
- package/src/services/creatorNode/index.ts +2 -0
- package/src/services/dataContracts/AudiusContracts.ts +234 -0
- package/src/services/dataContracts/IPLDBlacklistFactoryClient.ts +73 -0
- package/src/services/dataContracts/PlaylistFactoryClient.ts +370 -0
- package/src/services/dataContracts/RegistryClient.ts +95 -0
- package/src/services/dataContracts/SocialFeatureFactoryClient.ts +196 -0
- package/src/services/dataContracts/TrackFactoryClient.ts +131 -0
- package/src/services/dataContracts/UserFactoryClient.ts +351 -0
- package/src/services/dataContracts/UserLibraryFactoryClient.ts +115 -0
- package/src/services/dataContracts/UserReplicaSetManagerClient.ts +206 -0
- package/src/services/dataContracts/index.ts +1 -0
- package/src/services/discoveryProvider/DiscoveryProvider.ts +1168 -0
- package/src/services/discoveryProvider/DiscoveryProviderSelection.test.ts +536 -0
- package/src/services/discoveryProvider/DiscoveryProviderSelection.ts +383 -0
- package/src/services/discoveryProvider/constants.ts +13 -0
- package/src/services/discoveryProvider/index.ts +1 -0
- package/src/services/discoveryProvider/requests.ts +629 -0
- package/src/services/ethContracts/AudiusTokenClient.ts +163 -0
- package/src/services/ethContracts/ClaimDistributionClient.ts +45 -0
- package/src/services/ethContracts/ClaimsManagerClient.ts +102 -0
- package/src/services/ethContracts/DelegateManagerClient.ts +480 -0
- package/src/services/ethContracts/EthContracts.ts +359 -0
- package/src/services/ethContracts/EthRewardsManagerClient.ts +33 -0
- package/src/services/ethContracts/GovernanceClient.ts +451 -0
- package/src/services/ethContracts/RegistryClient.ts +33 -0
- package/src/services/ethContracts/ServiceProviderFactoryClient.ts +691 -0
- package/src/services/ethContracts/ServiceTypeManagerClient.ts +112 -0
- package/src/services/ethContracts/StakingProxyClient.ts +97 -0
- package/src/services/ethContracts/TrustedNotifierManagerClient.ts +101 -0
- package/src/services/ethContracts/WormholeClient.ts +97 -0
- package/src/services/ethContracts/index.ts +1 -0
- package/src/services/ethWeb3Manager/EthWeb3Manager.ts +239 -0
- package/src/services/ethWeb3Manager/index.ts +1 -0
- package/src/services/hedgehog/Hedgehog.ts +96 -0
- package/src/services/hedgehog/index.ts +1 -0
- package/src/services/identity/IdentityService.ts +551 -0
- package/src/services/identity/index.ts +1 -0
- package/src/services/identity/requests.ts +65 -0
- package/src/services/schemaValidator/SchemaValidator.ts +105 -0
- package/src/services/schemaValidator/index.ts +1 -0
- package/src/services/schemaValidator/schemas/trackSchema.json +267 -0
- package/src/services/schemaValidator/schemas/userSchema.json +230 -0
- package/src/services/solanaAudiusData/errors.ts +20 -0
- package/src/services/solanaAudiusData/index.ts +1189 -0
- package/src/services/solanaWeb3Manager/errors.js +101 -0
- package/src/services/solanaWeb3Manager/index.d.ts +46 -0
- package/src/services/solanaWeb3Manager/index.js +655 -0
- package/src/services/solanaWeb3Manager/padBNToUint8Array.ts +7 -0
- package/src/services/solanaWeb3Manager/rewards.js +941 -0
- package/src/services/solanaWeb3Manager/rewardsAttester.ts +1093 -0
- package/src/services/solanaWeb3Manager/tokenAccount.js +149 -0
- package/src/services/solanaWeb3Manager/transactionHandler.js +345 -0
- package/src/services/solanaWeb3Manager/transfer.js +272 -0
- package/src/services/solanaWeb3Manager/userBank.js +160 -0
- package/src/services/solanaWeb3Manager/utils.d.ts +31 -0
- package/src/services/solanaWeb3Manager/utils.js +163 -0
- package/src/services/solanaWeb3Manager/wAudio.js +28 -0
- package/src/services/solanaWeb3Manager/wAudio.test.js +30 -0
- package/src/services/web3Manager/Web3Config.ts +14 -0
- package/src/services/web3Manager/Web3Manager.ts +360 -0
- package/src/services/web3Manager/XMLHttpRequest.ts +11 -0
- package/src/services/web3Manager/index.ts +2 -0
- package/src/services/wormhole/index.js +424 -0
- package/src/types.ts +8 -0
- package/src/userStateManager.ts +53 -0
- package/src/utils/apiSigning.ts +51 -0
- package/src/utils/captcha.ts +97 -0
- package/src/utils/estimateGas.ts +64 -0
- package/src/utils/fileHasher.ts +278 -0
- package/src/utils/importContractABI.d.ts +9 -0
- package/src/utils/importContractABI.js +19 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/multiProvider.ts +72 -0
- package/src/utils/network.test.ts +127 -0
- package/src/utils/network.ts +308 -0
- package/src/utils/promiseFight.test.ts +87 -0
- package/src/utils/promiseFight.ts +36 -0
- package/src/utils/signatures.ts +139 -0
- package/src/utils/types.ts +34 -0
- package/src/utils/utils.test.ts +36 -0
- package/src/utils/utils.ts +235 -0
- package/src/utils/uuid.ts +14 -0
- package/src/web3.d.ts +9 -0
- package/src/web3.js +8 -0
- package/tests/assets/static_image.png +0 -0
- package/tests/assets/static_text.txt +1 -0
- package/tests/audiusTokenClientTest.js +37 -0
- package/tests/creatorNodeTest.js +19 -0
- package/tests/fileHasherTest.js +125 -0
- package/tests/governanceTest.js +382 -0
- package/tests/helpers.js +105 -0
- package/tests/index.js +14 -0
- package/tests/playlistClientTest.js +157 -0
- package/tests/providerSelectionTest.js +241 -0
- package/tests/registryClientTest.js +19 -0
- package/tests/rewardsAttesterTest.js +373 -0
- package/tests/serviceTypeManagerClientTest.js +33 -0
- package/tests/socialFeatureClientTest.js +79 -0
- package/tests/stakingTest.js +302 -0
- package/tests/trackClientTest.js +86 -0
- package/tests/userClientTest.js +121 -0
- package/tsconfig.json +10 -0
- package/types/@audius-hedgehog/index.d.ts +39 -0
- 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,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
|
+
})
|