Skip to content

Commit

Permalink
Merge branch 'develop' into feature/IOS-7809_show_provider_slippage
Browse files Browse the repository at this point in the history
  • Loading branch information
Vyachesl0ve committed Oct 25, 2024
2 parents 541e898 + 6f64ea9 commit 41e296f
Show file tree
Hide file tree
Showing 738 changed files with 8,361 additions and 7,991 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,5 @@ fastlane/test_output/
fastlane/report.xml

# Generated
Tangem/Resources/Generated/Localizable+Generated.swift
Tangem/Resources/Generated/XCAssets+Generated.swift
Tangem/Resources/Generated/**.swift
BlockchainSdk/Resources/Generated/**.swift
6 changes: 2 additions & 4 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# file options
--exclude Pods
--exclude Tangem/Resources/Generated
--exclude BlockchainSdk/Resources/Generated
--exclude Utilites/XCTemplate
# // TODO: Andrey Fedorov - Apply formatting (IOS-8239)
--exclude BlockchainSdk
--exclude BlockchainSdkTests
--exclude BlockchainSdkExample
--exclude **/*.pb.swift # Protobufs

# Format options
# Disable all default options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct AlgorandExternalLinkProvider: ExternalLinkProvider {
}

private let isTestnet: Bool

private var baseExplorerHost: String {
if isTestnet {
return "explorer.bitquery.io/algorand_testnet"
Expand Down
30 changes: 15 additions & 15 deletions BlockchainSdk/Blockchains/Algorand/AlgorandNetworkService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ import Combine

class AlgorandNetworkService: MultiNetworkProvider {
// MARK: - Protperties

let blockchain: Blockchain
let providers: [AlgorandNetworkProvider]
var currentProviderIndex: Int = 0

// MARK: - Init

init(blockchain: Blockchain, providers: [AlgorandNetworkProvider]) {
self.blockchain = blockchain
self.providers = providers
}

// MARK: - Implementation

func getAccount(address: String) -> AnyPublisher<AlgorandAccountModel, Error> {
providerPublisher { provider in
provider
Expand All @@ -37,7 +37,7 @@ class AlgorandNetworkService: MultiNetworkProvider {
.eraseToAnyPublisher()
}
}

func getEstimatedFee() -> AnyPublisher<AlgorandEstimatedFeeParams, Error> {
providerPublisher { provider in
provider
Expand All @@ -46,7 +46,7 @@ class AlgorandNetworkService: MultiNetworkProvider {
.tryMap { service, response in
let sourceFee = Decimal(response.fee) / service.blockchain.decimalValue
let minFee = Decimal(response.minFee) / service.blockchain.decimalValue

return AlgorandEstimatedFeeParams(
minFee: Amount(with: service.blockchain, value: minFee),
fee: Amount(with: service.blockchain, value: sourceFee)
Expand All @@ -55,7 +55,7 @@ class AlgorandNetworkService: MultiNetworkProvider {
.eraseToAnyPublisher()
}
}

func getTransactionParams() -> AnyPublisher<AlgorandTransactionBuildParams, Error> {
providerPublisher { provider in
provider
Expand All @@ -65,20 +65,20 @@ class AlgorandNetworkService: MultiNetworkProvider {
guard let genesisHash = Data(base64Encoded: response.genesisHash) else {
throw WalletError.failedToParseNetworkResponse()
}

let transactionParams = AlgorandTransactionBuildParams(
genesisId: response.genesisId,
genesisHash: genesisHash,
firstRound: response.lastRound,
lastRound: response.lastRound + Constants.bounceRoundValue
)

return transactionParams
}
.eraseToAnyPublisher()
}
}

func sendTransaction(data: Data) -> AnyPublisher<String, Error> {
providerPublisher { provider in
provider
Expand All @@ -89,7 +89,7 @@ class AlgorandNetworkService: MultiNetworkProvider {
.eraseToAnyPublisher()
}
}

func getPendingTransaction(transactionHash: String) -> AnyPublisher<AlgorandTransactionInfo?, Error> {
return providerPublisher { provider in
return provider
Expand All @@ -102,7 +102,7 @@ class AlgorandNetworkService: MultiNetworkProvider {
guard let response = response, let confirmedRound = response.confirmedRound else {
return nil
}

if confirmedRound > 0 {
return AlgorandTransactionInfo(transactionHash: transactionHash, status: .committed)
} else if confirmedRound == 0, response.poolError.isEmpty {
Expand All @@ -123,11 +123,11 @@ class AlgorandNetworkService: MultiNetworkProvider {
private extension AlgorandNetworkService {
func calculateCoinValueWithReserveDeposit(from accountModel: AlgorandResponse.Account) -> AlgorandAccountModel {
let changeBalanceValue = max(Decimal(accountModel.amount) - Decimal(accountModel.minBalance), 0)

let decimalCoinValue = Decimal(accountModel.amount) / blockchain.decimalValue
let decimalReserveValue = Decimal(accountModel.minBalance) / blockchain.decimalValue
let decimalCoinWithReserveValue = changeBalanceValue / blockchain.decimalValue

return AlgorandAccountModel(
reserveValue: decimalReserveValue,
coinValue: decimalCoinValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ final class AlgorandTransactionBuilder {
private let curve: EllipticCurve
private let isTestnet: Bool
private var coinType: CoinType { .algorand }

private var decimalValue: Decimal {
Blockchain.algorand(curve: curve, testnet: isTestnet).decimalValue
}

// MARK: - Init

init(publicKey: Data, curve: EllipticCurve, isTestnet: Bool) {
self.publicKey = publicKey
self.curve = curve
self.isTestnet = isTestnet
}

// MARK: - Implementation

func buildForSign(transaction: Transaction, with params: AlgorandTransactionBuildParams) throws -> Data {
Expand Down Expand Up @@ -64,7 +64,7 @@ final class AlgorandTransactionBuilder {
signatures: signature.asDataVector(),
publicKeys: publicKey.asDataVector()
)

let signingOutput = try AlgorandSigningOutput(serializedData: compiledTransaction)

guard signingOutput.error == .ok, !signingOutput.encoded.isEmpty else {
Expand All @@ -87,7 +87,7 @@ final class AlgorandTransactionBuilder {
} catch {
throw WalletError.failedToBuildTx
}

let transfer = AlgorandTransfer.with {
$0.toAddress = transaction.destinationAddress
$0.amount = (transaction.amount.value * decimalValue).roundedDecimalNumber.uint64Value
Expand All @@ -103,7 +103,7 @@ final class AlgorandTransactionBuilder {
input.fee = (transaction.fee.amount.value * decimalValue).roundedDecimalNumber.uint64Value
input.transfer = transfer
}

return input
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct AlgorandWalletAssembly: WalletManagerAssembly {
curve: input.wallet.blockchain.curve,
isTestnet: input.blockchain.isTestnet
)

return try AlgorandWalletManager(
wallet: input.wallet,
transactionBuilder: transactionBuilder,
Expand Down
41 changes: 19 additions & 22 deletions BlockchainSdk/Blockchains/Algorand/AlgorandWalletManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ import Foundation
import Combine

final class AlgorandWalletManager: BaseManager {

// MARK: - Private Properties

private let transactionBuilder: AlgorandTransactionBuilder
private let networkService: AlgorandNetworkService

// MARK: - Init

init(wallet: Wallet, transactionBuilder: AlgorandTransactionBuilder, networkService: AlgorandNetworkService) throws {
self.transactionBuilder = transactionBuilder
self.networkService = networkService
super.init(wallet: wallet)
}

// MARK: - Implementation

override func update(completion: @escaping (Result<Void, Error>) -> Void) {
let transactionStatusesPublisher = wallet
.pendingTransactions
Expand All @@ -35,19 +34,18 @@ final class AlgorandWalletManager: BaseManager {
.flatMap { walletManager, transaction in
return walletManager.networkService.getPendingTransaction(transactionHash: transaction.hash)
}
.compactMap({$0})
.compactMap { $0 }
.collect()

let accountInfoPublisher = networkService
.getAccount(address: wallet.address)

cancellable = Publishers.CombineLatest(accountInfoPublisher, transactionStatusesPublisher)
.withWeakCaptureOf(self)
.tryMap { walletManager, input in
let (accountInfo, _) = input
try walletManager.validateMinimalBalanceAccount(with: accountInfo)
return input

}
.sink(receiveCompletion: { [weak self] result in
switch result {
Expand All @@ -57,12 +55,11 @@ final class AlgorandWalletManager: BaseManager {
case .finished:
completion(.success(()))
}
}, receiveValue: { [weak self] (accountInfo, transactionsInfo) in
}, receiveValue: { [weak self] accountInfo, transactionsInfo in
self?.update(with: accountInfo)
self?.updatePendingTransactions(with: transactionsInfo)
})
}

}

// MARK: - Private Implementation
Expand All @@ -72,24 +69,24 @@ private extension AlgorandWalletManager {
/*
Every account on Algorand must have a minimum balance of 100,000 microAlgos. If ever a transaction is sent that would result in a balance lower than the minimum, the transaction will fail. The minimum balance increases with each asset holding the account has (whether the asset was created or owned by the account) and with each application the account created or opted in. Destroying a created asset, opting out/closing out an owned asset, destroying a created app, or opting out an opted in app decreases accordingly the minimum balance.
*/

if accountModel.coinValue < accountModel.reserveValue {
let error = makeNoAccountError(using: accountModel)
throw error
}
}

func update(with accountModel: AlgorandAccountModel) {
wallet.add(coinValue: accountModel.coinValueWithReserveValue)
wallet.add(reserveValue: accountModel.reserveValue)
}

func updatePendingTransactions(with transactionInfo: [AlgorandTransactionInfo]) {
let completedTransactionHashes = transactionInfo
.filter { $0.status == .committed || $0.status == .removed }
.map { $0.transactionHash }
.toSet()

wallet.removePendingTransaction(where: completedTransactionHashes.contains(_:))
}
}
Expand Down Expand Up @@ -130,11 +127,11 @@ extension AlgorandWalletManager {
networkService
.getTransactionParams()
.withWeakCaptureOf(self)
.tryMap { (walletManager, params) in
.tryMap { walletManager, params in
let hashForSign = try walletManager.transactionBuilder.buildForSign(transaction: transaction, with: params)
return (hashForSign, params)
}
.flatMap { (hashForSign, params) in
.flatMap { hashForSign, params in
let signaturePublisher = signer.sign(hash: hashForSign, walletPublicKey: self.wallet.publicKey)
let transactionParamsPublisher = Just(params).setFailureType(to: Error.self)

Expand All @@ -143,13 +140,13 @@ extension AlgorandWalletManager {
.withWeakCaptureOf(self)
.tryMap { walletManager, input -> Data in
let (signature, buildParams) = input

let dataForSend = try walletManager.transactionBuilder.buildForSend(
transaction: transaction,
with: buildParams,
signature: signature
)

return dataForSend
}
.withWeakCaptureOf(self)
Expand All @@ -169,13 +166,13 @@ extension AlgorandWalletManager {
.eraseSendError()
.eraseToAnyPublisher()
}

private func makeNoAccountError(using accountModel: AlgorandAccountModel) -> WalletError {
let networkName = wallet.blockchain.displayName
let reserveValue = accountModel.reserveValue
let reserveValueString = reserveValue.decimalNumber.stringValue
let currencySymbol = wallet.blockchain.currencySymbol
let errorMessage = "no_account_generic".localized([networkName, reserveValueString, currencySymbol])
let errorMessage = Localization.noAccountGeneric(networkName, reserveValueString, currencySymbol)

return WalletError.noAccount(message: errorMessage, amountToCreate: reserveValue)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension AlgorandResponse {
let amount: UInt64
let minBalance: UInt64
let round: UInt64

/*
[onl] delegation status of the account's MicroAlgos
* Offline - indicates that the associated account is delegated.
Expand All @@ -34,8 +34,8 @@ extension AlgorandResponse {
}

private enum CodingKeys: String, CodingKey {
case address = "address"
case amount = "amount"
case address
case amount
case minBalance = "min-balance"
case round
case status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
extension AlgorandResponse {
struct Error: Decodable, LocalizedError {
let message: String

var errorDescription: String? {
message
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extension AlgorandResponse {
struct PendingTransaction: Decodable {
let confirmedRound: UInt64?
let poolError: String

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
confirmedRound = try container.decode(UInt64.self, forKey: .confirmedRound)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension AlgorandResponse {
let fee: UInt64
let lastRound: UInt64
let minFee: UInt64

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
genesisId = try container.decode(String.self, forKey: .genesisId)
Expand Down
Loading

0 comments on commit 41e296f

Please sign in to comment.