Skip to content

Commit

Permalink
Merge pull request #795 from novasamatech/develop
Browse files Browse the repository at this point in the history
v6.7.3
  • Loading branch information
ERussel authored Aug 21, 2023
2 parents 193d8f8 + e5a68b7 commit 8cfb6ac
Show file tree
Hide file tree
Showing 98 changed files with 2,324 additions and 716 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
name: Build and Test on PR

on:
pull_request_target:
types: [labeled]
# pull_request:
# branches: [ develop ]
pull_request:

jobs:
build:
Expand Down
6 changes: 4 additions & 2 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Nova - Polkadot, Kusama wallet

Copyright 2022 Novasama Technologies PTE. LTD.
Copyright 2022-2023 Novasama Technologies PTE. LTD.
This product includes software developed at Novasama Technologies PTE. LTD.

Some parts of this product are derived from https://github.com/soramitsu/fearless-iOS, which belongs to Soramitsu K.K. and was mostly developed by our team of developers from May 1, 2020, to October 5, 2021.
Expand All @@ -12,4 +12,6 @@ Notwithstanding the above, some works related to this product are licensed under
2) SoraUI: https://github.com/ERussel/UIkit-iOS.git;
3) RobinHood: https://github.com/soramitsu/robinhood-ios;
4) CommonWallet: https://github.com/ERussel/Capital-iOS.git;
5) SoraFoundation: https://github.com/soramitsu/Foundation-iOS.
5) SoraFoundation: https://github.com/soramitsu/Foundation-iOS.

License Rights transferred from Novasama Technologies PTE. LTD to Novasama Technologies GmbH starting from 1st of April 2023
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Developed by former Fearless Wallet team & based on open source work under Apach

## License
Nova Wallet iOS is available under the Apache 2.0 license. See the LICENSE file for more info.
© Novasama Technologies GmbH 2023
160 changes: 160 additions & 0 deletions novawallet.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions novawallet/Common/Crypto/BaseSigner.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Foundation
import IrohaCrypto
import SoraKeystore

class BaseSigner: SignatureCreatorProtocol, AuthorizationPresentable {
let settingsManager: SettingsManagerProtocol

init(settingsManager: SettingsManagerProtocol) {
self.settingsManager = settingsManager
}

func sign(_ originalData: Data) throws -> IRSignatureProtocol {
if settingsManager.pinConfirmationEnabled == true {
let signingResult = signAfterAutorization(originalData)
switch signingResult {
case let .success(signature):
return signature
case let .failure(error):
throw error
}
} else {
return try signData(originalData)
}
}

private func signAfterAutorization(_ originalData: Data) -> Result<IRSignatureProtocol, Error> {
let semaphore = DispatchSemaphore(value: 0)
var signResult: Result<IRSignatureProtocol, Error>?

DispatchQueue.main.async {
self.authorize(animated: true, cancellable: true) { [weak self] completed in
defer {
semaphore.signal()
}
guard let self = self else {
return
}
if completed {
do {
let sign = try self.signData(originalData)
signResult = .success(sign)
} catch {
signResult = .failure(error)
}
}
}
}

semaphore.wait()

return signResult ?? .failure(SigningWrapperError.pinCheckNotPassed)
}

func signData(_: Data) throws -> IRSignatureProtocol {
fatalError("Must be overriden by subsclass")
}
}
14 changes: 10 additions & 4 deletions novawallet/Common/Crypto/EthereumSigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@ import IrohaCrypto
import SoraKeystore
import SubstrateSdk

