@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,655 @@
|
|
|
1
|
+
const solanaWeb3 = require('@solana/web3.js')
|
|
2
|
+
const splToken = require('@solana/spl-token')
|
|
3
|
+
const anchor = require('@project-serum/anchor')
|
|
4
|
+
const { idl } = require('@audius/anchor-audius-data')
|
|
5
|
+
|
|
6
|
+
const { transferWAudioBalance } = require('./transfer')
|
|
7
|
+
const { getBankAccountAddress, createUserBankFrom } = require('./userBank')
|
|
8
|
+
const {
|
|
9
|
+
createAssociatedTokenAccount,
|
|
10
|
+
getAssociatedTokenAccountInfo,
|
|
11
|
+
findAssociatedTokenAddress
|
|
12
|
+
} = require('./tokenAccount')
|
|
13
|
+
const { wAudioFromWeiAudio } = require('./wAudio')
|
|
14
|
+
const { Utils } = require('../../utils')
|
|
15
|
+
const SolanaUtils = require('./utils')
|
|
16
|
+
const { TransactionHandler } = require('./transactionHandler')
|
|
17
|
+
const {
|
|
18
|
+
submitAttestations,
|
|
19
|
+
evaluateAttestations,
|
|
20
|
+
createSender,
|
|
21
|
+
deriveSolanaSenderFromEthAddress
|
|
22
|
+
} = require('./rewards')
|
|
23
|
+
const { AUDIO_DECMIALS, WAUDIO_DECMIALS } = require('../../constants')
|
|
24
|
+
|
|
25
|
+
const { PublicKey } = solanaWeb3
|
|
26
|
+
|
|
27
|
+
// Somewhat arbitrary close-to-zero number of Sol. For context, creating a UserBank costs ~0.002 SOL.
|
|
28
|
+
// Without this padding, we could reach some low non-zero number of SOL where transactions would fail
|
|
29
|
+
// despite a remaining balance.
|
|
30
|
+
const ZERO_SOL_EPSILON = 0.005
|
|
31
|
+
const SOL_PER_LAMPORT = 0.000000001
|
|
32
|
+
|
|
33
|
+
// Generous default connection confirmation timeout to better cope with RPC congestion
|
|
34
|
+
const DEFAULT_CONNECTION_CONFIRMATION_TIMEOUT_MS = 180 * 1000
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {import("./rewards.js").AttestationMeta} AttestationMeta
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* SolanaWeb3Manager acts as the interface to solana contracts from a client.
|
|
42
|
+
* It wraps methods to create and lookup user banks, transfer balances, and
|
|
43
|
+
* interact with the @solana/web3 library.
|
|
44
|
+
*
|
|
45
|
+
* Note: Callers of this class should specify all $AUDIO amounts in units of wei.
|
|
46
|
+
* The internals of this class should handle the conversion from wei AUDIO to wormhole
|
|
47
|
+
* $AUDIO amounts.
|
|
48
|
+
*/
|
|
49
|
+
class SolanaWeb3Manager {
|
|
50
|
+
/**
|
|
51
|
+
* @param {Object} solanaWeb3Config
|
|
52
|
+
* @param {string} solanaWeb3Config.solanaClusterEndpoint
|
|
53
|
+
* the solana cluster RPC endpoint
|
|
54
|
+
* @param {string} solanaWeb3Config.mintAddress
|
|
55
|
+
* address for the wAudio mint - Audius (Wormhole) token
|
|
56
|
+
* @param {string} solanaWeb3Config.solanaTokenAddress
|
|
57
|
+
* the SPL token program address
|
|
58
|
+
* @param {string} solanaWeb3Config.claimableTokenPDA
|
|
59
|
+
* the program derived address for the claimable token program (using the mint)
|
|
60
|
+
* @param {string} solanaWeb3Config.feePayerAddress
|
|
61
|
+
* the address for the specific fee payer to be used in relayed transactions
|
|
62
|
+
* @param {string} solanaWeb3Config.claimableTokenProgramAddress
|
|
63
|
+
* the address for the claimable token program used to create banks and transfer wAudio
|
|
64
|
+
* @param {string} solanaWeb3Config.rewardsManagerProgramId
|
|
65
|
+
* the ID of the rewards manager program
|
|
66
|
+
* @param {string} solanaWeb3Config.rewardsManagerProgramPDA
|
|
67
|
+
* the manager account of the rewards manager program
|
|
68
|
+
* @param {string} solanaWeb3Config.rewardsManagerTokenPDA
|
|
69
|
+
* the token holder account of the rewards manager program
|
|
70
|
+
* @param {boolean} solanaWeb3Config.useRelay
|
|
71
|
+
* whether to submit transactions via a relay, or locally
|
|
72
|
+
* @param {KeyPair} solanaWeb3Config.feePayerKepairs
|
|
73
|
+
* KeyPairs for feepayers
|
|
74
|
+
* @param {number} [solanaWeb3Config.confirmationTimeout] optional default confirmation timeout
|
|
75
|
+
* @param {PublicKey} [solanaWeb3Config.audiusDataProgramId]
|
|
76
|
+
* Program ID for audius-data anchor program
|
|
77
|
+
* @param {PublicKey} [solanaWeb3Config.audiusDataAdminStorageKeypairPublicKey]
|
|
78
|
+
* PK for audius-data admin storage keypair
|
|
79
|
+
* @param {anchor.Idl} [solanaWeb3Config.audiusDataIdl]
|
|
80
|
+
* IDL for audius-data program
|
|
81
|
+
* @param {IdentityService} identityService
|
|
82
|
+
* @param {Web3Manager} web3Manager
|
|
83
|
+
*/
|
|
84
|
+
constructor (solanaWeb3Config, identityService, web3Manager) {
|
|
85
|
+
this.solanaWeb3Config = solanaWeb3Config
|
|
86
|
+
this.identityService = identityService
|
|
87
|
+
this.web3Manager = web3Manager
|
|
88
|
+
|
|
89
|
+
this.solanaWeb3 = solanaWeb3
|
|
90
|
+
this.splToken = splToken
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async init () {
|
|
94
|
+
const {
|
|
95
|
+
solanaClusterEndpoint,
|
|
96
|
+
mintAddress,
|
|
97
|
+
solanaTokenAddress,
|
|
98
|
+
claimableTokenPDA,
|
|
99
|
+
feePayerAddress,
|
|
100
|
+
claimableTokenProgramAddress,
|
|
101
|
+
rewardsManagerProgramId,
|
|
102
|
+
rewardsManagerProgramPDA,
|
|
103
|
+
rewardsManagerTokenPDA,
|
|
104
|
+
useRelay,
|
|
105
|
+
feePayerKeypairs,
|
|
106
|
+
confirmationTimeout,
|
|
107
|
+
audiusDataProgramId,
|
|
108
|
+
audiusDataAdminStorageKeypairPublicKey,
|
|
109
|
+
audiusDataIdl
|
|
110
|
+
} = this.solanaWeb3Config
|
|
111
|
+
|
|
112
|
+
this.solanaClusterEndpoint = solanaClusterEndpoint
|
|
113
|
+
this.connection = new solanaWeb3.Connection(this.solanaClusterEndpoint, {
|
|
114
|
+
confirmTransactionInitialTimeout:
|
|
115
|
+
confirmationTimeout || DEFAULT_CONNECTION_CONFIRMATION_TIMEOUT_MS
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
this.transactionHandler = new TransactionHandler({
|
|
119
|
+
connection: this.connection,
|
|
120
|
+
useRelay,
|
|
121
|
+
identityService: this.identityService,
|
|
122
|
+
feePayerKeypairs
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
this.mintAddress = mintAddress
|
|
126
|
+
this.mintKey = SolanaUtils.newPublicKeyNullable(mintAddress)
|
|
127
|
+
|
|
128
|
+
this.solanaTokenAddress = solanaTokenAddress
|
|
129
|
+
this.solanaTokenKey = SolanaUtils.newPublicKeyNullable(solanaTokenAddress)
|
|
130
|
+
|
|
131
|
+
if (feePayerAddress) {
|
|
132
|
+
this.feePayerAddress = feePayerAddress
|
|
133
|
+
this.feePayerKey = SolanaUtils.newPublicKeyNullable(feePayerAddress)
|
|
134
|
+
} else if (feePayerKeypairs && feePayerKeypairs.length) {
|
|
135
|
+
this.feePayerAddress = feePayerKeypairs[0].publicKey
|
|
136
|
+
this.feePayerKey = SolanaUtils.newPublicKeyNullable(
|
|
137
|
+
feePayerKeypairs[0].publicKey
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
this.claimableTokenProgramKey = SolanaUtils.newPublicKeyNullable(
|
|
142
|
+
claimableTokenProgramAddress
|
|
143
|
+
)
|
|
144
|
+
this.claimableTokenPDA =
|
|
145
|
+
claimableTokenPDA ||
|
|
146
|
+
(this.claimableTokenProgramKey
|
|
147
|
+
? (
|
|
148
|
+
await SolanaUtils.findProgramAddressFromPubkey(
|
|
149
|
+
this.claimableTokenProgramKey,
|
|
150
|
+
this.mintKey
|
|
151
|
+
)
|
|
152
|
+
)[0].toString()
|
|
153
|
+
: null)
|
|
154
|
+
this.claimableTokenPDAKey = SolanaUtils.newPublicKeyNullable(
|
|
155
|
+
this.claimableTokenPDA
|
|
156
|
+
)
|
|
157
|
+
this.rewardManagerProgramId = SolanaUtils.newPublicKeyNullable(
|
|
158
|
+
rewardsManagerProgramId
|
|
159
|
+
)
|
|
160
|
+
this.rewardManagerProgramPDA = SolanaUtils.newPublicKeyNullable(
|
|
161
|
+
rewardsManagerProgramPDA
|
|
162
|
+
)
|
|
163
|
+
this.rewardManagerTokenPDA = SolanaUtils.newPublicKeyNullable(
|
|
164
|
+
rewardsManagerTokenPDA
|
|
165
|
+
)
|
|
166
|
+
this.audiusDataProgramId = audiusDataProgramId
|
|
167
|
+
this.audiusDataAdminStorageKeypairPublicKey =
|
|
168
|
+
audiusDataAdminStorageKeypairPublicKey
|
|
169
|
+
|
|
170
|
+
this.audiusDataIdl = audiusDataIdl || idl
|
|
171
|
+
|
|
172
|
+
if (
|
|
173
|
+
this.audiusDataProgramId &&
|
|
174
|
+
this.audiusDataAdminStorageKeypairPublicKey &&
|
|
175
|
+
this.audiusDataIdl
|
|
176
|
+
) {
|
|
177
|
+
const connection = new solanaWeb3.Connection(
|
|
178
|
+
this.solanaClusterEndpoint,
|
|
179
|
+
anchor.AnchorProvider.defaultOptions()
|
|
180
|
+
)
|
|
181
|
+
const anchorProvider = new anchor.AnchorProvider(
|
|
182
|
+
connection,
|
|
183
|
+
solanaWeb3.Keypair.generate(),
|
|
184
|
+
anchor.AnchorProvider.defaultOptions()
|
|
185
|
+
)
|
|
186
|
+
this.anchorProgram = new anchor.Program(
|
|
187
|
+
this.audiusDataIdl,
|
|
188
|
+
audiusDataProgramId,
|
|
189
|
+
anchorProvider
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Creates a solana bank account from the web3 provider's eth address
|
|
196
|
+
*/
|
|
197
|
+
async createUserBank (feePayerOverride) {
|
|
198
|
+
if (!this.web3Manager) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
'A web3Manager is required for this solanaWeb3Manager method'
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const ethAddress = this.web3Manager.getWalletAddress()
|
|
205
|
+
return createUserBankFrom({
|
|
206
|
+
ethAddress,
|
|
207
|
+
claimableTokenPDAKey: this.claimableTokenPDAKey,
|
|
208
|
+
feePayerKey:
|
|
209
|
+
SolanaUtils.newPublicKeyNullable(feePayerOverride) || this.feePayerKey,
|
|
210
|
+
mintKey: this.mintKey,
|
|
211
|
+
solanaTokenProgramKey: this.solanaTokenKey,
|
|
212
|
+
claimableTokenProgramKey: this.claimableTokenProgramKey,
|
|
213
|
+
connection: this.connection,
|
|
214
|
+
transactionHandler: this.transactionHandler
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Creates a token account for the provided solana address (a wallet)
|
|
220
|
+
* See https://spl.solana.com/associated-token-account
|
|
221
|
+
* @param {string} solanaAddress
|
|
222
|
+
*/
|
|
223
|
+
async createAssociatedTokenAccount (solanaAddress) {
|
|
224
|
+
await createAssociatedTokenAccount({
|
|
225
|
+
feePayerKey: this.feePayerKey,
|
|
226
|
+
solanaWalletKey: new PublicKey(solanaAddress),
|
|
227
|
+
mintKey: this.mintKey,
|
|
228
|
+
solanaTokenProgramKey: this.solanaTokenKey,
|
|
229
|
+
connection: this.connection,
|
|
230
|
+
identityService: this.identityService
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Finds the wAudio token account for a provided solana address (a wallet)
|
|
236
|
+
* See https://spl.solana.com/associated-token-account
|
|
237
|
+
* @param {string} solanaAddress
|
|
238
|
+
*/
|
|
239
|
+
async findAssociatedTokenAddress (solanaAddress) {
|
|
240
|
+
return findAssociatedTokenAddress({
|
|
241
|
+
solanaWalletKey: new PublicKey(solanaAddress),
|
|
242
|
+
mintKey: this.mintKey,
|
|
243
|
+
solanaTokenProgramKey: this.solanaTokenKey
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Gets a solana bank account from the current we3 provider's eth address
|
|
249
|
+
* @returns {PublicKey} UserBank
|
|
250
|
+
*/
|
|
251
|
+
async getUserBank () {
|
|
252
|
+
if (!this.web3Manager) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
'A web3Manager is required for this solanaWeb3Manager method'
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
const ethAddress = this.web3Manager.getWalletAddress()
|
|
258
|
+
const bank = await getBankAccountAddress(
|
|
259
|
+
ethAddress,
|
|
260
|
+
this.claimableTokenPDAKey,
|
|
261
|
+
this.solanaTokenKey
|
|
262
|
+
)
|
|
263
|
+
return bank
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Gets the info for a user bank/wAudio token account given a solana address.
|
|
268
|
+
* If the solanaAddress is not a valid token account, returns `null`
|
|
269
|
+
* @returns {AccountInfo | null}
|
|
270
|
+
*/
|
|
271
|
+
async getAssociatedTokenAccountInfo (solanaAddress) {
|
|
272
|
+
try {
|
|
273
|
+
const res = await getAssociatedTokenAccountInfo({
|
|
274
|
+
tokenAccountAddressKey: new PublicKey(solanaAddress),
|
|
275
|
+
mintKey: this.mintKey,
|
|
276
|
+
solanaTokenProgramKey: this.solanaTokenKey,
|
|
277
|
+
connection: this.connection
|
|
278
|
+
})
|
|
279
|
+
return res
|
|
280
|
+
} catch (e) {
|
|
281
|
+
return null
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Gets the SPL waudio balance for a solana address in wei with 18 decimals
|
|
287
|
+
* @returns {BN | null}
|
|
288
|
+
*/
|
|
289
|
+
async getWAudioBalance (solanaAddress) {
|
|
290
|
+
try {
|
|
291
|
+
let tokenAccount = await this.getAssociatedTokenAccountInfo(solanaAddress)
|
|
292
|
+
|
|
293
|
+
// If the token account doesn't exist, check if solanaAddress is a root account
|
|
294
|
+
// if so, derive the associated token account & check that balance
|
|
295
|
+
if (!tokenAccount) {
|
|
296
|
+
const associatedTokenAccount = await this.findAssociatedTokenAddress(
|
|
297
|
+
solanaAddress
|
|
298
|
+
)
|
|
299
|
+
tokenAccount = await this.getAssociatedTokenAccountInfo(
|
|
300
|
+
associatedTokenAccount.toString()
|
|
301
|
+
)
|
|
302
|
+
if (!tokenAccount) {
|
|
303
|
+
return null
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Multiply by 10^10 to maintain same decimals as eth $AUDIO
|
|
308
|
+
const decimals = AUDIO_DECMIALS - WAUDIO_DECMIALS
|
|
309
|
+
return tokenAccount.amount.mul(Utils.toBN('1'.padEnd(decimals + 1, '0')))
|
|
310
|
+
} catch (e) {
|
|
311
|
+
return null
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Transfers audio from the web3 provider's eth address
|
|
317
|
+
* @param {string} recipientSolanaAddress
|
|
318
|
+
* Recipient solana address which is either a user bank, wAudio token account,
|
|
319
|
+
* or a solana account. In the last case, an associated token account is created
|
|
320
|
+
* if one does not already exist for the solana account
|
|
321
|
+
* @param {BN} amount the amount of $AUDIO to send in wei units of $AUDIO.
|
|
322
|
+
* **IMPORTANT NOTE**
|
|
323
|
+
* wAudio (Solana) does not support 10^-18 (wei) units of $AUDIO. The smallest
|
|
324
|
+
* demarcation on that side is 10^-8, so the $AUDIO amount must be >= 10^8 and have no
|
|
325
|
+
* remainder after a division with 10^8 or this method will throw.
|
|
326
|
+
*
|
|
327
|
+
* Generally speaking, callers into the solanaWeb3Manager should use BN.js representation
|
|
328
|
+
* of wei $AUDIO for all method calls
|
|
329
|
+
*/
|
|
330
|
+
async transferWAudio (recipientSolanaAddress, amount) {
|
|
331
|
+
if (!this.web3Manager) {
|
|
332
|
+
throw new Error(
|
|
333
|
+
'A web3Manager is required for this solanaWeb3Manager method'
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Check if the solana address is a token account
|
|
338
|
+
let tokenAccountInfo = await this.getAssociatedTokenAccountInfo(
|
|
339
|
+
recipientSolanaAddress
|
|
340
|
+
)
|
|
341
|
+
if (!tokenAccountInfo) {
|
|
342
|
+
console.info('Provided recipient solana address was not a token account')
|
|
343
|
+
// If not, check to see if it already has an associated token account.
|
|
344
|
+
const associatedTokenAccount = await this.findAssociatedTokenAddress(
|
|
345
|
+
recipientSolanaAddress
|
|
346
|
+
)
|
|
347
|
+
tokenAccountInfo = await this.getAssociatedTokenAccountInfo(
|
|
348
|
+
associatedTokenAccount.toString()
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
// If it's not a valid token account, we need to make one first
|
|
352
|
+
if (!tokenAccountInfo) {
|
|
353
|
+
console.info(
|
|
354
|
+
'Provided recipient solana address has no associated token account, creating'
|
|
355
|
+
)
|
|
356
|
+
await this.createAssociatedTokenAccount(recipientSolanaAddress)
|
|
357
|
+
}
|
|
358
|
+
recipientSolanaAddress = associatedTokenAccount.toString()
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
console.info(
|
|
362
|
+
`Transfering ${amount.toString()} wei $AUDIO to ${recipientSolanaAddress}`
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
const wAudioAmount = wAudioFromWeiAudio(amount)
|
|
366
|
+
|
|
367
|
+
const ethAddress = this.web3Manager.getWalletAddress()
|
|
368
|
+
const senderSolanaAddress = await getBankAccountAddress(
|
|
369
|
+
ethAddress,
|
|
370
|
+
this.claimableTokenPDAKey,
|
|
371
|
+
this.solanaTokenKey
|
|
372
|
+
)
|
|
373
|
+
return transferWAudioBalance({
|
|
374
|
+
amount: wAudioAmount,
|
|
375
|
+
senderEthAddress: ethAddress,
|
|
376
|
+
feePayerKey: this.feePayerKey,
|
|
377
|
+
senderEthPrivateKey: this.web3Manager.getOwnerWalletPrivateKey(),
|
|
378
|
+
senderSolanaAddress,
|
|
379
|
+
recipientSolanaAddress,
|
|
380
|
+
claimableTokenPDA: this.claimableTokenPDAKey,
|
|
381
|
+
solanaTokenProgramKey: this.solanaTokenKey,
|
|
382
|
+
claimableTokenProgramKey: this.claimableTokenProgramKey,
|
|
383
|
+
connection: this.connection,
|
|
384
|
+
mintKey: this.mintKey,
|
|
385
|
+
transactionHandler: this.transactionHandler
|
|
386
|
+
})
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Submits attestations for challenge completion to the RewardsManager program on Solana.
|
|
391
|
+
*
|
|
392
|
+
* @param {{
|
|
393
|
+
* attestations: AttestationMeta[],
|
|
394
|
+
* oracleAttestation: AttestationMeta,
|
|
395
|
+
* challengeId: string,
|
|
396
|
+
* specifier: string,
|
|
397
|
+
* recipientEthAddress: string,
|
|
398
|
+
* tokenAmount: BN,
|
|
399
|
+
* instructionsPerTransaction?: number,
|
|
400
|
+
* logger: any
|
|
401
|
+
* feePayerOverride: string | null
|
|
402
|
+
* }} {
|
|
403
|
+
* attestations,
|
|
404
|
+
* oracleAttestation,
|
|
405
|
+
* challengeId,
|
|
406
|
+
* specifier,
|
|
407
|
+
* recipientEthAddress,
|
|
408
|
+
* tokenAmount,
|
|
409
|
+
* instructionsPerTransaction,
|
|
410
|
+
* logger
|
|
411
|
+
* feePayerOverride
|
|
412
|
+
* }
|
|
413
|
+
* @memberof SolanaWeb3Manager
|
|
414
|
+
*/
|
|
415
|
+
async submitChallengeAttestations ({
|
|
416
|
+
attestations,
|
|
417
|
+
oracleAttestation,
|
|
418
|
+
challengeId,
|
|
419
|
+
specifier,
|
|
420
|
+
recipientEthAddress,
|
|
421
|
+
tokenAmount,
|
|
422
|
+
instructionsPerTransaction,
|
|
423
|
+
logger = console,
|
|
424
|
+
feePayerOverride = null
|
|
425
|
+
}) {
|
|
426
|
+
return submitAttestations({
|
|
427
|
+
rewardManagerProgramId: this.rewardManagerProgramId,
|
|
428
|
+
rewardManagerAccount: this.rewardManagerProgramPDA,
|
|
429
|
+
attestations,
|
|
430
|
+
oracleAttestation,
|
|
431
|
+
challengeId,
|
|
432
|
+
specifier,
|
|
433
|
+
feePayer:
|
|
434
|
+
SolanaUtils.newPublicKeyNullable(feePayerOverride) || this.feePayerKey,
|
|
435
|
+
recipientEthAddress,
|
|
436
|
+
tokenAmount,
|
|
437
|
+
transactionHandler: this.transactionHandler,
|
|
438
|
+
instructionsPerTransaction,
|
|
439
|
+
logger
|
|
440
|
+
})
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Evaluates existing submitted attestations, disbursing if successful.
|
|
445
|
+
*
|
|
446
|
+
* @param {{
|
|
447
|
+
* challengeId: string,
|
|
448
|
+
* specifier: string,
|
|
449
|
+
* recipientEthAddress: string
|
|
450
|
+
* oracleEthAddress: string
|
|
451
|
+
* logger: any
|
|
452
|
+
* feePayerOverride: string | null
|
|
453
|
+
* }} {
|
|
454
|
+
* challengeId,
|
|
455
|
+
* specifier,
|
|
456
|
+
* recipientEthAddress,
|
|
457
|
+
* oracleEthAddress,
|
|
458
|
+
* tokenAmount,
|
|
459
|
+
* logger
|
|
460
|
+
* feePayerOverride
|
|
461
|
+
* }
|
|
462
|
+
* @memberof SolanaWeb3Manager
|
|
463
|
+
*/
|
|
464
|
+
async evaluateChallengeAttestations ({
|
|
465
|
+
challengeId,
|
|
466
|
+
specifier,
|
|
467
|
+
recipientEthAddress,
|
|
468
|
+
oracleEthAddress,
|
|
469
|
+
tokenAmount,
|
|
470
|
+
logger = console,
|
|
471
|
+
feePayerOverride = null
|
|
472
|
+
}) {
|
|
473
|
+
return evaluateAttestations({
|
|
474
|
+
rewardManagerProgramId: this.rewardManagerProgramId,
|
|
475
|
+
rewardManagerAccount: this.rewardManagerProgramPDA,
|
|
476
|
+
rewardManagerTokenSource: this.rewardManagerTokenPDA,
|
|
477
|
+
challengeId,
|
|
478
|
+
specifier,
|
|
479
|
+
recipientEthAddress,
|
|
480
|
+
userBankProgramAccount: this.claimableTokenPDAKey,
|
|
481
|
+
oracleEthAddress,
|
|
482
|
+
feePayer:
|
|
483
|
+
SolanaUtils.newPublicKeyNullable(feePayerOverride) || this.feePayerKey,
|
|
484
|
+
tokenAmount,
|
|
485
|
+
transactionHandler: this.transactionHandler,
|
|
486
|
+
logger
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Creates a new rewards signer (one that can attest)
|
|
492
|
+
* @param {{
|
|
493
|
+
* senderEthAddress: string,
|
|
494
|
+
* operatorEthAddress: string,
|
|
495
|
+
* attestations: AttestationMeta[],
|
|
496
|
+
* feePayerOverride?: string
|
|
497
|
+
* }} {
|
|
498
|
+
* @memberof SolanaWeb3Manager
|
|
499
|
+
*/
|
|
500
|
+
async createSender ({
|
|
501
|
+
senderEthAddress,
|
|
502
|
+
operatorEthAddress,
|
|
503
|
+
attestations,
|
|
504
|
+
feePayerOverride = null
|
|
505
|
+
}) {
|
|
506
|
+
return createSender({
|
|
507
|
+
rewardManagerProgramId: this.rewardManagerProgramId,
|
|
508
|
+
rewardManagerAccount: this.rewardManagerProgramPDA,
|
|
509
|
+
senderEthAddress,
|
|
510
|
+
feePayer:
|
|
511
|
+
SolanaUtils.newPublicKeyNullable(feePayerOverride) || this.feePayerKey,
|
|
512
|
+
operatorEthAddress,
|
|
513
|
+
attestations,
|
|
514
|
+
identityService: this.identityService,
|
|
515
|
+
connection: this.connection,
|
|
516
|
+
transactionHandler: this.transactionHandler
|
|
517
|
+
})
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Gets the balance of a PublicKey, in SOL
|
|
522
|
+
*
|
|
523
|
+
* @param {{
|
|
524
|
+
* publicKey: PublicKey
|
|
525
|
+
* }} { publicKey }
|
|
526
|
+
* @return {Promise<number>}
|
|
527
|
+
* @memberof SolanaWeb3Manager
|
|
528
|
+
*/
|
|
529
|
+
async getBalance ({ publicKey }) {
|
|
530
|
+
const lamports = await this.connection.getBalance(publicKey)
|
|
531
|
+
return lamports * SOL_PER_LAMPORT
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Gets whether a PublicKey has a usable balance
|
|
536
|
+
*
|
|
537
|
+
* @param {{
|
|
538
|
+
* publicKey: PublicKey,
|
|
539
|
+
* epsilon?: number
|
|
540
|
+
* }} { publicKey }
|
|
541
|
+
* @return {Promise<boolean>}
|
|
542
|
+
* @memberof SolanaWeb3Manager
|
|
543
|
+
*/
|
|
544
|
+
async hasBalance ({ publicKey, epsilon = ZERO_SOL_EPSILON }) {
|
|
545
|
+
const balance = await this.getBalance({ publicKey })
|
|
546
|
+
return balance > epsilon
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
async getSlot () {
|
|
550
|
+
return this.connection.getSlot('processed')
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
async getRandomFeePayer () {
|
|
554
|
+
return this.identityService.getRandomFeePayer()
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Gets whether a given node registered on eth with `senderEthAddress` is registered on Solana
|
|
559
|
+
*
|
|
560
|
+
* @param {string} senderEthAddress
|
|
561
|
+
* @return {Promise<boolean>}
|
|
562
|
+
* @memberof SolanaWeb3Manager
|
|
563
|
+
*/
|
|
564
|
+
async getIsDiscoveryNodeRegistered (senderEthAddress) {
|
|
565
|
+
const derivedSenderSolanaAddress = await deriveSolanaSenderFromEthAddress(
|
|
566
|
+
senderEthAddress,
|
|
567
|
+
this.rewardManagerProgramId,
|
|
568
|
+
this.rewardManagerProgramPDA
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
const res = await this.connection.getAccountInfo(derivedSenderSolanaAddress)
|
|
572
|
+
return !!res
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
async findProgramAddress (programId, pubkey) {
|
|
576
|
+
return PublicKey.findProgramAddress(
|
|
577
|
+
[pubkey.toBytes().slice(0, 32)],
|
|
578
|
+
programId
|
|
579
|
+
)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Finds a 'derived' address by finding a programAddress with
|
|
584
|
+
* seeds array as first 32 bytes of base + seeds
|
|
585
|
+
* Returns [derivedAddress, bumpSeed]
|
|
586
|
+
* @param {string} programId
|
|
587
|
+
* @param {string} base
|
|
588
|
+
* @param {Buffer | Uint8Array} seed
|
|
589
|
+
* @returns the program address
|
|
590
|
+
*/
|
|
591
|
+
async findDerivedAddress (programId, base, seed) {
|
|
592
|
+
return PublicKey.findProgramAddress(
|
|
593
|
+
[base.toBytes().slice(0, 32), seed],
|
|
594
|
+
programId
|
|
595
|
+
)
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Finds the target PDA with the base audius admin as the initial seed
|
|
600
|
+
* In conjunction with the secondary seed as the users id in bytes
|
|
601
|
+
* @param {PublicKey} programId
|
|
602
|
+
* @param {PublicKey} adminAccount
|
|
603
|
+
* @param {Buffer | Uint8Array} seed
|
|
604
|
+
*/
|
|
605
|
+
async findDerivedPair (programId, adminAccount, seed) {
|
|
606
|
+
programId = SolanaUtils.newPublicKeyNullable(programId)
|
|
607
|
+
adminAccount = SolanaUtils.newPublicKeyNullable(adminAccount)
|
|
608
|
+
|
|
609
|
+
const [baseAuthorityAccount] = await this.findProgramAddress(
|
|
610
|
+
programId,
|
|
611
|
+
adminAccount
|
|
612
|
+
)
|
|
613
|
+
const derivedAddressInfo = await this.findDerivedAddress(
|
|
614
|
+
programId,
|
|
615
|
+
baseAuthorityAccount,
|
|
616
|
+
seed
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
const derivedAddress = derivedAddressInfo[0]
|
|
620
|
+
const bumpSeed = derivedAddressInfo[1]
|
|
621
|
+
|
|
622
|
+
return { baseAuthorityAccount, derivedAddress, bumpSeed }
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Fetch account on Solana given the program derived address
|
|
627
|
+
* @param {PublicKey} pda the program derived address from findDerivedPair()
|
|
628
|
+
*/
|
|
629
|
+
async fetchAccount (pda) {
|
|
630
|
+
let account
|
|
631
|
+
try {
|
|
632
|
+
account = await this.anchorProgram.account.user.fetch(pda)
|
|
633
|
+
return account
|
|
634
|
+
} catch (e) {
|
|
635
|
+
return null
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Given the eth address buffer from the account, convert to hex
|
|
641
|
+
* @param {Buffer} accountEthAddress
|
|
642
|
+
* @returns hex string of input bytes
|
|
643
|
+
*/
|
|
644
|
+
async deriveEthWalletFromAddress (accountEthAddress) {
|
|
645
|
+
let encodedEthAddress = Buffer.from(accountEthAddress).toString('hex')
|
|
646
|
+
|
|
647
|
+
if (!encodedEthAddress.startsWith('0x')) {
|
|
648
|
+
encodedEthAddress = '0x' + encodedEthAddress
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
return encodedEthAddress
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
module.exports = SolanaWeb3Manager
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type BN from 'bn.js'
|
|
2
|
+
/**
|
|
3
|
+
* Converts a BN to a Uint8Array of length 8, in little endian notation.
|
|
4
|
+
* Useful for when Rust wants a u64 (8 * 8) represented as a byte array.
|
|
5
|
+
* Ex: https://github.com/AudiusProject/audius-protocol/blob/master/solana-programs/reward-manager/program/src/processor.rs#L389
|
|
6
|
+
*/
|
|
7
|
+
export const padBNToUint8Array = (bn: BN): number[] => bn.toArray('le', 8)
|