@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,670 @@
|
|
|
1
|
+
const { Base, Services } = require('./base')
|
|
2
|
+
const { CreatorNode } = require('../services/creatorNode')
|
|
3
|
+
const { Utils } = require('../utils')
|
|
4
|
+
const { AuthHeaders } = require('../constants')
|
|
5
|
+
const {
|
|
6
|
+
getPermitDigest, sign
|
|
7
|
+
} = require('../utils/signatures')
|
|
8
|
+
const { PublicKey } = require('@solana/web3.js')
|
|
9
|
+
const { BN } = require('@project-serum/anchor')
|
|
10
|
+
|
|
11
|
+
class Account extends Base {
|
|
12
|
+
constructor (userApi, ...services) {
|
|
13
|
+
super(...services)
|
|
14
|
+
|
|
15
|
+
this.User = userApi
|
|
16
|
+
|
|
17
|
+
this.getCurrentUser = this.getCurrentUser.bind(this)
|
|
18
|
+
this.login = this.login.bind(this)
|
|
19
|
+
this.logout = this.logout.bind(this)
|
|
20
|
+
this.signUp = this.signUp.bind(this)
|
|
21
|
+
this.generateRecoveryLink = this.generateRecoveryLink.bind(this)
|
|
22
|
+
this.confirmCredentials = this.confirmCredentials.bind(this)
|
|
23
|
+
this.changePassword = this.changePassword.bind(this)
|
|
24
|
+
this.resetPassword = this.resetPassword.bind(this)
|
|
25
|
+
this.checkIfEmailRegistered = this.checkIfEmailRegistered.bind(this)
|
|
26
|
+
this.getUserEmail = this.getUserEmail.bind(this)
|
|
27
|
+
this.associateTwitterUser = this.associateTwitterUser.bind(this)
|
|
28
|
+
this.associateInstagramUser = this.associateInstagramUser.bind(this)
|
|
29
|
+
this.handleIsValid = this.handleIsValid.bind(this)
|
|
30
|
+
this.lookupTwitterHandle = this.lookupTwitterHandle.bind(this)
|
|
31
|
+
this.updateCreatorNodeEndpoint = this.updateCreatorNodeEndpoint.bind(this)
|
|
32
|
+
this.searchFull = this.searchFull.bind(this)
|
|
33
|
+
this.searchAutocomplete = this.searchAutocomplete.bind(this)
|
|
34
|
+
this.searchTags = this.searchTags.bind(this)
|
|
35
|
+
this.sendTokensFromEthToSol = this.sendTokensFromEthToSol.bind(this)
|
|
36
|
+
this.sendTokensFromSolToEth = this.sendTokensFromSolToEth.bind(this)
|
|
37
|
+
this.getUserAccountOnSolana = this.getUserAccountOnSolana.bind(this)
|
|
38
|
+
this.userHasClaimedSolAccount = this.userHasClaimedSolAccount.bind(this)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Fetches the user metadata for the current account
|
|
43
|
+
* @return {Object} user metadata
|
|
44
|
+
*/
|
|
45
|
+
getCurrentUser () {
|
|
46
|
+
return this.userStateManager.getCurrentUser()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Logs a user into Audius
|
|
51
|
+
* @param {string} email
|
|
52
|
+
* @param {string} password
|
|
53
|
+
*/
|
|
54
|
+
async login (email, password) {
|
|
55
|
+
const phases = {
|
|
56
|
+
FIND_WALLET: 'FIND_WALLET',
|
|
57
|
+
FIND_USER: 'FIND_USER'
|
|
58
|
+
}
|
|
59
|
+
let phase = ''
|
|
60
|
+
|
|
61
|
+
phase = phases.FIND_WALLET
|
|
62
|
+
if (!this.web3Manager.web3IsExternal()) {
|
|
63
|
+
this.REQUIRES(Services.HEDGEHOG)
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const ownerWallet = await this.hedgehog.login(email, password)
|
|
67
|
+
await this.web3Manager.setOwnerWallet(ownerWallet)
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return { error: e.message, phase }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
phase = phases.FIND_USER
|
|
74
|
+
const userAccount = await this.discoveryProvider.getUserAccount(this.web3Manager.getWalletAddress())
|
|
75
|
+
if (userAccount) {
|
|
76
|
+
this.userStateManager.setCurrentUser(userAccount)
|
|
77
|
+
const creatorNodeEndpoint = userAccount.creator_node_endpoint
|
|
78
|
+
if (creatorNodeEndpoint) {
|
|
79
|
+
this.creatorNode.setEndpoint(CreatorNode.getPrimary(creatorNodeEndpoint))
|
|
80
|
+
}
|
|
81
|
+
return { user: userAccount, error: false, phase }
|
|
82
|
+
}
|
|
83
|
+
return { error: 'No user found', phase }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Logs a user out of Audius
|
|
88
|
+
* Note: Actions will stop working at this point, but
|
|
89
|
+
* clients may wish to call window.location.reload()
|
|
90
|
+
* to show the user as logged out
|
|
91
|
+
*/
|
|
92
|
+
logout () {
|
|
93
|
+
if (!this.web3Manager.web3IsExternal()) {
|
|
94
|
+
this.REQUIRES(Services.HEDGEHOG)
|
|
95
|
+
this.hedgehog.logout()
|
|
96
|
+
this.userStateManager.clearUser()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Signs a user up for Audius
|
|
102
|
+
* @param {string} email
|
|
103
|
+
* @param {string} password
|
|
104
|
+
* @param {Object} metadata
|
|
105
|
+
* @param {?File} [profilePictureFile] an optional file to upload as the profile picture
|
|
106
|
+
* @param {?File} [coverPhotoFile] an optional file to upload as the cover phtoo
|
|
107
|
+
* @param {?boolean} [hasWallet]
|
|
108
|
+
* @param {?boolean} [host] The host url used for the recovery email
|
|
109
|
+
* @param {?boolean} [createWAudioUserBank] an optional flag to create the solana user bank account
|
|
110
|
+
* @param {?Function} [handleUserBankOutcomes] an optional callback to record user bank outcomes
|
|
111
|
+
* @param {?Object} [userBankOutcomes] an optional object with request, succes, and failure keys to record user bank outcomes
|
|
112
|
+
* @param {?string} [feePayerOverride] an optional string in case the client wants to switch between fee payers
|
|
113
|
+
* @param {?boolean} [generateRecoveryLink] an optional flag to skip generating recovery link for testing purposes
|
|
114
|
+
*/
|
|
115
|
+
async signUp (
|
|
116
|
+
email,
|
|
117
|
+
password,
|
|
118
|
+
metadata,
|
|
119
|
+
profilePictureFile = null,
|
|
120
|
+
coverPhotoFile = null,
|
|
121
|
+
hasWallet = false,
|
|
122
|
+
host = (typeof window !== 'undefined' && window.location.origin) || null,
|
|
123
|
+
handleUserBankOutcomes = () => {},
|
|
124
|
+
userBankOutcomes = {},
|
|
125
|
+
feePayerOverride = null,
|
|
126
|
+
generateRecoveryLink = true
|
|
127
|
+
) {
|
|
128
|
+
const phases = {
|
|
129
|
+
ADD_REPLICA_SET: 'ADD_REPLICA_SET',
|
|
130
|
+
CREATE_USER_RECORD: 'CREATE_USER_RECORD',
|
|
131
|
+
HEDGEHOG_SIGNUP: 'HEDGEHOG_SIGNUP',
|
|
132
|
+
SOLANA_USER_BANK_CREATION: 'SOLANA_USER_BANK_CREATION',
|
|
133
|
+
UPLOAD_PROFILE_IMAGES: 'UPLOAD_PROFILE_IMAGES',
|
|
134
|
+
ADD_USER: 'ADD_USER'
|
|
135
|
+
}
|
|
136
|
+
let phase = ''
|
|
137
|
+
let userId, blockHash, blockNumber
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
this.REQUIRES(Services.CREATOR_NODE, Services.IDENTITY_SERVICE)
|
|
141
|
+
|
|
142
|
+
if (this.web3Manager.web3IsExternal()) {
|
|
143
|
+
phase = phases.CREATE_USER_RECORD
|
|
144
|
+
await this.identityService.createUserRecord(email, this.web3Manager.getWalletAddress())
|
|
145
|
+
} else {
|
|
146
|
+
this.REQUIRES(Services.HEDGEHOG)
|
|
147
|
+
// If an owner wallet already exists, don't try to recreate it
|
|
148
|
+
if (!hasWallet) {
|
|
149
|
+
phase = phases.HEDGEHOG_SIGNUP
|
|
150
|
+
const ownerWallet = await this.hedgehog.signUp(email, password)
|
|
151
|
+
await this.web3Manager.setOwnerWallet(ownerWallet)
|
|
152
|
+
if (generateRecoveryLink) {
|
|
153
|
+
await this.generateRecoveryLink({ handle: metadata.handle, host })
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Create a wAudio user bank address.
|
|
159
|
+
// If userbank creation fails, we still proceed
|
|
160
|
+
// through signup
|
|
161
|
+
if (this.solanaWeb3Manager) {
|
|
162
|
+
phase = phases.SOLANA_USER_BANK_CREATION;
|
|
163
|
+
// Fire and forget createUserBank. In the case of failure, we will
|
|
164
|
+
// retry to create user banks in a later session before usage
|
|
165
|
+
(async () => {
|
|
166
|
+
try {
|
|
167
|
+
handleUserBankOutcomes(userBankOutcomes.Request)
|
|
168
|
+
const { error, errorCode } = await this.solanaWeb3Manager.createUserBank(feePayerOverride)
|
|
169
|
+
if (error || errorCode) {
|
|
170
|
+
console.error(
|
|
171
|
+
`Failed to create userbank, with err: ${error}, ${errorCode}`
|
|
172
|
+
)
|
|
173
|
+
handleUserBankOutcomes(userBankOutcomes.Failure, { error, errorCode })
|
|
174
|
+
} else {
|
|
175
|
+
console.log('Successfully created userbank!')
|
|
176
|
+
handleUserBankOutcomes('Create User Bank: Success')
|
|
177
|
+
}
|
|
178
|
+
} catch (err) {
|
|
179
|
+
console.error(`Got error creating userbank: ${err}, continuing...`)
|
|
180
|
+
handleUserBankOutcomes(userBankOutcomes.Failure, { error: err.toString() })
|
|
181
|
+
}
|
|
182
|
+
})()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Add user to chain
|
|
186
|
+
phase = phases.ADD_USER
|
|
187
|
+
const response = await this.User.addUser(metadata)
|
|
188
|
+
userId = response.userId
|
|
189
|
+
blockHash = response.blockHash
|
|
190
|
+
blockNumber = response.blockNumber
|
|
191
|
+
|
|
192
|
+
// Assign replica set to user, updates creator_node_endpoint on chain, and then update metadata object on content node + chain (in this order)
|
|
193
|
+
phase = phases.ADD_REPLICA_SET
|
|
194
|
+
metadata = await this.User.assignReplicaSet({ userId })
|
|
195
|
+
|
|
196
|
+
// Upload profile pic and cover photo to primary Content Node and sync across secondaries
|
|
197
|
+
phase = phases.UPLOAD_PROFILE_IMAGES
|
|
198
|
+
await this.User.uploadProfileImages(profilePictureFile, coverPhotoFile, metadata)
|
|
199
|
+
} catch (e) {
|
|
200
|
+
return { error: e.message, phase, errorStatus: e.response ? e.response.status : null }
|
|
201
|
+
}
|
|
202
|
+
return { blockHash, blockNumber, userId }
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Generates and sends a recovery email for a user
|
|
207
|
+
* @param {string} [handle] The user handle, defaults to the current user handle
|
|
208
|
+
* @param {string} [host] The host domain, defaults to window.location.origin
|
|
209
|
+
*/
|
|
210
|
+
async generateRecoveryLink ({ handle, host } = {}) {
|
|
211
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
212
|
+
try {
|
|
213
|
+
const recoveryInfo = await this.hedgehog.generateRecoveryInfo()
|
|
214
|
+
handle = handle || this.userStateManager.getCurrentUser().handle
|
|
215
|
+
|
|
216
|
+
const unixTs = Math.round((new Date()).getTime() / 1000) // current unix timestamp (sec)
|
|
217
|
+
const data = `Click sign to authenticate with identity service: ${unixTs}`
|
|
218
|
+
const signature = await this.web3Manager.sign(data)
|
|
219
|
+
|
|
220
|
+
const recoveryData = {
|
|
221
|
+
login: recoveryInfo.login,
|
|
222
|
+
host: host || recoveryInfo.host,
|
|
223
|
+
data,
|
|
224
|
+
signature,
|
|
225
|
+
handle
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
await this.identityService.sendRecoveryInfo(recoveryData)
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.error(e)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async resetPassword (email, newpassword) {
|
|
235
|
+
return this.hedgehog.resetPassword(email, newpassword)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async changePassword (email, newpassword, oldpassword) {
|
|
239
|
+
return this.hedgehog.changePassword(email, newpassword, oldpassword)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async confirmCredentials (email, password) {
|
|
243
|
+
return this.hedgehog.confirmCredentials(email, password)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check if an email address has been previously registered.
|
|
248
|
+
* @param {string} email
|
|
249
|
+
* @returns {{exists: boolean}}
|
|
250
|
+
*/
|
|
251
|
+
async checkIfEmailRegistered (email) {
|
|
252
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
253
|
+
return this.identityService.checkIfEmailRegistered(email)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get the current user's email address
|
|
258
|
+
* @returns {{email: string | undefined | null}}
|
|
259
|
+
*/
|
|
260
|
+
async getUserEmail () {
|
|
261
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
262
|
+
return this.identityService.getUserEmail()
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Associates a user with a twitter uuid.
|
|
267
|
+
* @param {string} uuid from the Twitter API
|
|
268
|
+
* @param {number} userId
|
|
269
|
+
* @param {string} handle
|
|
270
|
+
*/
|
|
271
|
+
async associateTwitterUser (uuid, userId, handle) {
|
|
272
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
273
|
+
return this.identityService.associateTwitterUser(uuid, userId, handle)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Associates a user with an instagram uuid.
|
|
278
|
+
* @param {string} uuid from the Instagram API
|
|
279
|
+
* @param {number} userId
|
|
280
|
+
* @param {string} handle
|
|
281
|
+
*/
|
|
282
|
+
async associateInstagramUser (uuid, userId, handle) {
|
|
283
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
284
|
+
return this.identityService.associateInstagramUser(uuid, userId, handle)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Checks if a requested handle is valid (unused).
|
|
289
|
+
* @param {string} handle
|
|
290
|
+
*/
|
|
291
|
+
async handleIsValid (handle) {
|
|
292
|
+
return this.contracts.UserFactoryClient.handleIsValid(handle)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Looks up a Twitter account by handle.
|
|
297
|
+
* @returns {Object} twitter API response.
|
|
298
|
+
*/
|
|
299
|
+
async lookupTwitterHandle (handle) {
|
|
300
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
301
|
+
return this.identityService.lookupTwitterHandle(handle)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Updates a user's creator node endpoint. Sets the connected creator node in the libs instance
|
|
306
|
+
* and updates the user's metadata blob.
|
|
307
|
+
* @param {string} url
|
|
308
|
+
*/
|
|
309
|
+
async updateCreatorNodeEndpoint (url) {
|
|
310
|
+
this.REQUIRES(Services.CREATOR_NODE)
|
|
311
|
+
|
|
312
|
+
const user = this.userStateManager.getCurrentUser()
|
|
313
|
+
if (user.is_creator) {
|
|
314
|
+
await this.creatorNode.setEndpoint(url)
|
|
315
|
+
// Only a creator will have a creator node endpoint
|
|
316
|
+
user.creator_node_endpoint = url
|
|
317
|
+
await this.User.updateCreator(user.user_id, user)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Perform a full-text search. Returns tracks, users, playlists, albums
|
|
323
|
+
* with optional user-specific results for each
|
|
324
|
+
* - user, track, and playlist objects have all same data as returned from standalone endpoints
|
|
325
|
+
* @param {string} text search query
|
|
326
|
+
* @param {string} kind 'tracks', 'users', 'playlists', 'albums', 'all'
|
|
327
|
+
* @param {number} limit max # of items to return per list (for pagination)
|
|
328
|
+
* @param {number} offset offset into list to return from (for pagination)
|
|
329
|
+
*/
|
|
330
|
+
async searchFull (text, kind, limit = 100, offset = 0) {
|
|
331
|
+
this.REQUIRES(Services.DISCOVERY_PROVIDER)
|
|
332
|
+
return this.discoveryProvider.searchFull(text, kind, limit, offset)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Perform a lighter-weight full-text search. Returns tracks, users, playlists, albums
|
|
337
|
+
* with optional user-specific results for each
|
|
338
|
+
* - user, track, and playlist objects have core data, and track & playlist objects
|
|
339
|
+
* also return user object
|
|
340
|
+
* @param {string} text search query
|
|
341
|
+
* @param {number} limit max # of items to return per list (for pagination)
|
|
342
|
+
* @param {number} offset offset into list to return from (for pagination)
|
|
343
|
+
*/
|
|
344
|
+
async searchAutocomplete (text, limit = 100, offset = 0) {
|
|
345
|
+
this.REQUIRES(Services.DISCOVERY_PROVIDER)
|
|
346
|
+
return this.discoveryProvider.searchAutocomplete(text, limit, offset)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Perform a tags-only search. Returns tracks with required tag and users
|
|
351
|
+
* that have used a tag greater than a specified number of times
|
|
352
|
+
* @param {string} text search query
|
|
353
|
+
* @param {number} user_tag_count min # of times a user must have used a tag to be returned
|
|
354
|
+
* @param {string} kind 'tracks', 'users', 'playlists', 'albums', 'all'
|
|
355
|
+
* @param {number} limit max # of items to return per list (for pagination)
|
|
356
|
+
* @param {number} offset offset into list to return from (for pagination)
|
|
357
|
+
*/
|
|
358
|
+
async searchTags (text, user_tag_count = 2, kind, limit = 100, offset = 0) {
|
|
359
|
+
this.REQUIRES(Services.DISCOVERY_PROVIDER)
|
|
360
|
+
return this.discoveryProvider.searchTags(text, user_tag_count, kind, limit, offset)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Check if the user has a distribution claim
|
|
365
|
+
* @param {number?} index The index of the claim to check (if known)
|
|
366
|
+
*/
|
|
367
|
+
async getHasClaimed (index) {
|
|
368
|
+
this.REQUIRES(Services.COMSTOCK)
|
|
369
|
+
if (index) {
|
|
370
|
+
return this.ethContracts.ClaimDistributionClient.isClaimed(index)
|
|
371
|
+
}
|
|
372
|
+
const userWallet = this.web3Manager.getWalletAddress()
|
|
373
|
+
const web3 = this.web3Manager.getWeb3()
|
|
374
|
+
const wallet = web3.utils.toChecksumAddress(userWallet)
|
|
375
|
+
const claim = await this.comstock.getComstock({ wallet })
|
|
376
|
+
return this.ethContracts.ClaimDistributionClient.isClaimed(claim.index)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get the distribution claim amount
|
|
381
|
+
*/
|
|
382
|
+
async getClaimDistributionAmount () {
|
|
383
|
+
this.REQUIRES(Services.COMSTOCK)
|
|
384
|
+
const userWallet = this.web3Manager.getWalletAddress()
|
|
385
|
+
const web3 = this.web3Manager.getWeb3()
|
|
386
|
+
const wallet = web3.utils.toChecksumAddress(userWallet)
|
|
387
|
+
const claimDistribution = await this.comstock.getComstock({ wallet })
|
|
388
|
+
const amount = Utils.toBN(claimDistribution.amount.replace('0x', ''), 16)
|
|
389
|
+
return amount
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Make the claim
|
|
394
|
+
* @param {number?} index The index of the claim to check
|
|
395
|
+
* @param {BN?} amount The amount to be claimed
|
|
396
|
+
* @param {Array<string>?} merkleProof The merkle proof for the claim
|
|
397
|
+
*/
|
|
398
|
+
async makeDistributionClaim (index, amount, merkleProof) {
|
|
399
|
+
this.REQUIRES(Services.COMSTOCK, Services.IDENTITY_SERVICE)
|
|
400
|
+
const userWallet = this.web3Manager.getWalletAddress()
|
|
401
|
+
const web3 = this.web3Manager.getWeb3()
|
|
402
|
+
const wallet = web3.utils.toChecksumAddress(userWallet)
|
|
403
|
+
if (index && amount && merkleProof) {
|
|
404
|
+
return this.ethContracts.ClaimDistributionClient.claim(
|
|
405
|
+
index,
|
|
406
|
+
userWallet,
|
|
407
|
+
amount,
|
|
408
|
+
merkleProof
|
|
409
|
+
)
|
|
410
|
+
}
|
|
411
|
+
const claim = await this.comstock.getComstock({ wallet })
|
|
412
|
+
return this.ethContracts.ClaimDistributionClient.claim(
|
|
413
|
+
claim.index,
|
|
414
|
+
userWallet,
|
|
415
|
+
claim.amount,
|
|
416
|
+
claim.proof
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Sends `amount` tokens to `recipientAddress`
|
|
422
|
+
*/
|
|
423
|
+
async permitAndSendTokens (recipientAddress, amount) {
|
|
424
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
425
|
+
const myWalletAddress = this.web3Manager.getWalletAddress()
|
|
426
|
+
const { selectedEthWallet } = await this.identityService.getEthRelayer(myWalletAddress)
|
|
427
|
+
await this.permitProxySendTokens(myWalletAddress, selectedEthWallet, amount)
|
|
428
|
+
await this.sendTokens(myWalletAddress, recipientAddress, selectedEthWallet, amount)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Sends Eth `amount` tokens to `solanaAccount` by way of the wormhole
|
|
433
|
+
* 1.) Permits the eth relay to proxy send tokens on behalf of the user
|
|
434
|
+
* 2.) Transfers the tokens on the eth side to the wormhole contract
|
|
435
|
+
* 3.) Gathers attestations from wormhole oracles and relizes the tokens on sol
|
|
436
|
+
*/
|
|
437
|
+
async sendTokensFromEthToSol (amount, solanaAccount) {
|
|
438
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
439
|
+
const phases = {
|
|
440
|
+
PERMIT_PROXY_SEND: 'PERMIT_PROXY_SEND',
|
|
441
|
+
TRANSFER_TOKENS: 'TRANSFER_TOKENS',
|
|
442
|
+
ATTEST_AND_COMPLETE_TRANSFER: 'ATTEST_AND_COMPLETE_TRANSFER'
|
|
443
|
+
}
|
|
444
|
+
let phase = phases.PERMIT_PROXY_SEND
|
|
445
|
+
const logs = [`Send tokens from eth to sol to ${solanaAccount} for ${amount.toString()}`]
|
|
446
|
+
try {
|
|
447
|
+
const myWalletAddress = this.web3Manager.getWalletAddress()
|
|
448
|
+
const wormholeAddress = this.ethContracts.WormholeClient.contractAddress
|
|
449
|
+
const { selectedEthWallet } = await this.identityService.getEthRelayer(myWalletAddress)
|
|
450
|
+
await this.permitProxySendTokens(myWalletAddress, wormholeAddress, amount)
|
|
451
|
+
|
|
452
|
+
logs.push('Completed permit proxy send tokens')
|
|
453
|
+
phase = phases.TRANSFER_TOKENS
|
|
454
|
+
const transferTokensTx = await this.wormholeClient.transferTokensToEthWormhole(
|
|
455
|
+
myWalletAddress, amount, solanaAccount, selectedEthWallet
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
const transferTransactionHash = transferTokensTx.txHash
|
|
459
|
+
logs.push(`Completed transfer tokens with tx ${transferTransactionHash}`)
|
|
460
|
+
phase = phases.ATTEST_AND_COMPLETE_TRANSFER
|
|
461
|
+
|
|
462
|
+
const response = await this.wormholeClient.attestAndCompleteTransferEthToSol(transferTransactionHash)
|
|
463
|
+
if (response.transactionSignature) {
|
|
464
|
+
logs.push(`Receive sol wrapped tokens in tx ${response.transactionSignature}`)
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
txSignature: response.transactionSignature,
|
|
468
|
+
phase: response.phase,
|
|
469
|
+
error: response.error || null,
|
|
470
|
+
logs: logs.concat(response.logs)
|
|
471
|
+
}
|
|
472
|
+
} catch (error) {
|
|
473
|
+
return {
|
|
474
|
+
error: error.message,
|
|
475
|
+
phase,
|
|
476
|
+
logs
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Sends Eth `amount` tokens to `solanaAccount` on the identity service
|
|
483
|
+
* by way of the wormhole.
|
|
484
|
+
*/
|
|
485
|
+
async proxySendTokensFromEthToSol (amount, solanaAccount) {
|
|
486
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
487
|
+
const myWalletAddress = this.web3Manager.getWalletAddress()
|
|
488
|
+
const wormholeAddress = this.ethContracts.WormholeClient.contractAddress
|
|
489
|
+
const { selectedEthWallet } = await this.identityService.getEthRelayer(myWalletAddress)
|
|
490
|
+
const permitMethod = await this.getPermitProxySendTokensMethod(myWalletAddress, wormholeAddress, amount)
|
|
491
|
+
const permit = await this.ethWeb3Manager.getRelayMethodParams(this.ethContracts.AudiusTokenClient.contractAddress, permitMethod, selectedEthWallet)
|
|
492
|
+
const transferTokensMethod = await this.wormholeClient.getTransferTokensToEthWormholeMethod(
|
|
493
|
+
|
|
494
|
+
myWalletAddress, amount, solanaAccount, selectedEthWallet
|
|
495
|
+
)
|
|
496
|
+
const transferTokens = await this.ethWeb3Manager.getRelayMethodParams(this.ethContracts.WormholeClient.contractAddress, transferTokensMethod, selectedEthWallet)
|
|
497
|
+
return this.identityService.wormholeRelay({
|
|
498
|
+
senderAddress: myWalletAddress,
|
|
499
|
+
permit,
|
|
500
|
+
transferTokens
|
|
501
|
+
})
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Sends `amount` tokens to `ethAccount` by way of the wormhole
|
|
506
|
+
* 1.) Creates a solana root wallet
|
|
507
|
+
* 2.) Sends the tokens from the user bank account to the solana wallet
|
|
508
|
+
* 3.) Permits the solana wallet to approve transfer to wormhole
|
|
509
|
+
* 4.) Transfers to the wrapped audio to the sol wormhole contract
|
|
510
|
+
* 5.) Gathers attestations from wormhole oracles and realizes the tokens on eth
|
|
511
|
+
*/
|
|
512
|
+
async sendTokensFromSolToEth (amount, ethAccount) {
|
|
513
|
+
const { error, logs, phase } = await this.wormholeClient.sendTokensFromSolToEthViaWormhole(amount, ethAccount)
|
|
514
|
+
return { error, logs, phase }
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
async _getPermitProxySendTokensParams (owner, relayerAddress, amount) {
|
|
518
|
+
const web3 = this.ethWeb3Manager.getWeb3()
|
|
519
|
+
const myPrivateKey = this.web3Manager.getOwnerWalletPrivateKey()
|
|
520
|
+
const chainId = await new Promise(resolve => web3.eth.getChainId((_, chainId) => resolve(chainId)))
|
|
521
|
+
const name = await this.ethContracts.AudiusTokenClient.name()
|
|
522
|
+
const tokenAddress = this.ethContracts.AudiusTokenClient.contractAddress
|
|
523
|
+
|
|
524
|
+
// Submit permit request to give address approval, via relayer
|
|
525
|
+
const nonce = await this.ethContracts.AudiusTokenClient.nonces(owner)
|
|
526
|
+
const currentBlockNumber = await web3.eth.getBlockNumber()
|
|
527
|
+
const currentBlock = await web3.eth.getBlock(currentBlockNumber)
|
|
528
|
+
// 1 hour, sufficiently far in future
|
|
529
|
+
const deadline = currentBlock.timestamp + (60 * 60 * 1)
|
|
530
|
+
|
|
531
|
+
const digest = getPermitDigest(
|
|
532
|
+
web3,
|
|
533
|
+
name,
|
|
534
|
+
tokenAddress,
|
|
535
|
+
chainId,
|
|
536
|
+
{ owner: owner, spender: relayerAddress, value: amount },
|
|
537
|
+
nonce,
|
|
538
|
+
deadline
|
|
539
|
+
)
|
|
540
|
+
const result = sign(digest, myPrivateKey)
|
|
541
|
+
return {
|
|
542
|
+
result,
|
|
543
|
+
deadline
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Permits `relayerAddress` to send `amount` on behalf of the current user, `owner`
|
|
549
|
+
*/
|
|
550
|
+
async permitProxySendTokens (owner, relayerAddress, amount) {
|
|
551
|
+
const {
|
|
552
|
+
result,
|
|
553
|
+
deadline
|
|
554
|
+
} = await this._getPermitProxySendTokensParams(owner, relayerAddress, amount)
|
|
555
|
+
const tx = await this.ethContracts.AudiusTokenClient.permit(
|
|
556
|
+
owner,
|
|
557
|
+
relayerAddress,
|
|
558
|
+
amount,
|
|
559
|
+
deadline,
|
|
560
|
+
result.v,
|
|
561
|
+
result.r,
|
|
562
|
+
result.s
|
|
563
|
+
)
|
|
564
|
+
return tx
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Gets the permit method to proxy send tokens `relayerAddress` to send `amount` on behalf of the current user, `owner`
|
|
569
|
+
*/
|
|
570
|
+
async getPermitProxySendTokensMethod (owner, relayerAddress, amount) {
|
|
571
|
+
const {
|
|
572
|
+
result,
|
|
573
|
+
deadline
|
|
574
|
+
} = await this._getPermitProxySendTokensParams(owner, relayerAddress, amount)
|
|
575
|
+
const contractMethod = this.ethContracts.AudiusTokenClient.AudiusTokenContract.methods.permit(
|
|
576
|
+
owner,
|
|
577
|
+
relayerAddress,
|
|
578
|
+
amount,
|
|
579
|
+
deadline,
|
|
580
|
+
result.v,
|
|
581
|
+
result.r,
|
|
582
|
+
result.s
|
|
583
|
+
)
|
|
584
|
+
return contractMethod
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Sends `amount` tokens to `address` from `owner`
|
|
589
|
+
*/
|
|
590
|
+
async sendTokens (owner, address, relayer, amount) {
|
|
591
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
592
|
+
return this.ethContracts.AudiusTokenClient.transferFrom(owner, address, relayer, amount)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Updates the minimum delegation amount for a user in identity
|
|
597
|
+
* NOTE: Requests eth account signature
|
|
598
|
+
*/
|
|
599
|
+
async updateMinimumDelegationAmount (amount) {
|
|
600
|
+
this.REQUIRES(Services.IDENTITY_SERVICE)
|
|
601
|
+
const unixTs = Math.round(new Date().getTime() / 1000) // current unix timestamp (sec)
|
|
602
|
+
const message = `Click sign to authenticate with identity service: ${unixTs}`
|
|
603
|
+
const signature = await this.ethWeb3Manager.sign(message)
|
|
604
|
+
const wallet = this.ethWeb3Manager.getWalletAddress()
|
|
605
|
+
return this.identityService.updateMinimumDelegationAmount(wallet, amount, {
|
|
606
|
+
[AuthHeaders.MESSAGE]: message,
|
|
607
|
+
[AuthHeaders.SIGNATURE]: signature
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Get current user account PDA from SOL given an ID and ETH wallet address
|
|
613
|
+
* @returns {object} with keys ethAddress, authority, replicaSet or
|
|
614
|
+
* null when account not found
|
|
615
|
+
*/
|
|
616
|
+
async getUserAccountOnSolana (
|
|
617
|
+
{ userId, wallet } = { userId: null, wallet: null }
|
|
618
|
+
) {
|
|
619
|
+
this.REQUIRES(Services.SOLANA_WEB3_MANAGER)
|
|
620
|
+
|
|
621
|
+
// If wallet or userId are not passed in, use the user loaded in libs
|
|
622
|
+
if (!wallet || !userId) {
|
|
623
|
+
const user = this.getCurrentUser()
|
|
624
|
+
wallet = user.wallet
|
|
625
|
+
userId = user.userId
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (!(userId instanceof BN)) {
|
|
629
|
+
userId = new BN(userId)
|
|
630
|
+
}
|
|
631
|
+
// matches format for PDA derivation seed in SOL program
|
|
632
|
+
// use BN.toArrayLike instead of .toBuffer for browser compat reasons
|
|
633
|
+
const userIdSeed = userId.toArrayLike(Buffer, 'le', 4)
|
|
634
|
+
|
|
635
|
+
const { derivedAddress: userAccountPDA } =
|
|
636
|
+
await this.solanaWeb3Manager.findDerivedPair(
|
|
637
|
+
this.solanaWeb3Manager.audiusDataProgramId,
|
|
638
|
+
this.solanaWeb3Manager.audiusDataAdminStorageKeypairPublicKey,
|
|
639
|
+
userIdSeed
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
const account = await this.solanaWeb3Manager.fetchAccount(userAccountPDA)
|
|
643
|
+
return account
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Checks that the current user has claimed account PDA on SOL
|
|
648
|
+
* @returns {boolean} userHasClaimedAccount
|
|
649
|
+
*/
|
|
650
|
+
async userHasClaimedSolAccount (
|
|
651
|
+
{ account = null, wallet = null, userId = null } = {
|
|
652
|
+
account: null,
|
|
653
|
+
wallet: null,
|
|
654
|
+
userId: null
|
|
655
|
+
}
|
|
656
|
+
) {
|
|
657
|
+
if (!account && !wallet && !userId) {
|
|
658
|
+
throw new Error('Must supply EITHER an `account` OR `wallet` and `userId` to look up whether userHasClaimedSolAccount')
|
|
659
|
+
}
|
|
660
|
+
if (!account && wallet && userId) {
|
|
661
|
+
account = await this.getUserAccountOnSolana({ wallet, userId })
|
|
662
|
+
}
|
|
663
|
+
const userHasClaimedAccount =
|
|
664
|
+
PublicKey.default.toString() !== account.authority.toString()
|
|
665
|
+
|
|
666
|
+
return userHasClaimedAccount
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
module.exports = Account
|