final class EthereumSigner: SignatureCreatorProtocol {
final class EthereumSigner: BaseSigner {
let keystore: KeystoreProtocol
let metaId: String
let accountId: AccountId?
let publicKeyData: Data

init(keystore: KeystoreProtocol, ethereumAccountResponse: MetaEthereumAccountResponse) {
init(
keystore: KeystoreProtocol,
ethereumAccountResponse: MetaEthereumAccountResponse,
settingsManager: SettingsManagerProtocol
) {
self.keystore = keystore
metaId = ethereumAccountResponse.metaId
accountId = ethereumAccountResponse.isChainAccount ? ethereumAccountResponse.address : nil
publicKeyData = ethereumAccountResponse.publicKey

super.init(settingsManager: settingsManager)
}

func sign(_ hashedData: Data) throws -> IRSignatureProtocol {
override func signData(_ data: Data) throws -> IRSignatureProtocol {
let tag = KeystoreTagV2.ethereumSecretKeyTagForMetaId(metaId, accountId: accountId)

let secretKey = try keystore.fetchKey(for: tag)
Expand All @@ -28,6 +34,6 @@ final class EthereumSigner: SignatureCreatorProtocol {

let signer = SECSigner(privateKey: privateKey)

return try signer.sign(hashedData)
return try signer.sign(data)
}
}
62 changes: 11 additions & 51 deletions novawallet/Common/Crypto/SigningWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ enum SigningWrapperError: Error {
case pinCheckNotPassed
}

final class SigningWrapper: SigningWrapperProtocol, AuthorizationPresentable {
final class SigningWrapper: BaseSigner, SigningWrapperProtocol {
let keystore: KeystoreProtocol
let metaId: String
let accountId: AccountId?
let isEthereumBased: Bool
let cryptoType: MultiassetCryptoType
let publicKeyData: Data
let settingsManager: SettingsManagerProtocol

init(
keystore: KeystoreProtocol,
Expand All @@ -33,7 +32,8 @@ final class SigningWrapper: SigningWrapperProtocol, AuthorizationPresentable {
self.cryptoType = cryptoType
self.isEthereumBased = isEthereumBased
self.publicKeyData = publicKeyData
self.settingsManager = settingsManager

super.init(settingsManager: settingsManager)
}

init(
Expand All @@ -48,7 +48,8 @@ final class SigningWrapper: SigningWrapperProtocol, AuthorizationPresentable {
isEthereumBased = accountResponse.isEthereumBased
cryptoType = accountResponse.cryptoType
publicKeyData = accountResponse.publicKey
self.settingsManager = settingsManager

super.init(settingsManager: settingsManager)
}

init(
Expand All @@ -62,52 +63,11 @@ final class SigningWrapper: SigningWrapperProtocol, AuthorizationPresentable {
isEthereumBased = true
cryptoType = MultiassetCryptoType.ethereumEcdsa
publicKeyData = ethereumAccountResponse.publicKey
self.settingsManager = settingsManager
}

func sign(_ originalData: Data) throws -> IRSignatureProtocol {
if settingsManager.pinConfirmationEnabled == true {
let signingResult = signAfterAutorization(originalData)
switch signingResult {
case let .success(signature):
return signature
case let .failure(error):
throw error
}
} else {
return try _sign(originalData)
}
}

private func signAfterAutorization(_ originalData: Data) -> Result<IRSignatureProtocol, Error> {
let semaphore = DispatchSemaphore(value: 0)
var signResult: Result<IRSignatureProtocol, Error>?

DispatchQueue.main.async {
self.authorize(animated: true, cancellable: true) { [weak self] completed in
defer {
semaphore.signal()
}
guard let self = self else {
return
}
if completed {
do {
let sign = try self._sign(originalData)
signResult = .success(sign)
} catch {
signResult = .failure(error)
}
}
}
}

semaphore.wait()

return signResult ?? .failure(SigningWrapperError.pinCheckNotPassed)
super.init(settingsManager: settingsManager)
}

private func _sign(_ originalData: Data) throws -> IRSignatureProtocol {
override func signData(_ data: Data) throws -> IRSignatureProtocol {
let tag: String = isEthereumBased ?
KeystoreTagV2.ethereumSecretKeyTagForMetaId(metaId, accountId: accountId) :
KeystoreTagV2.substrateSecretKeyTagForMetaId(metaId, accountId: accountId)
Expand All @@ -116,13 +76,13 @@ final class SigningWrapper: SigningWrapperProtocol, AuthorizationPresentable {

switch cryptoType {
case .sr25519:
return try signSr25519(originalData, secretKeyData: secretKey, publicKeyData: publicKeyData)
return try signSr25519(data, secretKeyData: secretKey, publicKeyData: publicKeyData)
case .ed25519:
return try signEd25519(originalData, secretKey: secretKey)
return try signEd25519(data, secretKey: secretKey)
case .substrateEcdsa:
return try signEcdsa(originalData, secretKey: secretKey)
return try signEcdsa(data, secretKey: secretKey)
case .ethereumEcdsa:
return try signEthereum(originalData, secretKey: secretKey)
return try signEthereum(data, secretKey: secretKey)
}
}
}
6 changes: 5 additions & 1 deletion novawallet/Common/Crypto/SigningWrapperFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ final class SigningWrapperFactory: SigningWrapperFactoryProtocol {
func createEthereumSigner(for ethereumAccountResponse: MetaEthereumAccountResponse) -> SignatureCreatorProtocol {
switch ethereumAccountResponse.type {
case .secrets:
return EthereumSigner(keystore: keystore, ethereumAccountResponse: ethereumAccountResponse)
return EthereumSigner(
keystore: keystore,
ethereumAccountResponse: ethereumAccountResponse,
settingsManager: settingsManager
)
case .watchOnly:
return NoKeysSigningWrapper()
case .paritySigner:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension NSPredicate {
if let filter = filter {
let filterPredicate = filterTransactionsByType(filter)

return NSCompoundPredicate(orPredicateWithSubpredicates: [filterPredicate, filterByAsset])
return NSCompoundPredicate(andPredicateWithSubpredicates: [filterByAsset, filterPredicate])
} else {
return filterByAsset
}
Expand Down Expand Up @@ -93,7 +93,7 @@ extension NSPredicate {
if let filter = filter {
let filterPredicate = filterTransactionsByType(filter)

return NSCompoundPredicate(orPredicateWithSubpredicates: [filterPredicate, filterByAsset])
return NSCompoundPredicate(andPredicateWithSubpredicates: [filterByAsset, filterPredicate])
} else {
return filterByAsset
}
Expand Down
22 changes: 22 additions & 0 deletions novawallet/Common/Model/ChainRegistry/LocalChain/ChainModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,28 @@ extension ChainModel {
)
}

func addingOrUpdating(asset: AssetModel) -> ChainModel {
let filteredAssets = assets.filter { $0.assetId != asset.assetId }
let newAssets = filteredAssets.union([asset])

return .init(
chainId: chainId,
parentId: parentId,
name: name,
assets: newAssets,
nodes: nodes,
nodeSwitchStrategy: nodeSwitchStrategy,
addressPrefix: addressPrefix,
types: types,
icon: icon,
options: options,
externalApis: externalApis,
explorers: explorers,
order: order,
additional: additional
)
}

func byChanging(assets: Set<AssetModel>? = nil, name: String? = nil) -> ChainModel {
let newAssets = assets ?? self.assets
let newName = name ?? self.name
Expand Down
7 changes: 7 additions & 0 deletions novawallet/Common/Model/FeeOutputModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Foundation
import BigInt

struct FeeOutputModel {
let value: BigUInt
let validationProvider: ExtrinsicValidationProviderProtocol?
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Core

struct EthereumBlockObject: Codable {
struct Transaction: Codable {
// swiftlint:disable:next nesting
enum CodingKeys: String, CodingKey {
case hash
case sender = "from"
Expand Down
13 changes: 10 additions & 3 deletions novawallet/Common/Network/Ethereum/EthereumOperationFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import SoraKeystore
import BigInt

protocol EthereumOperationFactoryProtocol {
func createGasLimitOperation(for transaction: EthereumTransaction) -> BaseOperation<String>
func createGasLimitOperation(for transaction: EthereumTransaction) -> BaseOperation<HexCodable<BigUInt>>

func createGasPriceOperation() -> BaseOperation<String>
func createGasPriceOperation() -> BaseOperation<HexCodable<BigUInt>>

func createTransactionsCountOperation(
for accountAddress: Data,
block: EthereumBlock
) -> BaseOperation<String>
) -> BaseOperation<HexCodable<BigUInt>>

func createSendTransactionOperation(
for transactionDataClosure: @escaping () throws -> Data
Expand All @@ -20,6 +20,12 @@ protocol EthereumOperationFactoryProtocol {
func createTransactionReceiptOperation(for transactionHash: String) -> BaseOperation<EthereumTransactionReceipt?>

func createBlockOperation(for blockNumber: BigUInt) -> RobinHood.BaseOperation<EthereumBlockObject>

func createReducedBlockOperation(
for blockOption: EthereumBlock
) -> RobinHood.BaseOperation<EthereumReducedBlockObject>

func createMaxPriorityPerGasOperation() -> BaseOperation<HexCodable<BigUInt>>
}

enum EthereumBlock: String {
Expand All @@ -35,4 +41,5 @@ enum EthereumMethod: String {
case sendRawTransaction = "eth_sendRawTransaction"
case transactionReceipt = "eth_getTransactionReceipt"
case blockByNumber = "eth_getBlockByNumber"
case maxPriorityFeePerGas = "eth_maxPriorityFeePerGas"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation
import BigInt

struct EthereumReducedBlockObject: Decodable {
@OptionHexCodable var baseFeePerGas: BigUInt?
}
Loading

0 comments on commit 8cfb6ac

Please sign in to comment.