diff --git a/fearless.xcodeproj/project.pbxproj b/fearless.xcodeproj/project.pbxproj index 28dde6513..ddb5c9138 100644 --- a/fearless.xcodeproj/project.pbxproj +++ b/fearless.xcodeproj/project.pbxproj @@ -381,6 +381,7 @@ 843F657A265854A700829C14 /* CrowdloanDisplayInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F6579265854A700829C14 /* CrowdloanDisplayInfo.swift */; }; 84403D7F25E91BC100494FD4 /* SuperIdentity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84403D7E25E91BC100494FD4 /* SuperIdentity.swift */; }; 84412EE126DAC3300049577A /* SubqueryHistoryOperationFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84412EE026DAC3300049577A /* SubqueryHistoryOperationFactory.swift */; }; + 84415BCA26E783EB005A3683 /* PayoutValidatorsForNominatorFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84415BC926E783EB005A3683 /* PayoutValidatorsForNominatorFactory.swift */; }; 8443FDB12554B7640092893D /* TitledMnemonicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8443FDB02554B7640092893D /* TitledMnemonicView.swift */; }; 8443FDB6255540570092893D /* ExportMnemonicData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8443FDB5255540570092893D /* ExportMnemonicData.swift */; }; 8443FE24255586230092893D /* ExportMnemonicConfirmProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8443FE23255586230092893D /* ExportMnemonicConfirmProtocols.swift */; }; @@ -558,7 +559,6 @@ 8470D6D2253E3382009E9A5D /* StorageSubscriptionContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8470D6D1253E3382009E9A5D /* StorageSubscriptionContainer.swift */; }; 8470D6D4253E35F0009E9A5D /* StorageUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8470D6D3253E35F0009E9A5D /* StorageUpdate.swift */; }; 847119C0262EF3BD00716580 /* PayoutValidatorsFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847119BF262EF3BD00716580 /* PayoutValidatorsFactoryProtocol.swift */; }; - 847119C8262EF45400716580 /* PayoutValidatorsForNominatorFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847119C7262EF45400716580 /* PayoutValidatorsForNominatorFactory.swift */; }; 847119CD262EF61F00716580 /* PayoutValidatorForValidatorFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847119CC262EF61F00716580 /* PayoutValidatorForValidatorFactory.swift */; }; 847119D5262EF95A00716580 /* PayoutInfoFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847119D4262EF95A00716580 /* PayoutInfoFactoryProtocol.swift */; }; 847119EB262EFF3800716580 /* ValidatorPayoutInfoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847119EA262EFF3800716580 /* ValidatorPayoutInfoFactory.swift */; }; @@ -1830,6 +1830,7 @@ 84403D7E25E91BC100494FD4 /* SuperIdentity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuperIdentity.swift; sourceTree = ""; }; 84403D8725E92A9C00494FD4 /* InitiatedBonding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitiatedBonding.swift; sourceTree = ""; }; 84412EE026DAC3300049577A /* SubqueryHistoryOperationFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubqueryHistoryOperationFactory.swift; sourceTree = ""; }; + 84415BC926E783EB005A3683 /* PayoutValidatorsForNominatorFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayoutValidatorsForNominatorFactory.swift; sourceTree = ""; }; 8443FDB02554B7640092893D /* TitledMnemonicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitledMnemonicView.swift; sourceTree = ""; }; 8443FDB5255540570092893D /* ExportMnemonicData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportMnemonicData.swift; sourceTree = ""; }; 8443FE23255586230092893D /* ExportMnemonicConfirmProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportMnemonicConfirmProtocols.swift; sourceTree = ""; }; @@ -2007,7 +2008,6 @@ 8470D6D1253E3382009E9A5D /* StorageSubscriptionContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageSubscriptionContainer.swift; sourceTree = ""; }; 8470D6D3253E35F0009E9A5D /* StorageUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageUpdate.swift; sourceTree = ""; }; 847119BF262EF3BD00716580 /* PayoutValidatorsFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayoutValidatorsFactoryProtocol.swift; sourceTree = ""; }; - 847119C7262EF45400716580 /* PayoutValidatorsForNominatorFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayoutValidatorsForNominatorFactory.swift; sourceTree = ""; }; 847119CC262EF61F00716580 /* PayoutValidatorForValidatorFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayoutValidatorForValidatorFactory.swift; sourceTree = ""; }; 847119D4262EF95A00716580 /* PayoutInfoFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayoutInfoFactoryProtocol.swift; sourceTree = ""; }; 847119EA262EFF3800716580 /* ValidatorPayoutInfoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorPayoutInfoFactory.swift; sourceTree = ""; }; @@ -7244,8 +7244,8 @@ 847119EA262EFF3800716580 /* ValidatorPayoutInfoFactory.swift */, 8490386A262E22DC0016D541 /* NominatorPayoutInfoFactory.swift */, 847119BF262EF3BD00716580 /* PayoutValidatorsFactoryProtocol.swift */, - 847119C7262EF45400716580 /* PayoutValidatorsForNominatorFactory.swift */, 847119CC262EF61F00716580 /* PayoutValidatorForValidatorFactory.swift */, + 84415BC926E783EB005A3683 /* PayoutValidatorsForNominatorFactory.swift */, ); path = PayoutRewardsService; sourceTree = ""; @@ -7980,6 +7980,7 @@ 849013DE24A927E2008F705E /* LocalizationManager+Shared.swift in Sources */, 849013DC24A927E2008F705E /* ApplicationConfigs.swift in Sources */, 84ACEBFA261E684A00AAE665 /* WalletHistoryFilter.swift in Sources */, + 84415BCA26E783EB005A3683 /* PayoutValidatorsForNominatorFactory.swift in Sources */, 84E7D67C26376A0A0037EB23 /* YourValidatorListInteractor+Subscription.swift in Sources */, 8401AEC32642A71D000B03E3 /* StakingRebondConfirmationViewController.swift in Sources */, 849014BE24AA87E4008F705E /* PinSetupPresenter.swift in Sources */, @@ -8426,7 +8427,6 @@ 8490144F24A93E2E008F705E /* UIImage+Drawing.swift in Sources */, 8444D13F267133CF00AF6D8C /* CrowdloanAddMemo.swift in Sources */, 84D97EC42520787500F07405 /* TransferConfirmConfigurator.swift in Sources */, - 847119C8262EF45400716580 /* PayoutValidatorsForNominatorFactory.swift in Sources */, 84EBC54324F656D100459D15 /* SortDescriptor+Storage.swift in Sources */, 8494D8742525331B00614D8F /* PriceInfo.swift in Sources */, 845532D02684690D00C2645D /* ParachainSlotLease.swift in Sources */, diff --git a/fearless/Common/Model/ChainHistoryRange.swift b/fearless/Common/Model/ChainHistoryRange.swift index 9ff0d798e..8fa95fe65 100644 --- a/fearless/Common/Model/ChainHistoryRange.swift +++ b/fearless/Common/Model/ChainHistoryRange.swift @@ -5,9 +5,14 @@ struct ChainHistoryRange { let activeEra: EraIndex let historyDepth: UInt32 - var erasRange: [EraIndex] { + var eraRange: EraRange { let start = max(currentEra - historyDepth, 0) let end = max(activeEra - 1, 0) - return Array(start ... end) + return EraRange(start, end) + } + + var eraList: [EraIndex] { + let range = eraRange + return Array(range.start ... range.end) } } diff --git a/fearless/Common/Model/SubstrateAlias.swift b/fearless/Common/Model/SubstrateAlias.swift index a78bf1f4e..085d7cb9d 100644 --- a/fearless/Common/Model/SubstrateAlias.swift +++ b/fearless/Common/Model/SubstrateAlias.swift @@ -10,6 +10,8 @@ typealias LeasingPeriod = UInt32 typealias Slot = UInt64 typealias SessionIndex = UInt32 typealias Moment = UInt32 +typealias EraIndex = UInt32 +typealias EraRange = (start: EraIndex, end: EraIndex) extension AccountId { static func matchHex(_ value: String) -> AccountId? { diff --git a/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService+Fetch.swift b/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService+Fetch.swift index eff6b9124..f77b7eb05 100644 --- a/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService+Fetch.swift +++ b/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService+Fetch.swift @@ -203,12 +203,12 @@ extension PayoutRewardsService { ) throws -> BaseOperation<[Data: [EraIndex]]> { ClosureOperation<[Data: [EraIndex]]> { let ledgerInfo = try ledgerInfoOperation.extractNoCancellableResultData() - let erasRange = try historyRangeOperation.extractNoCancellableResultData().erasRange + let eraList = try historyRangeOperation.extractNoCancellableResultData().eraList return ledgerInfo .reduce(into: [Data: [EraIndex]]()) { dict, ledger in let erasClaimedRewards = Set(ledger.claimedRewards.map(\.value)) - let erasUnclaimedRewards = Set(erasRange).subtracting(erasClaimedRewards) + let erasUnclaimedRewards = Set(eraList).subtracting(erasClaimedRewards) dict[ledger.stash] = Array(erasUnclaimedRewards) } } diff --git a/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService.swift b/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService.swift index 429fe88cc..53dff4484 100644 --- a/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService.swift +++ b/fearless/Common/Services/PayoutRewardsService/PayoutRewardsService.swift @@ -51,7 +51,11 @@ final class PayoutRewardsService: PayoutRewardsServiceProtocol { historyRangeWrapper.allOperations.forEach { $0.addDependency(codingFactoryOperation) } let validatorsWrapper = validatorsResolutionFactory - .createResolutionOperation(for: selectedAccountAddress) + .createResolutionOperation(for: selectedAccountAddress) { + try historyRangeWrapper.targetOperation.extractNoCancellableResultData().eraRange + } + + validatorsWrapper.addDependency(wrapper: historyRangeWrapper) let controllersWrapper: CompoundOperationWrapper<[Data]> = try createFetchAndMapOperation( dependingOn: validatorsWrapper.targetOperation, diff --git a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorForValidatorFactory.swift b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorForValidatorFactory.swift index b8fe4c113..4086c07e6 100644 --- a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorForValidatorFactory.swift +++ b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorForValidatorFactory.swift @@ -3,7 +3,10 @@ import RobinHood import IrohaCrypto final class PayoutValidatorsForValidatorFactory: PayoutValidatorsFactoryProtocol { - func createResolutionOperation(for address: AccountAddress) -> CompoundOperationWrapper<[AccountId]> { + func createResolutionOperation( + for address: AccountAddress, + eraRangeClosure _: @escaping () throws -> EraRange? + ) -> CompoundOperationWrapper<[AccountId]> { let operation = ClosureOperation<[AccountId]> { let accountId = try SS58AddressFactory().accountId(from: address) return [accountId] diff --git a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsFactoryProtocol.swift b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsFactoryProtocol.swift index fcff7526e..8af973ccf 100644 --- a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsFactoryProtocol.swift +++ b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsFactoryProtocol.swift @@ -2,5 +2,8 @@ import Foundation import RobinHood protocol PayoutValidatorsFactoryProtocol { - func createResolutionOperation(for address: AccountAddress) -> CompoundOperationWrapper<[AccountId]> + func createResolutionOperation( + for address: AccountAddress, + eraRangeClosure: @escaping () throws -> EraRange? + ) -> CompoundOperationWrapper<[AccountId]> } diff --git a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsForNominatorFactory.swift b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsForNominatorFactory.swift index fbf1b0d3e..c7a573ae8 100644 --- a/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsForNominatorFactory.swift +++ b/fearless/Common/Services/PayoutRewardsService/PayoutValidatorsForNominatorFactory.swift @@ -1,229 +1,89 @@ -import Foundation import RobinHood +import Foundation import FearlessUtils import IrohaCrypto final class PayoutValidatorsForNominatorFactory { - let chain: Chain - let subscanBaseURL: URL - let subscanOperationFactory: SubscanOperationFactoryProtocol - let operationManager: OperationManagerProtocol + let url: URL + let addressFactory: SS58AddressFactoryProtocol - init( - chain: Chain, - subscanBaseURL: URL, - subscanOperationFactory: SubscanOperationFactoryProtocol, - operationManager: OperationManagerProtocol - ) { - self.chain = chain - self.subscanBaseURL = subscanBaseURL - self.subscanOperationFactory = subscanOperationFactory - self.operationManager = operationManager + init(url: URL, addressFactory: SS58AddressFactoryProtocol) { + self.url = url + self.addressFactory = addressFactory } - private func createControllersQueryWrapper( - nominatorStashAddress: String - ) -> CompoundOperationWrapper> { - let controllersByStakingOperation = - createControllersByStakingOperation(nominatorStashAccount: nominatorStashAddress) - - let controllersByUtilityOperation = - createControllersByUtilityOperation(nominatorStashAccount: nominatorStashAddress) - - let mergeOperation = ClosureOperation> { - let stakingIds = try controllersByStakingOperation - .targetOperation.extractNoCancellableResultData() - let batchIds = try controllersByUtilityOperation - .targetOperation.extractNoCancellableResultData() - - return stakingIds.union(batchIds) + private func createRequestFactory( + address: AccountAddress, + historyRange: @escaping () -> EraRange? + ) -> NetworkRequestFactoryProtocol { + BlockNetworkRequestFactory { + var request = URLRequest(url: self.url) + + let eraRange = historyRange() + let params = self.requestParams(accountAddress: address, eraRange: eraRange) + let info = JSON.dictionaryValue(["query": JSON.stringValue(params)]) + request.httpBody = try JSONEncoder().encode(info) + request.setValue( + HttpContentType.json.rawValue, + forHTTPHeaderField: HttpHeaderKey.contentType.rawValue + ) + request.httpMethod = HttpMethod.post.rawValue + return request } - - let dependencies = controllersByStakingOperation.allOperations + controllersByUtilityOperation.allOperations - dependencies.forEach { mergeOperation.addDependency($0) } - - return CompoundOperationWrapper( - targetOperation: mergeOperation, - dependencies: dependencies - ) } - private func createControllersByStakingOperation(nominatorStashAccount: String) - -> CompoundOperationWrapper> { - let bondOperation = createSubscanQueryOperation( - address: nominatorStashAccount, - moduleName: "staking", - callName: "bond", - mapper: AnyMapper(mapper: ControllerMapper()), - reducer: AnyReducer(reducer: ControllersReducer()) - ) - - let setControllerOperation = createSubscanQueryOperation( - address: nominatorStashAccount, - moduleName: "staking", - callName: "set_controller", - mapper: AnyMapper(mapper: ControllerMapper()), - reducer: AnyReducer(reducer: ControllersReducer()) - ) - - let mergeOperation = ClosureOperation> { - let bondIds = try bondOperation.extractNoCancellableResultData() - let setControllerIds = try setControllerOperation.extractNoCancellableResultData() - - return bondIds.union(setControllerIds) - } - - let dependencies = [bondOperation, setControllerOperation] - dependencies.forEach { mergeOperation.addDependency($0) } - - return CompoundOperationWrapper( - targetOperation: mergeOperation, - dependencies: dependencies - ) - } - - private func createControllersByUtilityOperation( - nominatorStashAccount: String - ) -> CompoundOperationWrapper> { - let controllerMapper = AnyMapper(mapper: ControllerMapper()) - - let batchOperation = createSubscanQueryOperation( - address: nominatorStashAccount, - moduleName: "utility", - callName: "batch", - mapper: AnyMapper(mapper: BatchMapper(innerMapper: controllerMapper)), - reducer: AnyReducer(reducer: ControllersListReducer()) - ) - - let batchAllOperation = createSubscanQueryOperation( - address: nominatorStashAccount, - moduleName: "utility", - callName: "batch_all", - mapper: AnyMapper(mapper: BatchMapper(innerMapper: controllerMapper)), - reducer: AnyReducer(reducer: ControllersListReducer()) - ) - - let mergeOperation = ClosureOperation> { - let batchIds = try batchOperation.extractNoCancellableResultData() - let batchAllIds = try batchAllOperation.extractNoCancellableResultData() - - return batchIds.union(batchAllIds) + private func createResultFactory( + for addressFactory: SS58AddressFactoryProtocol + ) -> AnyNetworkResultFactory<[AccountId]> { + AnyNetworkResultFactory<[AccountId]> { data in + guard + let resultData = try? JSONDecoder().decode(JSON.self, from: data), + let nodes = resultData.data?.query?.eraValidatorInfos?.nodes?.arrayValue + else { return [] } + + return try nodes.compactMap { node in + guard let address = node.address?.stringValue else { + return nil + } + + return try addressFactory.accountId(from: address) + } } - - let dependencies = [batchOperation, batchAllOperation] - dependencies.forEach { mergeOperation.addDependency($0) } - - return CompoundOperationWrapper( - targetOperation: mergeOperation, - dependencies: dependencies - ) } - private func createValidatorsQueryWrapper( - controllers: Set - ) throws -> CompoundOperationWrapper<[AccountId]> { - let addressFactory = SS58AddressFactory() - - let validatorsOperations: [[BaseOperation>]] = - try controllers.map { controller in - let address = try addressFactory - .addressFromAccountId(data: controller, type: chain.addressType) - - let mapper = AnyMapper(mapper: NominateMapper()) - - let validatorsByNominate = createSubscanQueryOperation( - address: address, - moduleName: "staking", - callName: "nominate", - mapper: mapper, - reducer: AnyReducer(reducer: NominationsReducer()) - ) - - let validatorsByBatch = createSubscanQueryOperation( - address: address, - moduleName: "utility", - callName: "batch", - mapper: AnyMapper(mapper: BatchMapper(innerMapper: mapper)), - reducer: AnyReducer(reducer: NominationsListReducer()) - ) - - let validatorsByBatchAll = createSubscanQueryOperation( - address: address, - moduleName: "utility", - callName: "batch_all", - mapper: AnyMapper(mapper: BatchMapper(innerMapper: mapper)), - reducer: AnyReducer(reducer: NominationsListReducer()) - ) - - return [validatorsByNominate, validatorsByBatch, validatorsByBatchAll] - } - - let dependecies = validatorsOperations.flatMap { $0 } - - let mergeOperation = ClosureOperation<[Data]> { - let allSets = try dependecies.map { try $0.extractNoCancellableResultData() } - - let resultSet = allSets.reduce(into: Set()) { result, item in - result = result.union(item) + private func requestParams(accountAddress: AccountAddress, eraRange: EraRange?) -> String { + let eraFilter: String = eraRange.map { + "era:{greaterThanOrEqualTo: \($0.start), lessThanOrEqualTo: \($0.end)}," + } ?? "" + + return """ + { + query { + eraValidatorInfos( + filter:{ + \(eraFilter) + others:{contains:[{who:\"\(accountAddress)\"}]} + } + ) { + nodes { + address + } } - - return Array(resultSet) + } } - - dependecies.forEach { mergeOperation.addDependency($0) } - - return CompoundOperationWrapper( - targetOperation: mergeOperation, - dependencies: dependecies - ) - } - - private func createSubscanQueryOperation( - address: String, - moduleName: String, - callName: String, - mapper: AnyMapper, - reducer: AnyReducer> - ) -> BaseOperation> { - let url = subscanBaseURL - .appendingPathComponent(SubscanApi.extrinsics) - - let params = SubscanQueryParams(address: address, moduleName: moduleName, callName: callName) - - return SubscanQueryService( - url: url, - params: params, - mapper: mapper, - reducer: reducer, - initialResultValue: [], - subscanOperationFactory: subscanOperationFactory, - operationManager: operationManager - ).longrunOperation() + """ } } extension PayoutValidatorsForNominatorFactory: PayoutValidatorsFactoryProtocol { - func createResolutionOperation(for address: AccountAddress) -> CompoundOperationWrapper<[AccountId]> { - let controllersQueryWrapper = createControllersQueryWrapper(nominatorStashAddress: address) - - let validatorsOperation: BaseOperation<[[AccountId]]> = OperationCombiningService<[AccountId]>( - operationManager: operationManager - ) { - let controllers = try controllersQueryWrapper.targetOperation.extractNoCancellableResultData() - let wrapper = try self.createValidatorsQueryWrapper(controllers: controllers) - - return [wrapper] - }.longrunOperation() - - validatorsOperation.addDependency(controllersQueryWrapper.targetOperation) - - let mapOperation = ClosureOperation<[AccountId]> { - try validatorsOperation.extractNoCancellableResultData().flatMap { $0 } - } - - mapOperation.addDependency(validatorsOperation) - let dependencies = controllersQueryWrapper.allOperations + [validatorsOperation] - - return CompoundOperationWrapper(targetOperation: mapOperation, dependencies: dependencies) + func createResolutionOperation( + for address: AccountAddress, + eraRangeClosure _: @escaping () throws -> EraRange? + ) -> CompoundOperationWrapper<[AccountId]> { + let requestFactory = createRequestFactory(address: address, historyRange: { nil }) + let resultFactory = createResultFactory(for: addressFactory) + + let networkOperation = NetworkOperation(requestFactory: requestFactory, resultFactory: resultFactory) + return CompoundOperationWrapper(targetOperation: networkOperation) } } diff --git a/fearless/Common/Substrate/Types/ActiveEraInfo.swift b/fearless/Common/Substrate/Types/ActiveEraInfo.swift index 9c799eaef..1ae4de9a2 100644 --- a/fearless/Common/Substrate/Types/ActiveEraInfo.swift +++ b/fearless/Common/Substrate/Types/ActiveEraInfo.swift @@ -1,8 +1,6 @@ import Foundation import FearlessUtils -typealias EraIndex = UInt32 - struct ActiveEraInfo: Codable, Equatable { @StringCodable var index: EraIndex } diff --git a/fearless/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsViewFactory.swift b/fearless/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsViewFactory.swift index 5175cbaf4..a59c78fa4 100644 --- a/fearless/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsViewFactory.swift +++ b/fearless/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsViewFactory.swift @@ -10,7 +10,7 @@ final class StakingRewardPayoutsViewFactory: StakingRewardPayoutsViewFactoryProt ) -> StakingRewardPayoutsViewProtocol? { let settings = SettingsManager.shared let connection = settings.selectedConnection - let operationManager = OperationManagerFacade.sharedManager + let addressFactory = SS58AddressFactory() let chain = connection.type.chain @@ -19,20 +19,18 @@ final class StakingRewardPayoutsViewFactory: StakingRewardPayoutsViewFactoryProt let asset = primitiveFactory.createAssetForAddressType(chain.addressType) guard let assetId = WalletAssetId(rawValue: asset.identifier), - let subscanUrl = assetId.subscanUrl else { + let rewardsUrl = assetId.subqueryHistoryUrl else { return nil } let validatorsResolutionFactory = PayoutValidatorsForNominatorFactory( - chain: chain, - subscanBaseURL: subscanUrl, - subscanOperationFactory: SubscanOperationFactory(), - operationManager: operationManager + url: rewardsUrl, + addressFactory: addressFactory ) let payoutInfoFactory = NominatorPayoutInfoFactory( addressType: chain.addressType, - addressFactory: SS58AddressFactory() + addressFactory: addressFactory ) return createView( diff --git a/fearless/en.lproj/Localizable.strings b/fearless/en.lproj/Localizable.strings index d9934d94d..67513d7a8 100644 --- a/fearless/en.lproj/Localizable.strings +++ b/fearless/en.lproj/Localizable.strings @@ -28,7 +28,7 @@ Terms and Conditions and Privacy Policy"; "tabbar.staking.title" = "Staking"; "tabbar.settings.title" = "Settings"; "wallet.empty.description" = "Incoming and outgoing\ -transfers will appear here"; +operations will appear here"; "profile.title" = "Settings"; "profile.about.title" = "About"; "profile.language.title" = "Language"; @@ -130,7 +130,7 @@ transfers will appear here"; "wallet.send.amount.title" = "Amount"; "wallet.send.confirm.title" = "Confirm transfer"; "wallet.send.available.balance" = "Available balance"; -"wallet.contacts.empty.title" = "Your accounts and contacts to who you were sending transfers will appear here"; +"wallet.contacts.empty.title" = "Your accounts and contacts to whom you were sending transfers will appear here"; "wallet.search.empty.title" = "Make sure that the address is \ from the right network"; "wallet.contacts.search.placeholder" = "Account address or account name"; @@ -316,12 +316,12 @@ Derivation path: %@"; "staking.alerts.title" = "Alerts"; "staking.recommended.hint5" = "Limit of 2 validators per identity"; "staking.set.separate.account.controller" = "Set a separate account as a controller to increase staking management security."; -"staking.stash.can.hint" = "Stash can bond more and set the controller."; +"staking.stash.can.hint" = "Stash can stake more and set the controller."; "staking.controller.can.hint" = "Controller can unstake, redeem, return to stake, change rewards destination and validators."; "staking.switch.account.to.stash" = "Switch your account to stash to set the controller."; "staking.inactive.current.minimal.stake" = "Staking is currently inactive.\nCurrent minimal stake is %@."; "staking.change.your.validators" = "Change your validators."; -"staking.bond.more.tokens" = "Bond more tokens."; +"staking.bond.more.tokens" = "Stake more tokens."; "staking.redeem.unbonded.tokens" = "Redeem unstaked tokens."; "staking.your.stake" = "Your stake"; "staking.controller.account.zero.balance" = "We found that this account has no free tokens, are you sure that you want to change the controller?"; @@ -395,7 +395,7 @@ Derivation path: %@"; "staking.set.validators.message" = "Validators are not selected"; "staking.max.nominators.reached.title" = "Cannot start staking"; "staking.max.nominators.reached.message" = "Maximum number of nominators has been reached"; -"staking.custom.blocked.warning" = "This validator is blocked and cannot be selected at the moment. Please, try again in the next era."; +"staking.custom.blocked.warning" = "This validator is not accepting nominations at this moment. Please, try again in the next era."; "staking.alert.start.next.era.message" = "Please wait for the next era to start."; "staking.custom.proceed.button.disabled.title" = "Select validators (max %d)"; "staking.custom.proceed.button.enabled.title" = "Show selected: %d (max %d)"; diff --git a/fearless/ru.lproj/Localizable.strings b/fearless/ru.lproj/Localizable.strings index 6b551cbab..a37c194a3 100644 --- a/fearless/ru.lproj/Localizable.strings +++ b/fearless/ru.lproj/Localizable.strings @@ -395,7 +395,7 @@ "staking.set.validators.message" = "Валидаторы не выбраны"; "staking.max.nominators.reached.title" = "Невозможно начать стейкинг"; "staking.max.nominators.reached.message" = "Достигнуто максимальное количество номинаторов"; -"staking.custom.blocked.warning" = "Этот валидатор заблокирован и сейчас его невозможно выбрать. Пожалуйста, попробуйте снова в следующую эру."; +"staking.custom.blocked.warning" = "Этот валидатор не принимает номинации в данный момент. Пожалуйста, попробуйте снова в следующую эру."; "staking.alert.start.next.era.message" = "Пожалуйста, дождитесь начала следующей эры."; "staking.custom.proceed.button.disabled.title" = "Выбрать валидаторов (макс. %li)"; "staking.custom.proceed.button.enabled.title" = "Показать выбранных: %li (макс. %li)"; diff --git a/fearlessIntegrationTests/PayoutRewardsServiceTests.swift b/fearlessIntegrationTests/PayoutRewardsServiceTests.swift index e3ab7be9a..eca314e5b 100644 --- a/fearlessIntegrationTests/PayoutRewardsServiceTests.swift +++ b/fearlessIntegrationTests/PayoutRewardsServiceTests.swift @@ -12,7 +12,8 @@ class PayoutRewardsServiceTests: XCTestCase { let settings = SettingsManager.shared let assetId = WalletAssetId.kusama let chain = assetId.chain! - let selectedAccount = "FiLhWLARS32oxm4s64gmEMSppAdugsvaAx1pCjweTLGn5Rf" + let selectedAccount = "FyE2tgkaAhARtpTJSy8TtJum1PwNHP1nCy3SuFjEGSvNfMv" + let addressFactory = SS58AddressFactory() try! AccountCreationHelper.createAccountFromMnemonic( cryptoType: .sr25519, @@ -31,16 +32,14 @@ class PayoutRewardsServiceTests: XCTestCase { operationManager: operationManager ) let validatorsResolutionFactory = PayoutValidatorsForNominatorFactory( - chain: chain, - subscanBaseURL: assetId.subscanUrl!, - subscanOperationFactory: SubscanOperationFactory(), - operationManager: operationManager + url: assetId.subqueryHistoryUrl!, + addressFactory: addressFactory ) let identityOperation = IdentityOperationFactory(requestFactory: storageRequestFactory) let payoutInfoFactory = NominatorPayoutInfoFactory( addressType: chain.addressType, - addressFactory: SS58AddressFactory() + addressFactory: addressFactory ) let service = PayoutRewardsService(