Skip to content

Commit

Permalink
Merge pull request #1197 from novasamatech/develop
Browse files Browse the repository at this point in the history
8.6.0 Non-native Fee Payment Assets for Asset Hub and Hydration
  • Loading branch information
svojsu authored Aug 23, 2024
2 parents e54e030 + 094c696 commit bf17cfa
Show file tree
Hide file tree
Showing 95 changed files with 2,840 additions and 737 deletions.
6 changes: 3 additions & 3 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ platform :ios, '14.0'
abstract_target 'novawalletAll' do
use_frameworks!

pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.1'
pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.2'
pod 'SwiftLint'
pod 'R.swift', :inhibit_warnings => true
pod 'SoraKeystore', '~> 1.0.0'
Expand Down Expand Up @@ -37,7 +37,7 @@ abstract_target 'novawalletAll' do
inherit! :search_paths

pod 'Cuckoo'
pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.1'
pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.2'
pod 'SoraFoundation', :git => 'https://github.com/ERussel/Foundation-iOS.git', :tag => '1.1.0'
pod 'R.swift', :inhibit_warnings => true
pod 'FireMock', :inhibit_warnings => true
Expand All @@ -62,7 +62,7 @@ abstract_target 'novawalletAll' do
pod 'SoraKeystore', '~> 1.0.0'
pod 'Operation-iOS', :git => 'https://github.com/novasamatech/Operation-iOS', :tag => '2.0.1'
pod 'Sourcery', '~> 1.4'
pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.1'
pod 'SubstrateSdk', :git => 'https://github.com/nova-wallet/substrate-sdk-ios.git', :tag => '3.2.2'
pod 'SwiftyBeaver'
end

Expand Down
12 changes: 6 additions & 6 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ PODS:
- SoraUI/Skrull (1.13.0)
- Sourcery (1.4.1)
- Starscream (4.0.12)
- SubstrateSdk (3.2.1):
- SubstrateSdk (3.2.2):
- BigInt (~> 5.0)
- IrohaCrypto/ed25519 (~> 0.9.0)
- IrohaCrypto/Scrypt (~> 0.9.0)
Expand Down Expand Up @@ -981,7 +981,7 @@ DEPENDENCIES:
- SoraUI (from `https://github.com/ERussel/UIkit-iOS.git`, tag `1.13.0`)
- Sourcery (~> 1.4)
- Starscream (from `https://github.com/novasamatech/Starscream.git`, tag `4.0.12`)
- SubstrateSdk (from `https://github.com/nova-wallet/substrate-sdk-ios.git`, tag `3.2.1`)
- SubstrateSdk (from `https://github.com/nova-wallet/substrate-sdk-ios.git`, tag `3.2.2`)
- SVGKit (from `https://github.com/SVGKit/SVGKit.git`, tag `3.0.0`)
- SwiftAlgorithms (~> 1.0.0)
- SwiftFormat/CLI (~> 0.47.13)
Expand Down Expand Up @@ -1070,7 +1070,7 @@ EXTERNAL SOURCES:
:tag: 4.0.12
SubstrateSdk:
:git: https://github.com/nova-wallet/substrate-sdk-ios.git
:tag: 3.2.1
:tag: 3.2.2
SVGKit:
:git: https://github.com/SVGKit/SVGKit.git
:tag: 3.0.0
Expand Down Expand Up @@ -1110,7 +1110,7 @@ CHECKOUT OPTIONS:
:tag: 4.0.12
SubstrateSdk:
:git: https://github.com/nova-wallet/substrate-sdk-ios.git
:tag: 3.2.1
:tag: 3.2.2
SVGKit:
:git: https://github.com/SVGKit/SVGKit.git
:tag: 3.0.0
Expand Down Expand Up @@ -1172,7 +1172,7 @@ SPEC CHECKSUMS:
SoraUI: 1d1a25881d1d597f19bc55f82c99ee236cc1ab11
Sourcery: db66600e8b285c427701821598d07cf3c7e6c476
Starscream: 9265e4163aeea93d4a74c49bc8cb4c0b9c6ff350
SubstrateSdk: fe20689ad3f1bc680318a338c9e7dcde53e9c36b
SubstrateSdk: bc3da50e8e44ebb67e54fb20d5938a91ed85fc3c
SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63
SwiftAlgorithms: 38dda4731d19027fdeee1125f973111bf3386b53
SwiftFormat: 73573b89257437c550b03d934889725fbf8f75e5
Expand All @@ -1187,6 +1187,6 @@ SPEC CHECKSUMS:
ZMarkupParser: a92d31ba40695b790f1da5fec98c3d4505341aff
ZNSTextAttachment: 1ddd53660a8d3c42dbb716bf6866ffce22c44181

PODFILE CHECKSUM: 98141de3b13f527da1029c2ef17b57dfef7c184a
PODFILE CHECKSUM: 73c4593a21ffac681c225d143f0787a49f9e9826

COCOAPODS: 1.15.2
148 changes: 111 additions & 37 deletions novawallet.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,27 @@ extension NSPredicate {
let chainPredicate = filterTransactionsByChainId(chainId)
let assetPredicate = filterTransactionsByAssetId(utilityAssetId)
let swapPredicate = filterSwapTransactionsByAssetId(utilityAssetId)
let feeAssetPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [
filterTransactionsByFeeAssetId(utilityAssetId),
filterTransactionsByNoFeeAssetId()
])

let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
chainPredicate,
NSCompoundPredicate(
orPredicateWithSubpredicates: [
senderPredicate,
NSCompoundPredicate(andPredicateWithSubpredicates: [
assetPredicate,
senderPredicate
]),
NSCompoundPredicate(andPredicateWithSubpredicates: [
swapPredicate,
senderPredicate
]),
NSCompoundPredicate(andPredicateWithSubpredicates: [
feeAssetPredicate,
senderPredicate
]),
NSCompoundPredicate(andPredicateWithSubpredicates: [
assetPredicate,
receiverPredicate
Expand Down Expand Up @@ -162,6 +177,14 @@ extension NSPredicate {
NSPredicate(format: "%K == %d", #keyPath(CDTransactionItem.assetId), Int32(bitPattern: assetId))
}

static func filterTransactionsByFeeAssetId(_ assetId: UInt32) -> NSPredicate {
NSPredicate(format: "%K == %d", #keyPath(CDTransactionItem.feeAssetId), Int32(bitPattern: assetId))
}

static func filterTransactionsByNoFeeAssetId() -> NSPredicate {
NSPredicate(format: "%K = nil", #keyPath(CDTransactionItem.feeAssetId))
}

static func filterTransactionsBySource(_ source: TransactionHistoryItemSource) -> NSPredicate {
NSPredicate(format: "%K == %d", #keyPath(CDTransactionItem.source), source.rawValue)
}
Expand Down
3 changes: 3 additions & 0 deletions novawallet/Common/Migration/SubstrateStorageVersion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum SubstrateStorageVersion: String, CaseIterable {
case version29 = "SubstrateDataModel29"
case version30 = "SubstrateDataModel30"
case version31 = "SubstrateDataModel31"
case version32 = "SubstrateDataModel32"

static var current: SubstrateStorageVersion {
allCases.last!
Expand Down Expand Up @@ -98,6 +99,8 @@ enum SubstrateStorageVersion: String, CaseIterable {
case .version30:
return .version31
case .version31:
return .version32
case .version32:
return nil
}
}
Expand Down
8 changes: 8 additions & 0 deletions novawallet/Common/Model/AssetType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@ enum AssetType: String {
case evmAsset = "evm"
case evmNative
case equilibrium

init?(rawType: String?) {
if let rawType {
self.init(rawValue: rawType)
} else {
return nil
}
}
}
14 changes: 14 additions & 0 deletions novawallet/Common/Model/ChainRegistry/LocalChain/ChainModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,18 @@ struct ChainModel: Equatable, Hashable {
hasSwapHub || hasSwapHydra
}

var hasAssetHubTransferFees: Bool {
options?.contains(where: { $0 == .assetHubFees }) ?? false
}

var hasHydrationTransferFees: Bool {
options?.contains(where: { $0 == .hydrationFees }) ?? false
}

var hasCustomTransferFees: Bool {
hasAssetHubTransferFees || hasHydrationTransferFees
}

var hasProxy: Bool {
options?.contains(where: { $0 == .proxy }) ?? false
}
Expand Down Expand Up @@ -335,6 +347,8 @@ enum LocalChainOptions: String, Codable {
case swapHydra = "hydradx-swaps"
case proxy
case pushNotifications = "pushSupport"
case assetHubFees = "assethub-fees"
case hydrationFees = "hydration-fees"
}

extension ChainModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ protocol EvmTransactionFeeProxyProtocol: AnyObject {
final class EvmTransactionFeeProxy: TransactionFeeProxy<EvmFeeModel> {
weak var delegate: EvmTransactionFeeProxyDelegate?

private func handle(result: Result<EvmFeeModel, Error>, for identifier: TransactionFeeId) {
update(result: result, for: identifier)
private func handle(result: Result<EvmFeeModel, Error>, for stateKey: StateKey) {
update(result: result, for: stateKey)

delegate?.didReceiveFee(result: result, for: identifier)
delegate?.didReceiveFee(result: result, for: stateKey.reuseIdentifier)
}
}

Expand All @@ -31,18 +31,20 @@ extension EvmTransactionFeeProxy: EvmTransactionFeeProxyProtocol {
reuseIdentifier: TransactionFeeId,
setupBy closure: @escaping EvmTransactionBuilderClosure
) {
if let state = getCachedState(for: reuseIdentifier) {
let stateKey = StateKey(reuseIdentifier: reuseIdentifier, chainAssetId: nil)

if let state = getCachedState(for: stateKey) {
if case let .loaded(result) = state {
delegate?.didReceiveFee(result: result, for: reuseIdentifier)
}

return
}

setCachedState(.loading, for: reuseIdentifier)
setCachedState(.loading, for: stateKey)

service.estimateFee(closure, runningIn: .main) { [weak self] result in
self?.handle(result: result, for: reuseIdentifier)
self?.handle(result: result, for: stateKey)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import BigInt
class BaseExtrinsicOperationFactory {
let runtimeRegistry: RuntimeCodingServiceProtocol
let engine: JSONRPCEngine
let feeEstimationRegistry: ExtrinsicFeeEstimationRegistring
let operationManager: OperationManagerProtocol
let usesStateCallForFee: Bool

init(
runtimeRegistry: RuntimeCodingServiceProtocol,
engine: JSONRPCEngine,
feeEstimationRegistry: ExtrinsicFeeEstimationRegistring,
operationManager: OperationManagerProtocol,
usesStateCallForFee: Bool
) {
self.runtimeRegistry = runtimeRegistry
self.engine = engine
self.feeEstimationRegistry = feeEstimationRegistry
self.operationManager = operationManager
self.usesStateCallForFee = usesStateCallForFee
}
Expand All @@ -28,6 +31,7 @@ class BaseExtrinsicOperationFactory {
func createExtrinsicWrapper(
customClosure _: @escaping ExtrinsicBuilderIndexedClosure,
indexes _: [Int],
payingFeeIn _: ChainAssetId?,
signingClosure _: @escaping (Data, ExtrinsicSigningContext) throws -> Data
) -> CompoundOperationWrapper<ExtrinsicsCreationResult> {
fatalError("Subclass must override this method")
Expand Down Expand Up @@ -184,7 +188,8 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {

func estimateFeeOperation(
_ closure: @escaping ExtrinsicBuilderIndexedClosure,
indexes: IndexSet
indexes: IndexSet,
payingIn chainAssetId: ChainAssetId?
) -> CompoundOperationWrapper<FeeIndexedExtrinsicResult> {
let signingClosure: (Data, ExtrinsicSigningContext) throws -> Data = { data, context in
guard let cryptoType = context.substrateCryptoType else {
Expand All @@ -201,36 +206,30 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {
let builderWrapper = createExtrinsicWrapper(
customClosure: closure,
indexes: indexList,
payingFeeIn: chainAssetId,
signingClosure: signingClosure
)

let coderFactoryOperation = runtimeRegistry.fetchCoderFactoryOperation()

let feeOperation = createFeeOperation(
dependingOn: coderFactoryOperation,
extrinsicOperation: builderWrapper.targetOperation,
connection: connection,
usesStateCallForFee: usesStateCallForFee
let feeWrapper = feeEstimationRegistry.createFeeEstimatingWrapper(
payingIn: chainAssetId,
extrinsicCreatingResultClosure: {
try builderWrapper.targetOperation.extractNoCancellableResultData()
}
)

feeOperation.addDependency(coderFactoryOperation)
feeOperation.addDependency(builderWrapper.targetOperation)
feeWrapper.addDependency(operations: [coderFactoryOperation])
feeWrapper.addDependency(wrapper: builderWrapper)

let wrapperOperation = ClosureOperation<ExtrinsicRetriableResult<ExtrinsicFeeProtocol>> {
do {
let results = try feeOperation.extractNoCancellableResultData()
let sender = try builderWrapper.targetOperation.extractNoCancellableResultData().sender

let feePayer = ExtrinsicFeePayer(senderResolution: sender)

let indexedResults = try zip(indexList, results).map { indexedResult in
guard let convertedResult = ExtrinsicFee(dispatchInfo: indexedResult.1, payer: feePayer) else {
throw CommonError.dataCorruption
}
let result = try feeWrapper.targetOperation.extractNoCancellableResultData()

return FeeIndexedExtrinsicResult.IndexedResult(
let indexedResults = zip(indexList, result.items).map { indexedResult in
FeeIndexedExtrinsicResult.IndexedResult(
index: indexedResult.0,
result: .success(convertedResult)
result: .success(indexedResult.1)
)
}

Expand All @@ -244,18 +243,18 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {
}
}

wrapperOperation.addDependency(feeOperation)
wrapperOperation.addDependency(feeWrapper.targetOperation)

return CompoundOperationWrapper(
targetOperation: wrapperOperation,
dependencies: builderWrapper.allOperations + [coderFactoryOperation, feeOperation]
)
return feeWrapper
.insertingHead(operations: builderWrapper.allOperations + [coderFactoryOperation])
.insertingTail(operation: wrapperOperation)
}

func submit(
_ closure: @escaping ExtrinsicBuilderIndexedClosure,
signer: SigningWrapperProtocol,
indexes: IndexSet
indexes: IndexSet,
payingIn chainAssetId: ChainAssetId?
) -> CompoundOperationWrapper<SubmitIndexedExtrinsicResult> {
let signingClosure: (Data, ExtrinsicSigningContext) throws -> Data = { data, context in
try signer.sign(data, context: context).rawData()
Expand All @@ -266,6 +265,7 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {
let builderWrapper = createExtrinsicWrapper(
customClosure: closure,
indexes: indexList,
payingFeeIn: chainAssetId,
signingClosure: signingClosure
)

Expand Down Expand Up @@ -319,7 +319,8 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {

func buildExtrinsic(
_ closure: @escaping ExtrinsicBuilderClosure,
signer: SigningWrapperProtocol
signer: SigningWrapperProtocol,
payingFeeIn chainAssetId: ChainAssetId?
) -> CompoundOperationWrapper<String> {
let wrapperClosure: ExtrinsicBuilderIndexedClosure = { builder, _ in
try closure(builder)
Expand All @@ -332,6 +333,7 @@ extension BaseExtrinsicOperationFactory: ExtrinsicOperationFactoryProtocol {
let builderWrapper = createExtrinsicWrapper(
customClosure: wrapperClosure,
indexes: [0],
payingFeeIn: chainAssetId,
signingClosure: signingClosure
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ protocol ExtrinsicBuilderOperationFactoryProtocol {
func createWrapper(
customClosure: @escaping ExtrinsicBuilderIndexedClosure,
indexes: [Int],
payingFeeIn chainAssetId: ChainAssetId?,
signingClosure: @escaping (Data, ExtrinsicSigningContext) throws -> Data
) -> CompoundOperationWrapper<ExtrinsicsCreationResult>

Expand All @@ -19,6 +20,7 @@ final class ExtrinsicProxyOperationFactory: BaseExtrinsicOperationFactory {
proxy: ExtrinsicBuilderOperationFactoryProtocol,
runtimeRegistry: RuntimeCodingServiceProtocol,
engine: JSONRPCEngine,
feeEstimationRegistry: ExtrinsicFeeEstimationRegistring,
operationManager: OperationManagerProtocol,
usesStateCallForFee: Bool
) {
Expand All @@ -27,6 +29,7 @@ final class ExtrinsicProxyOperationFactory: BaseExtrinsicOperationFactory {
super.init(
runtimeRegistry: runtimeRegistry,
engine: engine,
feeEstimationRegistry: feeEstimationRegistry,
operationManager: operationManager,
usesStateCallForFee: usesStateCallForFee
)
Expand All @@ -39,11 +42,13 @@ final class ExtrinsicProxyOperationFactory: BaseExtrinsicOperationFactory {
override func createExtrinsicWrapper(
customClosure: @escaping ExtrinsicBuilderIndexedClosure,
indexes: [Int],
payingFeeIn chainAssetId: ChainAssetId?,
signingClosure: @escaping (Data, ExtrinsicSigningContext) throws -> Data
) -> CompoundOperationWrapper<ExtrinsicsCreationResult> {
proxy.createWrapper(
customClosure: customClosure,
indexes: indexes,
payingFeeIn: chainAssetId,
signingClosure: signingClosure
)
}
Expand Down
Loading

0 comments on commit bf17cfa

Please sign in to comment.