From 2bec06b406aecca797f1f86cd14eacc5241704e1 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Fri, 14 Jul 2023 11:29:06 +0300 Subject: [PATCH 01/49] IOS-3913 add init commit for chia transaction builder --- BlockchainSdk.xcodeproj/project.pbxproj | 24 +++++++++++ .../Chia/ChiaNetworkProvider.swift | 15 +++++++ .../Chia/ChiaNetworkService.swift | 42 +++++++++++++++++++ .../Chia/ChiaNetworkUrl.swift | 13 ++++++ .../Chia/ChiaTransactionBuilder.swift | 12 ++++++ .../Chia/ChiaWalletManager.swift | 41 ++++++++++++++++++ 6 files changed, 147 insertions(+) create mode 100644 BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift create mode 100644 BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift create mode 100644 BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift create mode 100644 BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index b8afe1785..2ad9eace6 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 2D1976732A613AC3006C4D3E /* ChiaTransactionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */; }; + 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */; }; + 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */; }; + 2D19767A2A613B9A006C4D3E /* ChiaNetworkUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */; }; 2D29A7F729D5C2AE00359A0C /* TWPublicKeyType+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */; }; 2D3829C929D34A93001D4785 /* TWCoin+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829C829D34A93001D4785 /* TWCoin+.swift */; }; 2D3829CE29D350D1001D4785 /* AddressServiceManagerUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */; }; @@ -385,6 +389,10 @@ /* Begin PBXFileReference section */ 0C79DB7FEDD8D4029AFA208D /* Pods-BlockchainSdk.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BlockchainSdk.release.xcconfig"; path = "Target Support Files/Pods-BlockchainSdk/Pods-BlockchainSdk.release.xcconfig"; sourceTree = ""; }; + 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaTransactionBuilder.swift; sourceTree = ""; }; + 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkService.swift; sourceTree = ""; }; + 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkProvider.swift; sourceTree = ""; }; + 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkUrl.swift; sourceTree = ""; }; 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWPublicKeyType+.swift"; sourceTree = ""; }; 2D3829C829D34A93001D4785 /* TWCoin+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWCoin+.swift"; sourceTree = ""; }; 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressServiceManagerUtility.swift; sourceTree = ""; }; @@ -781,6 +789,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2D1976742A613B38006C4D3E /* Chia */ = { + isa = PBXGroup; + children = ( + 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */, + 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */, + 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */, + ); + path = Chia; + sourceTree = ""; + }; 2D535E7A2A0CC5FA0081EB76 /* Vectors */ = { isa = PBXGroup; children = ( @@ -806,6 +824,7 @@ children = ( 2D78F4092A5C3CBE00962CCA /* ChiaAddressService.swift */, 2D78F40B2A5C3CCF00962CCA /* ChiaWalletManager.swift */, + 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */, ); path = Chia; sourceTree = ""; @@ -1124,6 +1143,7 @@ 5D01BCE0243F7F6F0048D1BA /* XRP */, 2D9A919629BB8C1700476EA6 /* TON */, EF2BC61C29DAC62C003D3F18 /* Ravencoin */, + 2D1976742A613B38006C4D3E /* Chia */, ); path = BlockchainService; sourceTree = ""; @@ -2234,6 +2254,7 @@ E9941AC92927846B00399DE3 /* BlockBookTarget.swift in Sources */, 2DC5DAB429B9E6A10039154A /* WalletCoreSigner.swift in Sources */, 5D7D243325136254001B9A4F /* XRPAddress.swift in Sources */, + 2D19767A2A613B9A006C4D3E /* ChiaNetworkUrl.swift in Sources */, B0C34958267B83580027CC9D /* BitcoinModels.swift in Sources */, DA63B0A029CB3FC700AC6E49 /* KaspaAddressComponents.swift in Sources */, DA30812B2817BF3C00DE41F1 /* Tron.pb.swift in Sources */, @@ -2322,6 +2343,7 @@ 2DDE5BAB29C4F8D200A5B708 /* StellarWalletAssembly.swift in Sources */, 5D845511243DE9CD0072155E /* CardanoTransactionBuilder.swift in Sources */, 5DED72C423A1315F006D79AE /* StellarWalletManager.swift in Sources */, + 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */, 5D740B802625B42500DE9636 /* RskAddressService.swift in Sources */, EF9F9086299F88D1006F638F /* EthereumWalletManager.swift in Sources */, 5D8653FE23A8E486000DE52D /* StellarSdk+.swift in Sources */, @@ -2385,6 +2407,7 @@ EFD717CC2A25EB0B00E5430D /* ABIEncoder.swift in Sources */, 5DA6F7BC243F3C0B0040AB4B /* CBOR+.swift in Sources */, 2DDE5BA529C4F8D200A5B708 /* DogecoinWalletAssembly.swift in Sources */, + 2D1976732A613AC3006C4D3E /* ChiaTransactionBuilder.swift in Sources */, E95D95152929872B0068F876 /* BlockBookResponses.swift in Sources */, 5DA163D2273D2146007AA991 /* TezosJsonRpcProvider.swift in Sources */, EFD717B82A24B20700E5430D /* OptimismContract.swift in Sources */, @@ -2485,6 +2508,7 @@ DA82433D27A2B06500CFC2C0 /* PolkadotJsonRpcProvider.swift in Sources */, EF57BEDA2A1E625400C2A493 /* DerivationConfigV2.swift in Sources */, B00FBEDA2996A1B700FDB874 /* BlockscoutTarget.swift in Sources */, + 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift new file mode 100644 index 000000000..893827073 --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift @@ -0,0 +1,15 @@ +// +// ChiaNetworkProvider.swift +// BlockchainSdk +// +// Created by skibinalexander on 14.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct ChiaNetworkProvider: HostProvider { + + var host: String + +} diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift new file mode 100644 index 000000000..388d3e1fb --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift @@ -0,0 +1,42 @@ +// +// ChiaNetworkService.swift +// BlockchainSdk +// +// Created by skibinalexander on 14.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation +import Combine + +class ChiaNetworkService: MultiNetworkProvider { + + // MARK: - Protperties + + let providers: [ChiaNetworkProvider] + var currentProviderIndex: Int = 0 + + private var blockchain: Blockchain + + // MARK: - Init + + init(providers: [ChiaNetworkProvider], blockchain: Blockchain) { + self.providers = providers + self.blockchain = blockchain + } + + // MARK: - Implementation + + func getInfo(address: String) -> AnyPublisher { + return .emptyFail + } + + func getFee(address: String, message: String) -> AnyPublisher<[Fee], Error> { + return .emptyFail + } + + func send(message: String) -> AnyPublisher { + return .emptyFail + } + +} diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift new file mode 100644 index 000000000..257f84774 --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift @@ -0,0 +1,13 @@ +// +// ChiaNetworkUrl.swift +// BlockchainSdk +// +// Created by skibinalexander on 14.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct ChiaNetworkUrl { + +} diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift new file mode 100644 index 000000000..eca35d42e --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -0,0 +1,12 @@ +// +// ChiaTransactionBuilder.swift +// BlockchainSdk +// +// Created by skibinalexander on 14.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation +import CryptoKit + +final class ChiaTransactionBuilder {} diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index da2583f6e..9da77ed35 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -7,3 +7,44 @@ // import Foundation +import Combine +import TangemSdk +import WalletCore + +final class ChiaWalletManager: BaseManager, WalletManager { + + // MARK: - Properties + + var currentHost: String { networkService.host } + var allowsFeeSelection: Bool = false + + // MARK: - Private Properties + + private let networkService: ChiaNetworkService + + // MARK: - Init + + init(wallet: Wallet, networkService: ChiaNetworkService) throws { + self.networkService = networkService + super.init(wallet: wallet) + } + + // MARK: - Implementation + + func update(completion: @escaping (Result) -> Void) { + + } + + func send(_ transaction: Transaction, signer: TransactionSigner) -> AnyPublisher { + return .emptyFail + } + + func buildTransaction(input: TheOpenNetworkSigningInput, with signer: TransactionSigner? = nil) throws -> String { + throw WalletError.empty + } + + func getFee(amount: Amount, destination: String) -> AnyPublisher<[Fee], Error> { + return .emptyFail + } + +} From ca006208250c91063d5e42ba13043c672054f680 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Sun, 16 Jul 2023 00:49:20 +0300 Subject: [PATCH 02/49] IOS-3913 Add chia network provider implementation --- BlockchainSdk.xcodeproj/project.pbxproj | 40 ++++++++++++++---- .../Chia/ChiaNetworkProvider.swift | 15 ------- .../Chia/ChiaNetworkUrl.swift | 32 ++++++++++++++- .../Chia/Provider/ChiaNetworkProvider.swift | 41 +++++++++++++++++++ .../Chia/Provider/ChiaProviderResponse.swift | 21 ++++++++++ .../Chia/Provider/ChiaProviderTarget.swift | 25 +++++++++++ 6 files changed, 151 insertions(+), 23 deletions(-) delete mode 100644 BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift create mode 100644 BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift create mode 100644 BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift create mode 100644 BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index 249e490f8..f8ce5f553 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -11,6 +11,9 @@ 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */; }; 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */; }; 2D19767A2A613B9A006C4D3E /* ChiaNetworkUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */; }; + 2D19767E2A6331D3006C4D3E /* ClvmProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */; }; + 2D1976812A633EDD006C4D3E /* ChiaProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */; }; + 2D1976832A633EFA006C4D3E /* ChiaProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */; }; 2D29A7F729D5C2AE00359A0C /* TWPublicKeyType+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */; }; 2D3829C929D34A93001D4785 /* TWCoin+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829C829D34A93001D4785 /* TWCoin+.swift */; }; 2D3829CE29D350D1001D4785 /* AddressServiceManagerUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */; }; @@ -28,7 +31,6 @@ 2D78F40A2A5C3CBE00962CCA /* ChiaAddressService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D78F4092A5C3CBE00962CCA /* ChiaAddressService.swift */; }; 2D78F40C2A5C3CCF00962CCA /* ChiaWalletManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D78F40B2A5C3CCF00962CCA /* ChiaWalletManager.swift */; }; 2D78F40F2A5CA55100962CCA /* ChiaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D78F40E2A5CA55100962CCA /* ChiaTests.swift */; }; - 2D78F4142A5D955700962CCA /* ClvmProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D78F4132A5D955700962CCA /* ClvmProgram.swift */; }; 2D8501F729DEC20A00F4A11B /* TONTransactionParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8501F629DEC20A00F4A11B /* TONTransactionParams.swift */; }; 2D9A919229BB8BFF00476EA6 /* TONWalletInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A918D29BB8BFF00476EA6 /* TONWalletInfo.swift */; }; 2D9A919329BB8BFF00476EA6 /* TONTransactionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A918E29BB8BFF00476EA6 /* TONTransactionBuilder.swift */; }; @@ -393,6 +395,9 @@ 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkService.swift; sourceTree = ""; }; 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkProvider.swift; sourceTree = ""; }; 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkUrl.swift; sourceTree = ""; }; + 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClvmProgram.swift; sourceTree = ""; }; + 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderTarget.swift; sourceTree = ""; }; + 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderResponse.swift; sourceTree = ""; }; 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWPublicKeyType+.swift"; sourceTree = ""; }; 2D3829C829D34A93001D4785 /* TWCoin+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWCoin+.swift"; sourceTree = ""; }; 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressServiceManagerUtility.swift; sourceTree = ""; }; @@ -793,12 +798,30 @@ isa = PBXGroup; children = ( 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */, - 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */, 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */, + 2D19767F2A633C77006C4D3E /* Provider */, ); path = Chia; sourceTree = ""; }; + 2D19767C2A6331D3006C4D3E /* Common */ = { + isa = PBXGroup; + children = ( + 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */, + ); + path = Common; + sourceTree = ""; + }; + 2D19767F2A633C77006C4D3E /* Provider */ = { + isa = PBXGroup; + children = ( + 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */, + 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */, + 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */, + ); + path = Provider; + sourceTree = ""; + }; 2D535E7A2A0CC5FA0081EB76 /* Vectors */ = { isa = PBXGroup; children = ( @@ -822,10 +845,10 @@ 2D78F4082A5C3CA400962CCA /* Chia */ = { isa = PBXGroup; children = ( - 2D19767B2A613F27006C4D3E /* Common */, 2D78F4092A5C3CBE00962CCA /* ChiaAddressService.swift */, 2D78F40B2A5C3CCF00962CCA /* ChiaWalletManager.swift */, 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */, + 2D19767C2A6331D3006C4D3E /* Common */, ); path = Chia; sourceTree = ""; @@ -863,12 +886,12 @@ children = ( 2D9A919729BB8C1700476EA6 /* TONNetworkService.swift */, 2D9A919829BB8C1700476EA6 /* TONNetworkUrl.swift */, - 2D9A919929BB8C1700476EA6 /* TONProviderProvider */, + 2D9A919929BB8C1700476EA6 /* Provider */, ); path = TON; sourceTree = ""; }; - 2D9A919929BB8C1700476EA6 /* TONProviderProvider */ = { + 2D9A919929BB8C1700476EA6 /* Provider */ = { isa = PBXGroup; children = ( 2D9A919A29BB8C1700476EA6 /* TONProviderModels.swift */, @@ -877,7 +900,7 @@ 2D9A919D29BB8C1700476EA6 /* TONProvider.swift */, 2D9A919E29BB8C1700476EA6 /* TONProviderRequest.swift */, ); - path = TONProviderProvider; + path = Provider; sourceTree = ""; }; 2DBBE94E29C8DBD900971539 /* TON */ = { @@ -1837,6 +1860,7 @@ isa = PBXGroup; children = ( EF32FEBB2A306D40002ED43F /* DucatusNetworkParams.swift */, + 2D78F4132A5D955700962CCA /* ClvmProgram.swift */, ); name = "Recovered References"; sourceTree = ""; @@ -2275,7 +2299,6 @@ B044B3A126047F5500D9864F /* RosettaResponse.swift in Sources */, 5DACA35B255E97FE0096BC48 /* Address.swift in Sources */, DC4E442B29BF4B4C0088617C /* XRPBase58.swift in Sources */, - 2D78F4142A5D955700962CCA /* ClvmProgram.swift in Sources */, 5D7D2443251362AB001B9A4F /* BitcoinfeesTarget.swift in Sources */, B0BAEE9825FF1E0400F318A6 /* RosettaBody.swift in Sources */, DA198B6129E4090C00DB6EEA /* CosmosRestProvider.swift in Sources */, @@ -2399,6 +2422,7 @@ 2DDE5BA729C4F8D200A5B708 /* XRPWalletAssembly.swift in Sources */, DA570CF927A82322007F34EB /* PolkadotBlockchainMeta.swift in Sources */, 5D14E4972397B87000C15FC8 /* WalletManager.swift in Sources */, + 2D19767E2A6331D3006C4D3E /* ClvmProgram.swift in Sources */, DA9F76F127EC9C8300F0665C /* TronJsonRpcProvider.swift in Sources */, 5D4B33BC23F6EA0500C93A84 /* BlockchairTarget.swift in Sources */, 5D94E56723A3946C009C7482 /* Data+.swift in Sources */, @@ -2424,6 +2448,7 @@ 5DF8D5B5243DB80C00186BF0 /* CardanoAddressService.swift in Sources */, EF3FFFFD2A27740400C6E7D9 /* AdaliteUnspentOutputResponseDTO.swift in Sources */, 2D9A919529BB8BFF00476EA6 /* TONWalletManager.swift in Sources */, + 2D1976832A633EFA006C4D3E /* ChiaProviderResponse.swift in Sources */, 5DF91519253DB7B300B927DD /* TezosAddress.swift in Sources */, 5DF91521253DB89800B927DD /* TezosTarget.swift in Sources */, EFF56B4129C30265002B6952 /* EthereumFeeParameters.swift in Sources */, @@ -2493,6 +2518,7 @@ EF32FEC22A3072B9002ED43F /* CashAddrService.swift in Sources */, EF2BC62729DAD65F003D3F18 /* RavencoinTransactionInfo.swift in Sources */, EF666C2E2A2F3EE90044986F /* BitcoinLegacyAddressService.swift in Sources */, + 2D1976812A633EDD006C4D3E /* ChiaProviderTarget.swift in Sources */, DA570CEF27A802BE007F34EB /* SolanaError+.swift in Sources */, 5D4B33D323F7DF1F00C93A84 /* BinanceNetworkService.swift in Sources */, DA9F76EF27EC9BCD00F0665C /* TronNetworkService.swift in Sources */, diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift deleted file mode 100644 index 893827073..000000000 --- a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkProvider.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// ChiaNetworkProvider.swift -// BlockchainSdk -// -// Created by skibinalexander on 14.07.2023. -// Copyright © 2023 Tangem AG. All rights reserved. -// - -import Foundation - -struct ChiaNetworkProvider: HostProvider { - - var host: String - -} diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift index 257f84774..7906efcab 100644 --- a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkUrl.swift @@ -8,6 +8,36 @@ import Foundation -struct ChiaNetworkUrl { +enum ChiaEndpointType { + case fireacademy(isTestnet: Bool) +} + +struct ChiaNetworkEndpoint { + public let url: URL + public let apiKeyValue: String? + + init(url: URL, apiKeyValue: String?) { + self.url = url + self.apiKeyValue = apiKeyValue + } +} + +struct ChiaNetworkNode { + let apiKeyValue: String + let endpointType: ChiaEndpointType + + var endpoint: ChiaNetworkEndpoint { + switch endpointType { + case .fireacademy(let testnet): + let url = testnet ? + URL(string: "https://kraken.fireacademy.io/leaflet-testnet10/")! : + URL(string: "https://kraken.fireacademy.io/leaflet/")! + return ChiaNetworkEndpoint(url: url, apiKeyValue: apiKeyValue) + } + } + init(apiKeyValue: String, endpointType: ChiaEndpointType) { + self.apiKeyValue = apiKeyValue + self.endpointType = endpointType + } } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift new file mode 100644 index 000000000..7800cb461 --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift @@ -0,0 +1,41 @@ +// +// ChiaNetworkProvider.swift +// BlockchainSdk +// +// Created by skibinalexander on 14.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation +import Combine + +struct ChiaNetworkProvider: HostProvider { + + // MARK: - HostProvider + + /// Blockchain API host + var host: String { + node.endpoint.url.hostOrUnknown + } + + /// Configuration connection node for provider + private let node: ChiaNetworkNode + + // MARK: - Properties + + /// Network provider of blockchain + private let network: NetworkProvider + + // MARK: - Init + + init( + node: ChiaNetworkNode, + networkConfig: NetworkProviderConfiguration + ) { + self.node = node + self.network = .init(configuration: networkConfig) + } + + // MARK: - Implementation + +} diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift new file mode 100644 index 000000000..3a18e4d5f --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift @@ -0,0 +1,21 @@ +// +// ChiaProviderResponse.swift +// BlockchainSdk +// +// Created by skibinalexander on 15.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct ChiaCoinRecordsResponse: Decodable { + let coinRecords: [ChiaCoinRecordResponse] +} + +struct ChiaSendTransactionResponse: Decodable { + let status: String +} + +struct ChiaCoinRecordResponse: Decodable { + let coin: String +} diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift new file mode 100644 index 000000000..ea700dccd --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift @@ -0,0 +1,25 @@ +// +// ChiaProviderTarget.swift +// BlockchainSdk +// +// Created by skibinalexander on 15.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation +import Moya + +public struct ChiaProviderTarget: TargetType { + + public var baseURL: URL + + public var path: String + + public var method: Moya.Method + + public var task: Moya.Task + + public var headers: [String : String]? + + +} From 4b0ab1baa6fa5b668dd090f4dfb63f04eccfbf98 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Sun, 16 Jul 2023 12:01:02 +0300 Subject: [PATCH 03/49] IOS-3913 Revert wrong changes --- BlockchainSdk.xcodeproj/project.pbxproj | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index f8ce5f553..cafb82512 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -14,6 +14,11 @@ 2D19767E2A6331D3006C4D3E /* ClvmProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */; }; 2D1976812A633EDD006C4D3E /* ChiaProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */; }; 2D1976832A633EFA006C4D3E /* ChiaProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */; }; + 2D19768A2A63E82B006C4D3E /* TONProviderModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976852A63E82B006C4D3E /* TONProviderModels.swift */; }; + 2D19768B2A63E82B006C4D3E /* TONProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976862A63E82B006C4D3E /* TONProviderResponse.swift */; }; + 2D19768C2A63E82B006C4D3E /* TONProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976872A63E82B006C4D3E /* TONProviderTarget.swift */; }; + 2D19768D2A63E82B006C4D3E /* TONProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976882A63E82B006C4D3E /* TONProvider.swift */; }; + 2D19768E2A63E82B006C4D3E /* TONProviderRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976892A63E82B006C4D3E /* TONProviderRequest.swift */; }; 2D29A7F729D5C2AE00359A0C /* TWPublicKeyType+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */; }; 2D3829C929D34A93001D4785 /* TWCoin+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829C829D34A93001D4785 /* TWCoin+.swift */; }; 2D3829CE29D350D1001D4785 /* AddressServiceManagerUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */; }; @@ -38,11 +43,6 @@ 2D9A919529BB8BFF00476EA6 /* TONWalletManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919129BB8BFF00476EA6 /* TONWalletManager.swift */; }; 2D9A919F29BB8C1700476EA6 /* TONNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919729BB8C1700476EA6 /* TONNetworkService.swift */; }; 2D9A91A029BB8C1700476EA6 /* TONNetworkUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919829BB8C1700476EA6 /* TONNetworkUrl.swift */; }; - 2D9A91A129BB8C1700476EA6 /* TONProviderModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919A29BB8C1700476EA6 /* TONProviderModels.swift */; }; - 2D9A91A229BB8C1700476EA6 /* TONProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919B29BB8C1700476EA6 /* TONProviderResponse.swift */; }; - 2D9A91A329BB8C1700476EA6 /* TONProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919C29BB8C1700476EA6 /* TONProviderTarget.swift */; }; - 2D9A91A429BB8C1700476EA6 /* TONProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919D29BB8C1700476EA6 /* TONProvider.swift */; }; - 2D9A91A529BB8C1700476EA6 /* TONProviderRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A919E29BB8C1700476EA6 /* TONProviderRequest.swift */; }; 2D9A91A729BB8C2E00476EA6 /* WalletCoreAddressService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9A91A629BB8C2E00476EA6 /* WalletCoreAddressService.swift */; }; 2DA8AB0D2A433A1000C75D85 /* ExceptionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA8AB0C2A433A1000C75D85 /* ExceptionHandler.swift */; }; 2DBBE94D29C8686000971539 /* OptimismWalletAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBBE94C29C8686000971539 /* OptimismWalletAssembly.swift */; }; @@ -398,6 +398,11 @@ 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClvmProgram.swift; sourceTree = ""; }; 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderTarget.swift; sourceTree = ""; }; 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderResponse.swift; sourceTree = ""; }; + 2D1976852A63E82B006C4D3E /* TONProviderModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderModels.swift; sourceTree = ""; }; + 2D1976862A63E82B006C4D3E /* TONProviderResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderResponse.swift; sourceTree = ""; }; + 2D1976872A63E82B006C4D3E /* TONProviderTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderTarget.swift; sourceTree = ""; }; + 2D1976882A63E82B006C4D3E /* TONProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProvider.swift; sourceTree = ""; }; + 2D1976892A63E82B006C4D3E /* TONProviderRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderRequest.swift; sourceTree = ""; }; 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWPublicKeyType+.swift"; sourceTree = ""; }; 2D3829C829D34A93001D4785 /* TWCoin+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWCoin+.swift"; sourceTree = ""; }; 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressServiceManagerUtility.swift; sourceTree = ""; }; @@ -423,11 +428,6 @@ 2D9A919129BB8BFF00476EA6 /* TONWalletManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONWalletManager.swift; sourceTree = ""; }; 2D9A919729BB8C1700476EA6 /* TONNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONNetworkService.swift; sourceTree = ""; }; 2D9A919829BB8C1700476EA6 /* TONNetworkUrl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONNetworkUrl.swift; sourceTree = ""; }; - 2D9A919A29BB8C1700476EA6 /* TONProviderModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderModels.swift; sourceTree = ""; }; - 2D9A919B29BB8C1700476EA6 /* TONProviderResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderResponse.swift; sourceTree = ""; }; - 2D9A919C29BB8C1700476EA6 /* TONProviderTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderTarget.swift; sourceTree = ""; }; - 2D9A919D29BB8C1700476EA6 /* TONProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProvider.swift; sourceTree = ""; }; - 2D9A919E29BB8C1700476EA6 /* TONProviderRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderRequest.swift; sourceTree = ""; }; 2D9A91A629BB8C2E00476EA6 /* WalletCoreAddressService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletCoreAddressService.swift; sourceTree = ""; }; 2DA8AB0C2A433A1000C75D85 /* ExceptionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExceptionHandler.swift; sourceTree = ""; }; 2DBBE94C29C8686000971539 /* OptimismWalletAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimismWalletAssembly.swift; sourceTree = ""; }; @@ -822,6 +822,18 @@ path = Provider; sourceTree = ""; }; + 2D1976842A63E82B006C4D3E /* TONProviderProvider */ = { + isa = PBXGroup; + children = ( + 2D1976852A63E82B006C4D3E /* TONProviderModels.swift */, + 2D1976862A63E82B006C4D3E /* TONProviderResponse.swift */, + 2D1976872A63E82B006C4D3E /* TONProviderTarget.swift */, + 2D1976882A63E82B006C4D3E /* TONProvider.swift */, + 2D1976892A63E82B006C4D3E /* TONProviderRequest.swift */, + ); + path = TONProviderProvider; + sourceTree = ""; + }; 2D535E7A2A0CC5FA0081EB76 /* Vectors */ = { isa = PBXGroup; children = ( @@ -886,23 +898,11 @@ children = ( 2D9A919729BB8C1700476EA6 /* TONNetworkService.swift */, 2D9A919829BB8C1700476EA6 /* TONNetworkUrl.swift */, - 2D9A919929BB8C1700476EA6 /* Provider */, + 2D1976842A63E82B006C4D3E /* TONProviderProvider */, ); path = TON; sourceTree = ""; }; - 2D9A919929BB8C1700476EA6 /* Provider */ = { - isa = PBXGroup; - children = ( - 2D9A919A29BB8C1700476EA6 /* TONProviderModels.swift */, - 2D9A919B29BB8C1700476EA6 /* TONProviderResponse.swift */, - 2D9A919C29BB8C1700476EA6 /* TONProviderTarget.swift */, - 2D9A919D29BB8C1700476EA6 /* TONProvider.swift */, - 2D9A919E29BB8C1700476EA6 /* TONProviderRequest.swift */, - ); - path = Provider; - sourceTree = ""; - }; 2DBBE94E29C8DBD900971539 /* TON */ = { isa = PBXGroup; children = ( @@ -2256,10 +2256,10 @@ EF57BEE32A1E682D00C2A493 /* Blockchain+AllCases.swift in Sources */, EF332D1B288EB3D900AE3C85 /* NetworkProviderConfiguration.swift in Sources */, EF3FFFFE2A27740400C6E7D9 /* AdaliteBalanceResponseDTO.swift in Sources */, + 2D19768D2A63E82B006C4D3E /* TONProvider.swift in Sources */, DA2E770029769BF6001FF957 /* TransactionCreator.swift in Sources */, EF31EA1529DC31E000A59FBE /* RavencoinMainNetworkParams.swift in Sources */, B0EBBEF2265D0E7700D37141 /* DogecoinNetworkParams.swift in Sources */, - 2D9A91A329BB8C1700476EA6 /* TONProviderTarget.swift in Sources */, 2D9A919329BB8BFF00476EA6 /* TONTransactionBuilder.swift in Sources */, B0F9DCA125FB4C9B00C0AF18 /* MultiNetworkProvider.swift in Sources */, 5D7D243B25136254001B9A4F /* URandom.swift in Sources */, @@ -2273,7 +2273,6 @@ 5D88C809256BCD6C00020028 /* XRPTransactionParams.swift in Sources */, 5DED72C623A13377006D79AE /* StellarAddressService.swift in Sources */, EF31EA1829DC6B4700A59FBE /* RavencoinFee.swift in Sources */, - 2D9A91A529BB8C1700476EA6 /* TONProviderRequest.swift in Sources */, 5D7D242C25136254001B9A4F /* WebSocket.swift in Sources */, E9941AC92927846B00399DE3 /* BlockBookTarget.swift in Sources */, 2DC5DAB429B9E6A10039154A /* WalletCoreSigner.swift in Sources */, @@ -2286,7 +2285,6 @@ 5D4B33C823F72F2700C93A84 /* BitcoinCashWalletManager.swift in Sources */, 5D26CEF1243CB9EA00994CC0 /* BlockchainInfoResponse.swift in Sources */, EF332D19288EAEAC00AE3C85 /* NetworkProvider.swift in Sources */, - 2D9A91A429BB8C1700476EA6 /* TONProvider.swift in Sources */, 5D54FE1A23E41E5A009FAC2F /* LitecoinNetworkParams.swift in Sources */, 5D31EA2F27DA1C910031DBEB /* DetailedError.swift in Sources */, DA9F76EC27EC9A2900F0665C /* TronWalletManager.swift in Sources */, @@ -2306,6 +2304,7 @@ 5D26CEEE243CB95000994CC0 /* BlockcypherTarget.swift in Sources */, DA63B09A29CB3FC700AC6E49 /* KaspaNetworkModels.swift in Sources */, DA198B6329E41AD800DB6EEA /* CosmosNetworkService.swift in Sources */, + 2D19768A2A63E82B006C4D3E /* TONProviderModels.swift in Sources */, DA656FCC2954B5220092CC61 /* EthereumTarget.swift in Sources */, 5D7D243425136254001B9A4F /* XRPAccountInfo.swift in Sources */, EF0DA78C285246A90081092A /* DashMainNetworkParams.swift in Sources */, @@ -2341,7 +2340,6 @@ 5D6DEAB6243CC09A00510EC8 /* EthereumTransactionBuilder.swift in Sources */, DA9F76F527EC9CB400F0665C /* TronTarget.swift in Sources */, 5D7D243525136254001B9A4F /* XRPAmount.swift in Sources */, - 2D9A91A129BB8C1700476EA6 /* TONProviderModels.swift in Sources */, DA9EA73F29EE958500CAE6F2 /* CosmosTransactionParams.swift in Sources */, EF3FFFFF2A27740400C6E7D9 /* AdaliteBaseResponseDTO.swift in Sources */, B04DC65E25AC6538009AA7B3 /* EthereumAdditionalInfoProvider.swift in Sources */, @@ -2349,6 +2347,7 @@ 2DDE5BA829C4F8D200A5B708 /* BitcoinWalletAssembly.swift in Sources */, 5D03D2D0253DE61B009A8A9F /* TezosAddressService.swift in Sources */, 5D5CE0D52625C8EC009023EC /* XrpNetworkProvider.swift in Sources */, + 2D19768C2A63E82B006C4D3E /* TONProviderTarget.swift in Sources */, 5D94E56323A38204009C7482 /* EthereumAddressService.swift in Sources */, 2D9A91A029BB8C1700476EA6 /* TONNetworkUrl.swift in Sources */, E93532CE292D0E86008FD979 /* BlockBookUtxoProvider.swift in Sources */, @@ -2369,6 +2368,7 @@ 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */, 5D740B802625B42500DE9636 /* RskAddressService.swift in Sources */, EF9F9086299F88D1006F638F /* EthereumWalletManager.swift in Sources */, + 2D19768B2A63E82B006C4D3E /* TONProviderResponse.swift in Sources */, 5D8653FE23A8E486000DE52D /* StellarSdk+.swift in Sources */, DA82434127A2B0AD00CFC2C0 /* PolkadotTarget.swift in Sources */, 5D26CEF9243CBF2700994CC0 /* BitcoinNetworkProvider.swift in Sources */, @@ -2397,7 +2397,6 @@ 2DDE5BAD29C4F8D200A5B708 /* EthereumWalletAssembly.swift in Sources */, B0A63E0D26259D01001FDB7A /* EthereumTransactionParams.swift in Sources */, 5D7D243125136254001B9A4F /* XRPHistoricalTransaction.swift in Sources */, - 2D9A91A229BB8C1700476EA6 /* TONProviderResponse.swift in Sources */, B056729B2570F9DC00A8CB59 /* BlockchainSdkError.swift in Sources */, EF32FEE02A38D43A002ED43F /* BitcoinScriptAddressesProvider.swift in Sources */, DADF5F932A1B7C6B00D58DC3 /* TWPublicKey+.swift in Sources */, @@ -2452,6 +2451,7 @@ 5DF91519253DB7B300B927DD /* TezosAddress.swift in Sources */, 5DF91521253DB89800B927DD /* TezosTarget.swift in Sources */, EFF56B4129C30265002B6952 /* EthereumFeeParameters.swift in Sources */, + 2D19768E2A63E82B006C4D3E /* TONProviderRequest.swift in Sources */, B0C2C86725FBA10E00A61622 /* AnyPublisher+.swift in Sources */, EFD717D02A2619C400E5430D /* Wallet+PublicKey.swift in Sources */, 5DFF005F2521F772005203FB /* DucatusWalletManager.swift in Sources */, From e1666d1f16733a4bd7b78f3aa247a77aa0dc561d Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 18 Jul 2023 00:17:31 +0300 Subject: [PATCH 04/49] IOS-3913 Add implementation network service --- BlockchainSdk.xcodeproj/project.pbxproj | 8 +++ .../Chia/ChiaNetworkService.swift | 19 +++--- .../Chia/Provider/ChiaNetworkProvider.swift | 29 ++++++++ .../Chia/Provider/ChiaProviderResponse.swift | 2 +- .../Chia/Provider/ChiaProviderTarget.swift | 66 +++++++++++++++++-- .../Common/BlockchainSdkConfig.swift | 17 +++++ .../Derivations/DerivationConfigV1.swift | 2 +- .../Derivations/DerivationConfigV2.swift | 2 +- .../Derivations/DerivationConfigV3.swift | 2 +- .../WalletAssembly/ChiaWalletAssembly.swift | 21 +++++- BlockchainSdk/Extensions/JSONDecoder+.swift | 6 ++ .../Chia/ChiaAddressService.swift | 12 +--- .../Chia/ChiaTransactionBuilder.swift | 45 ++++++++++++- .../Chia/ChiaWalletManager.swift | 52 +++++++++++++-- .../Chia/Common/ChiaConstant.swift | 18 +++++ .../Chia/Common/ChiaModels.swift | 35 ++++++++++ .../BlockchainSdkExampleViewModel.swift | 5 ++ 17 files changed, 305 insertions(+), 36 deletions(-) create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index cafb82512..ff7830433 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 2D0F67902A6542EE000865A5 /* ChiaModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */; }; + 2D0F67922A658DBE000865A5 /* ChiaConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */; }; 2D1976732A613AC3006C4D3E /* ChiaTransactionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */; }; 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */; }; 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */; }; @@ -391,6 +393,8 @@ /* Begin PBXFileReference section */ 0C79DB7FEDD8D4029AFA208D /* Pods-BlockchainSdk.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BlockchainSdk.release.xcconfig"; path = "Target Support Files/Pods-BlockchainSdk/Pods-BlockchainSdk.release.xcconfig"; sourceTree = ""; }; + 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaModels.swift; sourceTree = ""; }; + 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaConstant.swift; sourceTree = ""; }; 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaTransactionBuilder.swift; sourceTree = ""; }; 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkService.swift; sourceTree = ""; }; 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkProvider.swift; sourceTree = ""; }; @@ -808,6 +812,8 @@ isa = PBXGroup; children = ( 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */, + 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */, + 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */, ); path = Common; sourceTree = ""; @@ -2392,7 +2398,9 @@ 2D535E892A0CC9920081EB76 /* TWCurve+.swift in Sources */, 5DC7DD60243F83E6008F83F2 /* XRPAddressService.swift in Sources */, B0CDFF252641488900B9BA9D /* EthereumJsonRpcProvider.swift in Sources */, + 2D0F67922A658DBE000865A5 /* ChiaConstant.swift in Sources */, 2DA8AB0D2A433A1000C75D85 /* ExceptionHandler.swift in Sources */, + 2D0F67902A6542EE000865A5 /* ChiaModels.swift in Sources */, DAD65BB02955F201003B3E8D /* EthereumApiKeys.swift in Sources */, 2DDE5BAD29C4F8D200A5B708 /* EthereumWalletAssembly.swift in Sources */, B0A63E0D26259D01001FDB7A /* EthereumTransactionParams.swift in Sources */, diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift index 388d3e1fb..965fd944e 100644 --- a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift @@ -27,16 +27,15 @@ class ChiaNetworkService: MultiNetworkProvider { // MARK: - Implementation - func getInfo(address: String) -> AnyPublisher { - return .emptyFail - } - - func getFee(address: String, message: String) -> AnyPublisher<[Fee], Error> { - return .emptyFail - } - - func send(message: String) -> AnyPublisher { - return .emptyFail + func getUnspents(puzzleHash: String) -> AnyPublisher<[ChiaCoin], Error> { + providerPublisher { provider in + provider + .getUnspents(puzzleHash: puzzleHash) + .map { response in + return response.map { $0.coin } + } + .eraseToAnyPublisher() + } } } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift index 7800cb461..abeda2a4d 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift @@ -38,4 +38,33 @@ struct ChiaNetworkProvider: HostProvider { // MARK: - Implementation + func getUnspents(puzzleHash: String) -> AnyPublisher<[ChiaCoinRecordResponse], Error> { + let target = ChiaProviderTarget( + node: node, + targetType: .getCoinRecordsBy(puzzleHashBody: .init(puzzleHash: puzzleHash)) + ) + + return requestPublisher(for: target) + } + + func sendTransaction(body: ChiaTransactionBody) -> AnyPublisher { + return .emptyFail + } + + // MARK: - Private Implementation + + private func requestPublisher(for target: ChiaProviderTarget) -> AnyPublisher { + let decoder = JSONDecoder() + decoder.keyDecodingStrategy = .convertFromSnakeCase + + return network.requestPublisher(target) + .filterSuccessfulStatusAndRedirectCodes() + .map(T.self, using: decoder) + .mapError { error in +// assertionFailure(error.localizedDescription) + return WalletError.empty + } + .eraseToAnyPublisher() + } + } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift index 3a18e4d5f..c6a4adb9b 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift @@ -17,5 +17,5 @@ struct ChiaSendTransactionResponse: Decodable { } struct ChiaCoinRecordResponse: Decodable { - let coin: String + let coin: ChiaCoin } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift index ea700dccd..2dbb6251d 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift @@ -9,17 +9,71 @@ import Foundation import Moya -public struct ChiaProviderTarget: TargetType { +struct ChiaProviderTarget: TargetType { + // MARK: - Properties - public var baseURL: URL + private let node: ChiaNetworkNode + private let targetType: TargetType + + // MARK: - Init + + init(node: ChiaNetworkNode, targetType: TargetType) { + self.node = node + self.targetType = targetType + } + + var baseURL: URL { + return node.endpoint.url + } - public var path: String + var path: String { + switch targetType { + case .getCoinRecordsBy: + return "get_coin_records_by_puzzle_hash" + case .sendTransaction: + return "push_tx" + } + } - public var method: Moya.Method + var method: Moya.Method { + return .post + } - public var task: Moya.Task + var task: Moya.Task { + let encoder = JSONEncoder() + encoder.keyEncodingStrategy = .convertToSnakeCase + + let jrpcRequest: Dictionary + + switch targetType { + case .getCoinRecordsBy(let puzzleHashBody): + jrpcRequest = (try? puzzleHashBody.asDictionary(with: encoder)) ?? [:] + default: + jrpcRequest = [:] + } + + return .requestParameters(parameters: jrpcRequest, encoding: JSONEncoding.default) + } - public var headers: [String : String]? + var headers: [String : String]? { + var headers: [String : String] = [ + "Accept": "application/json", + "Content-Type": "application/json" + ] + + if let apiKeyHeaderValue = node.endpoint.apiKeyValue { + headers["X-API-Key"] = apiKeyHeaderValue + } + + return headers + } } + +extension ChiaProviderTarget { + enum TargetType { + case getCoinRecordsBy(puzzleHashBody: ChiaPuzzleHashBody) + case sendTransaction(body: ChiaTransactionBody) + } +} diff --git a/BlockchainSdk/Common/BlockchainSdkConfig.swift b/BlockchainSdk/Common/BlockchainSdkConfig.swift index 4ece9e5ac..6e1dbfe93 100644 --- a/BlockchainSdk/Common/BlockchainSdkConfig.swift +++ b/BlockchainSdk/Common/BlockchainSdkConfig.swift @@ -17,6 +17,7 @@ public struct BlockchainSdkConfig { let kaspaSecondaryApiUrl: String? let tronGridApiKey: String let tonCenterApiKeys: TonCenterApiKeys + let fireacademyApiKeys: FireacamyApiKeys let quickNodeSolanaCredentials: QuickNodeCredentials let quickNodeBscCredentials: QuickNodeCredentials let blockscoutCredentials: NetworkProviderConfiguration.Credentials @@ -32,6 +33,7 @@ public struct BlockchainSdkConfig { kaspaSecondaryApiUrl: String?, tronGridApiKey: String, tonCenterApiKeys: TonCenterApiKeys, + fireacademyApiKeys: FireacamyApiKeys, quickNodeSolanaCredentials: QuickNodeCredentials, quickNodeBscCredentials: QuickNodeCredentials, blockscoutCredentials: NetworkProviderConfiguration.Credentials, @@ -46,6 +48,7 @@ public struct BlockchainSdkConfig { self.kaspaSecondaryApiUrl = kaspaSecondaryApiUrl self.tronGridApiKey = tronGridApiKey self.tonCenterApiKeys = tonCenterApiKeys + self.fireacademyApiKeys = fireacademyApiKeys self.quickNodeSolanaCredentials = quickNodeSolanaCredentials self.quickNodeBscCredentials = quickNodeBscCredentials self.blockscoutCredentials = blockscoutCredentials @@ -82,4 +85,18 @@ public extension BlockchainSdkConfig { return testnet ? testnetApiKey : mainnetApiKey } } + + struct FireacamyApiKeys { + let mainnetApiKey: String + let testnetApiKey: String + + public init(mainnetApiKey: String, testnetApiKey: String) { + self.mainnetApiKey = mainnetApiKey + self.testnetApiKey = testnetApiKey + } + + func getApiKey(for testnet: Bool) -> String { + return testnet ? testnetApiKey : mainnetApiKey + } + } } diff --git a/BlockchainSdk/Common/Derivations/DerivationConfigV1.swift b/BlockchainSdk/Common/Derivations/DerivationConfigV1.swift index fec6397dd..09e482d10 100644 --- a/BlockchainSdk/Common/Derivations/DerivationConfigV1.swift +++ b/BlockchainSdk/Common/Derivations/DerivationConfigV1.swift @@ -88,7 +88,7 @@ public struct DerivationConfigV1: DerivationConfig { case .telos: return [.default: "m/44'/977'/0'/0/0"] case .chia: - return [:] + return [.default: "m"] } } } diff --git a/BlockchainSdk/Common/Derivations/DerivationConfigV2.swift b/BlockchainSdk/Common/Derivations/DerivationConfigV2.swift index 2be769da5..f1b536300 100644 --- a/BlockchainSdk/Common/Derivations/DerivationConfigV2.swift +++ b/BlockchainSdk/Common/Derivations/DerivationConfigV2.swift @@ -80,7 +80,7 @@ public struct DerivationConfigV2: DerivationConfig { case .terraV1, .terraV2: return [.default: "m/44'/330'/0'/0/0"] case .chia: - return [:] + return [.default: "m"] } } } diff --git a/BlockchainSdk/Common/Derivations/DerivationConfigV3.swift b/BlockchainSdk/Common/Derivations/DerivationConfigV3.swift index 321f2ba8e..e2620aa07 100644 --- a/BlockchainSdk/Common/Derivations/DerivationConfigV3.swift +++ b/BlockchainSdk/Common/Derivations/DerivationConfigV3.swift @@ -85,7 +85,7 @@ public struct DerivationConfigV3: DerivationConfig { case .terraV1, .terraV2: return [.default: "m/44'/330'/0'/0/0"] case .chia: - return [:] + return [.default: "m"] } } } diff --git a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift index 0a5867507..14e773c21 100644 --- a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift +++ b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift @@ -10,6 +10,25 @@ import Foundation struct ChiaWalletAssembly: WalletManagerAssembly { func make(with input: WalletManagerAssemblyInput) throws -> WalletManager { - throw WalletError.empty + var providers: [ChiaNetworkProvider] = [] + + providers.append( + ChiaNetworkProvider( + node: .init( + apiKeyValue: input.blockchainConfig.fireacademyApiKeys.getApiKey(for: input.blockchain.isTestnet), + endpointType: .fireacademy(isTestnet: input.blockchain.isTestnet) + ), + networkConfig: input.networkConfig + ) + ) + + return try ChiaWalletManager( + wallet: input.wallet, + networkService: .init( + providers: providers, + blockchain: input.blockchain + ), + txBuilder: .init() + ) } } diff --git a/BlockchainSdk/Extensions/JSONDecoder+.swift b/BlockchainSdk/Extensions/JSONDecoder+.swift index 5a7a4e38c..7c8f00514 100644 --- a/BlockchainSdk/Extensions/JSONDecoder+.swift +++ b/BlockchainSdk/Extensions/JSONDecoder+.swift @@ -25,4 +25,10 @@ extension Encodable { let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) return dictionary as? [String: Any] ?? [:] } + + func asDictionary(with encoder: JSONEncoder) throws -> [String: Any] { + let data = try encoder.encode(self) + let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) + return dictionary as? [String: Any] ?? [:] + } } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift index 03b37ab95..628fd9d80 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift @@ -17,12 +17,12 @@ public struct ChiaAddressService: AddressService { private(set) var isTestnet: Bool - private let constans = ChiaAddressService.Constans.self + private let constants = ChiaConstant.self // MARK: - Implementation public func makeAddress(for publicKey: Wallet.PublicKey, with addressType: AddressType) throws -> PlainAddress { - let puzzle = Data(hex: constans.puzzleReveal.rawValue) + (publicKey.blockchainKey) + Data(hex: constans.fingerprint.rawValue) + let puzzle = constants.getPuzzle(walletPublicKey: publicKey.blockchainKey) let puzzleHash = try ClvmNode.Decoder(programBytes: puzzle.bytes).deserialize().hash() let hrp = HRP(isTestnet: isTestnet).rawValue @@ -40,7 +40,6 @@ public struct ChiaAddressService: AddressService { return false } } - } extension ChiaAddressService { @@ -58,10 +57,3 @@ extension ChiaAddressService { case invalidHumanReadablePart } } - -extension ChiaAddressService { - enum Constans: String { - case puzzleReveal = "ff02ffff01ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0" - case fingerprint = "ff018080" - } -} diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index eca35d42e..995930e82 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -9,4 +9,47 @@ import Foundation import CryptoKit -final class ChiaTransactionBuilder {} +final class ChiaTransactionBuilder { + // MARK: - Properties + + let unspentCoins: [String] + + // MARK: - Init + + init(unspentCoins: [String] = []) { + self.unspentCoins = unspentCoins + } + + // MARK: - Implementation + + /// Build input for sign transaction from Parameters + /// - Parameters: + /// - amount: Amount transaction + /// - destination: Destination address transaction + /// - Returns: Array of bytes for transaction + func buildForSign(amount: Amount, destination: String) throws -> Data { + throw WalletError.empty + } + + func buildToSend(signatures: Data) throws -> ChiaTransactionBody { + throw WalletError.empty + } + + // MARK: - Private Implementation + + private func toChiaCoinSpends( + unspentCoins: [ChiaCoin], + change: Int64 + ) throws -> [ChiaCoinSpend] { + throw WalletError.empty + } + + private func calculateChange( + amount: Amount, + destination: String, + unspentCoins: [String] + ) throws -> UInt64 { + throw WalletError.empty + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 9da77ed35..9b2d46674 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -21,25 +21,69 @@ final class ChiaWalletManager: BaseManager, WalletManager { // MARK: - Private Properties private let networkService: ChiaNetworkService + private let txBuilder: ChiaTransactionBuilder + private let puzzleHash: String // MARK: - Init - init(wallet: Wallet, networkService: ChiaNetworkService) throws { + init(wallet: Wallet, networkService: ChiaNetworkService, txBuilder: ChiaTransactionBuilder) throws { self.networkService = networkService + self.txBuilder = txBuilder + self.puzzleHash = ChiaConstant.getPuzzle(walletPublicKey: wallet.publicKey.blockchainKey).hex super.init(wallet: wallet) } // MARK: - Implementation func update(completion: @escaping (Result) -> Void) { - + cancellable = networkService + .getUnspents(puzzleHash: puzzleHash) + .sink( + receiveCompletion: { [unowned self] completionSubscription in + if case let .failure(error) = completionSubscription { + // TODO: - Hander error completion + completion(.failure(error)) + } + }, + receiveValue: { [unowned self] response in + print(response) + completion(.success(())) + } + ) } func send(_ transaction: Transaction, signer: TransactionSigner) -> AnyPublisher { - return .emptyFail + Just(()) + .receive(on: DispatchQueue.global()) + .tryMap { [weak self] _ -> String in + guard let self = self else { + throw WalletError.failedToBuildTx + } + + let input = try self.txBuilder.buildForSign( + amount: transaction.amount, + destination: transaction.destinationAddress + ) + + throw WalletError.empty + } + .flatMap { [weak self] message -> AnyPublisher in + guard let self = self else { + return Fail(error: WalletError.failedToBuildTx).eraseToAnyPublisher() + } + + return .emptyFail + +// return self.networkService.send(message: message) + } + .map { [weak self] hash in + self?.wallet.add(transaction: transaction) + return TransactionSendResult(hash: hash) + } + .eraseToAnyPublisher() } - func buildTransaction(input: TheOpenNetworkSigningInput, with signer: TransactionSigner? = nil) throws -> String { + func build(transaction: TheOpenNetworkSigningInput, with signer: TransactionSigner? = nil) throws -> String { throw WalletError.empty } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift new file mode 100644 index 000000000..76eefb9d7 --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift @@ -0,0 +1,18 @@ +// +// ChiaConstans.swift +// BlockchainSdk +// +// Created by skibinalexander on 17.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +enum ChiaConstant: String { + case puzzleReveal = "ff02ffff01ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0" + case fingerprint = "ff018080" + + static func getPuzzle(walletPublicKey: Data) -> Data { + return Data(hex: ChiaConstant.puzzleReveal.rawValue) + walletPublicKey + Data(hex: ChiaConstant.fingerprint.rawValue) + } +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift new file mode 100644 index 000000000..24df27aca --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift @@ -0,0 +1,35 @@ +// +// ChiaModels.swift +// BlockchainSdk +// +// Created by skibinalexander on 17.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct ChiaPuzzleHashBody: Encodable { + let puzzleHash: String +} + +struct ChiaTransactionBody { + let spendBundle: ChiaSpendBundle +} + +struct ChiaSpendBundle { + let aggregatedSignature: String + let coinSpends: ChiaCoinSpend +} + +struct ChiaCoinSpend { + let coin: ChiaCoin + let puzzleReveal: String + let solution: String +} + +struct ChiaCoin: Decodable { + // Has to be encoded as a number in JSON, therefore Long is used. It's enough to encode ~1/3 of Chia total supply. + let amount: Int64 + let parentCoinInfo: String + let puzzleHash: String +} diff --git a/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift b/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift index 03ecfdb2c..5ca2c4a21 100644 --- a/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift +++ b/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift @@ -70,6 +70,10 @@ class BlockchainSdkExampleViewModel: ObservableObject { kaspaSecondaryApiUrl: nil, tronGridApiKey: "", tonCenterApiKeys: .init(mainnetApiKey: "", testnetApiKey: ""), + fireacademyApiKeys: .init( + mainnetApiKey: "be200a1d-2b9f-4716-b428-d393f564e999", + testnetApiKey: "be200a1d-2b9f-4716-b428-d393f564e999" + ), quickNodeSolanaCredentials: .init(apiKey: "", subdomain: ""), quickNodeBscCredentials: .init(apiKey: "", subdomain: ""), blockscoutCredentials: .init(login: "", password: ""), @@ -462,6 +466,7 @@ class BlockchainSdkExampleViewModel: ObservableObject { .terraV1, .terraV2, .cronos, + .chia(testnet: false) ] return blockchains.map { ($0.displayName, $0.codingKey) } From bd2987d5c095b745843b79927d51277943d6fa3d Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 18 Jul 2023 20:18:21 +0300 Subject: [PATCH 05/49] IOS-3913 Add implementation chia transaction sign builder --- BlockchainSdk.xcodeproj/project.pbxproj | 16 ++++-- .../Chia/ChiaNetworkService.swift | 2 +- .../Chia/Provider/ChiaNetworkProvider.swift | 4 +- .../Chia/Provider/ChiaProviderRequests.swift | 17 ++++++ ...onse.swift => ChiaProviderResponses.swift} | 8 ++- BlockchainSdk/Common/Blockchain.swift | 4 +- .../WalletAssembly/ChiaWalletAssembly.swift | 4 +- .../Extensions/BlockchainUtils/Bech32.swift | 3 +- BlockchainSdk/Extensions/Decimal+.swift | 4 ++ .../Chia/ChiaAddressService.swift | 14 +---- .../Chia/ChiaTransactionBuilder.swift | 52 ++++++++++++++----- .../Chia/ChiaWalletManager.swift | 25 +++++++-- .../Chia/Common/ChiaConstant.swift | 23 ++++++++ .../Chia/Common/ChiaCreateCoinCondition.swift | 20 +++++++ .../Chia/Common/ChiaModels.swift | 14 ++--- 15 files changed, 156 insertions(+), 54 deletions(-) create mode 100644 BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderRequests.swift rename BlockchainSdk/BlockchainService/Chia/Provider/{ChiaProviderResponse.swift => ChiaProviderResponses.swift} (69%) create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index ff7830433..771773c01 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -9,13 +9,15 @@ /* Begin PBXBuildFile section */ 2D0F67902A6542EE000865A5 /* ChiaModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */; }; 2D0F67922A658DBE000865A5 /* ChiaConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */; }; + 2D0F67962A66C036000865A5 /* ChiaProviderRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67952A66C036000865A5 /* ChiaProviderRequests.swift */; }; + 2D0F67982A66C491000865A5 /* ChiaCreateCoinCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */; }; 2D1976732A613AC3006C4D3E /* ChiaTransactionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */; }; 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */; }; 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */; }; 2D19767A2A613B9A006C4D3E /* ChiaNetworkUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */; }; 2D19767E2A6331D3006C4D3E /* ClvmProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */; }; 2D1976812A633EDD006C4D3E /* ChiaProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */; }; - 2D1976832A633EFA006C4D3E /* ChiaProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */; }; + 2D1976832A633EFA006C4D3E /* ChiaProviderResponses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976822A633EFA006C4D3E /* ChiaProviderResponses.swift */; }; 2D19768A2A63E82B006C4D3E /* TONProviderModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976852A63E82B006C4D3E /* TONProviderModels.swift */; }; 2D19768B2A63E82B006C4D3E /* TONProviderResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976862A63E82B006C4D3E /* TONProviderResponse.swift */; }; 2D19768C2A63E82B006C4D3E /* TONProviderTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976872A63E82B006C4D3E /* TONProviderTarget.swift */; }; @@ -395,13 +397,15 @@ 0C79DB7FEDD8D4029AFA208D /* Pods-BlockchainSdk.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BlockchainSdk.release.xcconfig"; path = "Target Support Files/Pods-BlockchainSdk/Pods-BlockchainSdk.release.xcconfig"; sourceTree = ""; }; 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaModels.swift; sourceTree = ""; }; 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaConstant.swift; sourceTree = ""; }; + 2D0F67952A66C036000865A5 /* ChiaProviderRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderRequests.swift; sourceTree = ""; }; + 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaCreateCoinCondition.swift; sourceTree = ""; }; 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaTransactionBuilder.swift; sourceTree = ""; }; 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkService.swift; sourceTree = ""; }; 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkProvider.swift; sourceTree = ""; }; 2D1976792A613B9A006C4D3E /* ChiaNetworkUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkUrl.swift; sourceTree = ""; }; 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClvmProgram.swift; sourceTree = ""; }; 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderTarget.swift; sourceTree = ""; }; - 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderResponse.swift; sourceTree = ""; }; + 2D1976822A633EFA006C4D3E /* ChiaProviderResponses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderResponses.swift; sourceTree = ""; }; 2D1976852A63E82B006C4D3E /* TONProviderModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderModels.swift; sourceTree = ""; }; 2D1976862A63E82B006C4D3E /* TONProviderResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderResponse.swift; sourceTree = ""; }; 2D1976872A63E82B006C4D3E /* TONProviderTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderTarget.swift; sourceTree = ""; }; @@ -812,6 +816,7 @@ isa = PBXGroup; children = ( 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */, + 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */, 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */, 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */, ); @@ -823,7 +828,8 @@ children = ( 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */, 2D1976802A633EDD006C4D3E /* ChiaProviderTarget.swift */, - 2D1976822A633EFA006C4D3E /* ChiaProviderResponse.swift */, + 2D1976822A633EFA006C4D3E /* ChiaProviderResponses.swift */, + 2D0F67952A66C036000865A5 /* ChiaProviderRequests.swift */, ); path = Provider; sourceTree = ""; @@ -2329,6 +2335,8 @@ 2D29A7F729D5C2AE00359A0C /* TWPublicKeyType+.swift in Sources */, DA67A69629E51FEA001B6799 /* CosmosWalletManager.swift in Sources */, 2D78F40C2A5C3CCF00962CCA /* ChiaWalletManager.swift in Sources */, + 2D0F67962A66C036000865A5 /* ChiaProviderRequests.swift in Sources */, + 2D0F67982A66C491000865A5 /* ChiaCreateCoinCondition.swift in Sources */, DAB87CB1297ADCDC00FF30EB /* GetBlockBlockBookConfig.swift in Sources */, EF0DA78D285246A90081092A /* DashWalletManager.swift in Sources */, EF32FEBF2A306E51002ED43F /* AddressService.swift in Sources */, @@ -2455,7 +2463,7 @@ 5DF8D5B5243DB80C00186BF0 /* CardanoAddressService.swift in Sources */, EF3FFFFD2A27740400C6E7D9 /* AdaliteUnspentOutputResponseDTO.swift in Sources */, 2D9A919529BB8BFF00476EA6 /* TONWalletManager.swift in Sources */, - 2D1976832A633EFA006C4D3E /* ChiaProviderResponse.swift in Sources */, + 2D1976832A633EFA006C4D3E /* ChiaProviderResponses.swift in Sources */, 5DF91519253DB7B300B927DD /* TezosAddress.swift in Sources */, 5DF91521253DB89800B927DD /* TezosTarget.swift in Sources */, EFF56B4129C30265002B6952 /* EthereumFeeParameters.swift in Sources */, diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift index 965fd944e..d13e32d8a 100644 --- a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift @@ -32,7 +32,7 @@ class ChiaNetworkService: MultiNetworkProvider { provider .getUnspents(puzzleHash: puzzleHash) .map { response in - return response.map { $0.coin } + return response.coinRecords.map { $0.coin } } .eraseToAnyPublisher() } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift index abeda2a4d..5c5e9c538 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift @@ -38,7 +38,7 @@ struct ChiaNetworkProvider: HostProvider { // MARK: - Implementation - func getUnspents(puzzleHash: String) -> AnyPublisher<[ChiaCoinRecordResponse], Error> { + func getUnspents(puzzleHash: String) -> AnyPublisher { let target = ChiaProviderTarget( node: node, targetType: .getCoinRecordsBy(puzzleHashBody: .init(puzzleHash: puzzleHash)) @@ -61,7 +61,7 @@ struct ChiaNetworkProvider: HostProvider { .filterSuccessfulStatusAndRedirectCodes() .map(T.self, using: decoder) .mapError { error in -// assertionFailure(error.localizedDescription) + print(error.localizedDescription) return WalletError.empty } .eraseToAnyPublisher() diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderRequests.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderRequests.swift new file mode 100644 index 000000000..ff385af60 --- /dev/null +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderRequests.swift @@ -0,0 +1,17 @@ +// +// ChiaProviderRequests.swift +// BlockchainSdk +// +// Created by skibinalexander on 18.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct ChiaPuzzleHashBody: Encodable { + let puzzleHash: String +} + +struct ChiaTransactionBody: Encodable { + let spendBundle: ChiaSpendBundle +} diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift similarity index 69% rename from BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift rename to BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift index c6a4adb9b..5b0f2e1a0 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponse.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift @@ -8,14 +8,18 @@ import Foundation +enum ChiaStatusResponse: String, Decodable { + case success, error +} + struct ChiaCoinRecordsResponse: Decodable { - let coinRecords: [ChiaCoinRecordResponse] + let coinRecords: [ChiaCoinRecord] } struct ChiaSendTransactionResponse: Decodable { let status: String } -struct ChiaCoinRecordResponse: Decodable { +struct ChiaCoinRecord: Decodable { let coin: ChiaCoin } diff --git a/BlockchainSdk/Common/Blockchain.swift b/BlockchainSdk/Common/Blockchain.swift index 5073ae00e..f1e6f0372 100644 --- a/BlockchainSdk/Common/Blockchain.swift +++ b/BlockchainSdk/Common/Blockchain.swift @@ -223,8 +223,8 @@ public enum Blockchain: Equatable, Hashable { return "CRO" case .telos: return "TLOS" - case .chia: - return "XCH" + case .chia(let testnet): + return testnet ? "TXCH" : "XCH" } } diff --git a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift index 14e773c21..eada4764e 100644 --- a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift +++ b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift @@ -28,7 +28,9 @@ struct ChiaWalletAssembly: WalletManagerAssembly { providers: providers, blockchain: input.blockchain ), - txBuilder: .init() + txBuilder: .init( + walletPublicKey: input.wallet.publicKey.blockchainKey + ) ) } } diff --git a/BlockchainSdk/Extensions/BlockchainUtils/Bech32.swift b/BlockchainSdk/Extensions/BlockchainUtils/Bech32.swift index 6e2af2443..4d1c3918b 100644 --- a/BlockchainSdk/Extensions/BlockchainUtils/Bech32.swift +++ b/BlockchainSdk/Extensions/BlockchainUtils/Bech32.swift @@ -53,6 +53,7 @@ public class Bech32 { chk ^= ((top >> i) & 1) == 0 ? 0 : gen[Int(i)] } } + return chk } @@ -75,7 +76,7 @@ public class Bech32 { private func verifyChecksum(hrp: String, checksum: Data) -> Bool { var data = expandHrp(hrp) data.append(checksum) - return polymod(data) == 1 + return polymod(data) == constant.rawValue } /// Create checksum diff --git a/BlockchainSdk/Extensions/Decimal+.swift b/BlockchainSdk/Extensions/Decimal+.swift index 55c853cc7..428bc4541 100644 --- a/BlockchainSdk/Extensions/Decimal+.swift +++ b/BlockchainSdk/Extensions/Decimal+.swift @@ -59,4 +59,8 @@ extension Decimal { var uint64Value: UInt64 { (self as NSDecimalNumber).uint64Value } + + var int64Value: Int64 { + (self as NSDecimalNumber).int64Value + } } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift index 628fd9d80..cf9183fa1 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift @@ -25,7 +25,7 @@ public struct ChiaAddressService: AddressService { let puzzle = constants.getPuzzle(walletPublicKey: publicKey.blockchainKey) let puzzleHash = try ClvmNode.Decoder(programBytes: puzzle.bytes).deserialize().hash() - let hrp = HRP(isTestnet: isTestnet).rawValue + let hrp = ChiaConstant.HRP(isTestnet: isTestnet).rawValue let encodeValue = Bech32(constant: .bech32m).encode(hrp, values: puzzleHash) return .init(value: encodeValue, publicKey: publicKey, type: addressType) @@ -34,7 +34,7 @@ public struct ChiaAddressService: AddressService { public func validate(_ address: String) -> Bool { do { let result = try Bech32(constant: .bech32m).decode(address) - return HRP(isTestnet: isTestnet).rawValue == result.hrp + return ChiaConstant.HRP(isTestnet: isTestnet).rawValue == result.hrp } catch { assertionFailure(error.localizedDescription) return false @@ -42,16 +42,6 @@ public struct ChiaAddressService: AddressService { } } -extension ChiaAddressService { - enum HRP: String { - case txch, xch - - init(isTestnet: Bool) { - self = isTestnet ? .txch : .xch - } - } -} - extension ChiaAddressService { enum ChiaAddressError: Error { case invalidHumanReadablePart diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 995930e82..77487b334 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -10,13 +10,19 @@ import Foundation import CryptoKit final class ChiaTransactionBuilder { - // MARK: - Properties + // MARK: - Public Properties - let unspentCoins: [String] + var unspentCoins: [ChiaCoin] + + // MARK: - Private Properties + + private let walletPublicKey: Data + private var coinSpends: [ChiaCoinSpend] = [] // MARK: - Init - init(unspentCoins: [String] = []) { + init(walletPublicKey: Data, unspentCoins: [ChiaCoin] = []) { + self.walletPublicKey = walletPublicKey self.unspentCoins = unspentCoins } @@ -28,7 +34,25 @@ final class ChiaTransactionBuilder { /// - destination: Destination address transaction /// - Returns: Array of bytes for transaction func buildForSign(amount: Amount, destination: String) throws -> Data { - throw WalletError.empty + guard !unspentCoins.isEmpty else { + throw WalletError.failedToBuildTx + } + + let change = try calculateChange(amount: amount, destination: destination) + let coinSpends = try toChiaCoinSpends(change: change, destination: destination, amount: amount) + + let hashesForSign = coinSpends.map { _ in +// let solutionHash = ClvmNode.Decoder( +// programBytes: Data(hex: $0.solution).dro .hexToBytes().drop(1).dropLast(1).toByteArray() +// ).deserialize().hash() + +// (solutionHash + it.coin.calculateId() + genesisChallenge).hashAugScheme() +// return Data() + } + +// return Data(hashesForSign) + + return Data() } func buildToSend(signatures: Data) throws -> ChiaTransactionBody { @@ -37,18 +61,20 @@ final class ChiaTransactionBuilder { // MARK: - Private Implementation - private func toChiaCoinSpends( - unspentCoins: [ChiaCoin], - change: Int64 - ) throws -> [ChiaCoinSpend] { + private func toChiaCoinSpends(change: Int64, destination: String, amount: Amount) throws -> [ChiaCoinSpend] { + let coinSpends = unspentCoins.map { + ChiaCoinSpend(coin: $0, puzzleReveal: ChiaConstant.getPuzzle(walletPublicKey: walletPublicKey).hex, solution: "") + } + + let sendCondition = try CreateCoinCondition( + destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: destination), + amount: amount.value.int64Value + ) + throw WalletError.empty } - private func calculateChange( - amount: Amount, - destination: String, - unspentCoins: [String] - ) throws -> UInt64 { + private func calculateChange(amount: Amount, destination: String) throws -> Int64 { throw WalletError.empty } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 9b2d46674..4a1f19a58 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -29,7 +29,7 @@ final class ChiaWalletManager: BaseManager, WalletManager { init(wallet: Wallet, networkService: ChiaNetworkService, txBuilder: ChiaTransactionBuilder) throws { self.networkService = networkService self.txBuilder = txBuilder - self.puzzleHash = ChiaConstant.getPuzzle(walletPublicKey: wallet.publicKey.blockchainKey).hex + self.puzzleHash = try ChiaConstant.getPuzzleHash(address: wallet.address).hex super.init(wallet: wallet) } @@ -39,15 +39,13 @@ final class ChiaWalletManager: BaseManager, WalletManager { cancellable = networkService .getUnspents(puzzleHash: puzzleHash) .sink( - receiveCompletion: { [unowned self] completionSubscription in + receiveCompletion: { completionSubscription in if case let .failure(error) = completionSubscription { - // TODO: - Hander error completion completion(.failure(error)) } }, receiveValue: { [unowned self] response in - print(response) - completion(.success(())) + self.update(with: response, completion: completion) } ) } @@ -92,3 +90,20 @@ final class ChiaWalletManager: BaseManager, WalletManager { } } + +// MARK: - Private Implementation + +private extension ChiaWalletManager { + private func update(with coins: [ChiaCoin], completion: @escaping (Result) -> Void) { + let balance = coins.map { $0.amount }.reduce(0, +) + + if balance != wallet.amounts[.coin]?.value.int64Value { + wallet.transactions = [] + } + + wallet.add(coinValue: .init(balance / wallet.blockchain.decimalValue.int64Value)) + txBuilder.unspentCoins = coins + + completion(.success(())) + } +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift index 76eefb9d7..74d0e53fe 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift @@ -8,11 +8,34 @@ import Foundation +/* + - PuzzleHash Chia documentation - https://docs.chia.net/guides/crash-course/signatures/ + - Сurried and serialized signature.clsp (https://github.com/Chia-Network/chialisp-crash-course/blob/af620db2505db507b348d4f036dc4955fa81a004/signature.clsp) + */ + enum ChiaConstant: String { case puzzleReveal = "ff02ffff01ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0" case fingerprint = "ff018080" + case genesisChallengeMainnet = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb" + case genesisChallengeTestnet = "ae83525ba8d1dd3f09b277de18ca3e43fc0af20d20c4b3e92ef2a48bd291ccb2" static func getPuzzle(walletPublicKey: Data) -> Data { return Data(hex: ChiaConstant.puzzleReveal.rawValue) + walletPublicKey + Data(hex: ChiaConstant.fingerprint.rawValue) } + + static func getPuzzleHash(address: String) throws -> Data { + let bech32 = Bech32(constant: .bech32m) + let dataBytes = try bech32.decode(address).checksum + return try Data(bech32.convertBits(data: dataBytes.bytes, fromBits: 5, toBits: 8, pad: false)) + } +} + +extension ChiaConstant { + enum HRP: String { + case txch, xch + + init(isTestnet: Bool) { + self = isTestnet ? .txch : .xch + } + } } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift new file mode 100644 index 000000000..bc93b3125 --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift @@ -0,0 +1,20 @@ +// +// ChiaCreateCoinCondition.swift +// BlockchainSdk +// +// Created by skibinalexander on 18.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +struct CreateCoinCondition { + private let destinationPuzzleHash: Data + private let amount: Int64 + private let memos: Data = Data() + + init(destinationPuzzleHash: Data, amount: Int64) { + self.destinationPuzzleHash = destinationPuzzleHash + self.amount = amount + } +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift index 24df27aca..c7ab6de09 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift @@ -8,26 +8,18 @@ import Foundation -struct ChiaPuzzleHashBody: Encodable { - let puzzleHash: String -} - -struct ChiaTransactionBody { - let spendBundle: ChiaSpendBundle -} - -struct ChiaSpendBundle { +struct ChiaSpendBundle: Codable { let aggregatedSignature: String let coinSpends: ChiaCoinSpend } -struct ChiaCoinSpend { +struct ChiaCoinSpend: Codable { let coin: ChiaCoin let puzzleReveal: String let solution: String } -struct ChiaCoin: Decodable { +struct ChiaCoin: Codable { // Has to be encoded as a number in JSON, therefore Long is used. It's enough to encode ~1/3 of Chia total supply. let amount: Int64 let parentCoinInfo: String From 80a7b69a0782185f2ab993a388924fab3c2cf888 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 18 Jul 2023 21:11:04 +0300 Subject: [PATCH 06/49] IOS-3913 Add implementation condition --- BlockchainSdk.xcodeproj/project.pbxproj | 8 +-- .../Chia/ChiaAddressService.swift | 2 +- ...oinCondition.swift => ChiaCondition.swift} | 6 +++ .../Chia/Common/ClvmProgram.swift | 49 ++++++++++++++----- 4 files changed, 47 insertions(+), 18 deletions(-) rename BlockchainSdk/WalletManagers/Chia/Common/{ChiaCreateCoinCondition.swift => ChiaCondition.swift} (81%) diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index 771773c01..8c13fb154 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 2D0F67902A6542EE000865A5 /* ChiaModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */; }; 2D0F67922A658DBE000865A5 /* ChiaConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */; }; 2D0F67962A66C036000865A5 /* ChiaProviderRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67952A66C036000865A5 /* ChiaProviderRequests.swift */; }; - 2D0F67982A66C491000865A5 /* ChiaCreateCoinCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */; }; + 2D0F67982A66C491000865A5 /* ChiaCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0F67972A66C491000865A5 /* ChiaCondition.swift */; }; 2D1976732A613AC3006C4D3E /* ChiaTransactionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */; }; 2D1976762A613B58006C4D3E /* ChiaNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */; }; 2D1976782A613B86006C4D3E /* ChiaNetworkProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */; }; @@ -398,7 +398,7 @@ 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaModels.swift; sourceTree = ""; }; 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaConstant.swift; sourceTree = ""; }; 2D0F67952A66C036000865A5 /* ChiaProviderRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaProviderRequests.swift; sourceTree = ""; }; - 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaCreateCoinCondition.swift; sourceTree = ""; }; + 2D0F67972A66C491000865A5 /* ChiaCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaCondition.swift; sourceTree = ""; }; 2D1976722A613AC3006C4D3E /* ChiaTransactionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaTransactionBuilder.swift; sourceTree = ""; }; 2D1976752A613B58006C4D3E /* ChiaNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkService.swift; sourceTree = ""; }; 2D1976772A613B86006C4D3E /* ChiaNetworkProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChiaNetworkProvider.swift; sourceTree = ""; }; @@ -816,7 +816,7 @@ isa = PBXGroup; children = ( 2D19767D2A6331D3006C4D3E /* ClvmProgram.swift */, - 2D0F67972A66C491000865A5 /* ChiaCreateCoinCondition.swift */, + 2D0F67972A66C491000865A5 /* ChiaCondition.swift */, 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */, 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */, ); @@ -2336,7 +2336,7 @@ DA67A69629E51FEA001B6799 /* CosmosWalletManager.swift in Sources */, 2D78F40C2A5C3CCF00962CCA /* ChiaWalletManager.swift in Sources */, 2D0F67962A66C036000865A5 /* ChiaProviderRequests.swift in Sources */, - 2D0F67982A66C491000865A5 /* ChiaCreateCoinCondition.swift in Sources */, + 2D0F67982A66C491000865A5 /* ChiaCondition.swift in Sources */, DAB87CB1297ADCDC00FF30EB /* GetBlockBlockBookConfig.swift in Sources */, EF0DA78D285246A90081092A /* DashWalletManager.swift in Sources */, EF32FEBF2A306E51002ED43F /* AddressService.swift in Sources */, diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift index cf9183fa1..637f3f5a2 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaAddressService.swift @@ -24,7 +24,7 @@ public struct ChiaAddressService: AddressService { public func makeAddress(for publicKey: Wallet.PublicKey, with addressType: AddressType) throws -> PlainAddress { let puzzle = constants.getPuzzle(walletPublicKey: publicKey.blockchainKey) - let puzzleHash = try ClvmNode.Decoder(programBytes: puzzle.bytes).deserialize().hash() + let puzzleHash = try ClvmProgram.Decoder(programBytes: puzzle.bytes).deserialize().hash() let hrp = ChiaConstant.HRP(isTestnet: isTestnet).rawValue let encodeValue = Bech32(constant: .bech32m).encode(hrp, values: puzzleHash) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift similarity index 81% rename from BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift rename to BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift index bc93b3125..ab0a3b33c 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCreateCoinCondition.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift @@ -8,6 +8,12 @@ import Foundation +protocol ChiaCondition { + var conditionCode: Int64 { get set } + + func toProgram() -> ClvmProgram +} + struct CreateCoinCondition { private let destinationPuzzleHash: Data private let amount: Int64 diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index ad621d817..bc9e99276 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -10,12 +10,14 @@ import Foundation import TangemSdk import CryptoSwift -class ClvmNode { +class ClvmProgram { private let atom: Array? - private let left: ClvmNode? - private let right: ClvmNode? + private let left: ClvmProgram? + private let right: ClvmProgram? + + // MARK: - Init - init(atom: Array? = nil, left: ClvmNode? = nil, right: ClvmNode? = nil) { + init(atom: Array? = nil, left: ClvmProgram? = nil, right: ClvmProgram? = nil) { self.atom = atom self.left = left self.right = right @@ -38,35 +40,56 @@ class ClvmNode { return hash } + + func serialize() throws -> Data { + if let atom = atom { + if atom.isEmpty { + return Data(Byte(0x80)) + } else if atom.count == 1 && atom[0] <= 0x7F { + return Data(atom[0]) + } else { + // TODO: - Make serialize + let size = atom.count + var result = [Byte]() + throw NSError() + } + } else { + if let left = left, let right = right { + return try Data(Byte(0xff)) + left.serialize() + right.serialize() + } else { + throw NSError() + } + } + } } -extension ClvmNode { +extension ClvmProgram { class Decoder { // MARK: - Properties - private var iterator: ClvmNode.Iterator + private var iterator: ClvmProgram.Iterator // MARK: - Init init(programBytes: Array) { - self.iterator = ClvmNode.Iterator(programBytes: programBytes) + self.iterator = ClvmProgram.Iterator(programBytes: programBytes) } // MARK: - Public Implementation - func deserialize() throws -> ClvmNode { + func deserialize() throws -> ClvmProgram { try deserialize(with: &iterator) } // MARK: - Private Implementation - private func deserialize(with programByteIterator: inout ClvmNode.Iterator) throws -> ClvmNode { + private func deserialize(with programByteIterator: inout ClvmProgram.Iterator) throws -> ClvmProgram { var sizeBytes = Array() let currentByte = programByteIterator.next()! if currentByte <= 0x7F { - return ClvmNode(atom: [currentByte]) + return ClvmProgram(atom: [currentByte]) } else if currentByte <= 0xBF { sizeBytes = [currentByte & 0x3F] } else if currentByte <= 0xDF { @@ -80,14 +103,14 @@ extension ClvmNode { } else if currentByte == 0xFF { let left = try deserialize(with: &programByteIterator) let right = try deserialize(with: &programByteIterator) - return ClvmNode(atom: nil, left: left, right: right) + return ClvmProgram(atom: nil, left: left, right: right) } else { throw DecoderError.errorCompareCurrentByte } let size = sizeBytes.toInt() let nextBytes = try programByteIterator.next(byteCount: size) - return ClvmNode(atom: nextBytes) + return ClvmProgram(atom: nextBytes) } } @@ -96,7 +119,7 @@ extension ClvmNode { } } -extension ClvmNode { +extension ClvmProgram { private struct Iterator: IteratorProtocol { typealias Element = T From 4fc583a2a1edb45532ee99b981c251aad0516588 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Mon, 24 Jul 2023 16:20:00 +0300 Subject: [PATCH 07/49] IOS-3913 Add implementation transaction builder --- .../Chia/ChiaTransactionBuilder.swift | 9 +++++++++ .../WalletManagers/Chia/ChiaWalletManager.swift | 2 +- .../Chia/Common/ChiaCondition.swift | 9 +++++++++ .../WalletManagers/Chia/Common/ClvmProgram.swift | 16 ++++++++++++++++ Podfile | 3 +++ Podfile.lock | 7 ++++++- 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 77487b334..a88541efa 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -79,3 +79,12 @@ final class ChiaTransactionBuilder { } } + +extension ChiaCoin { + + private func calculateId() -> Data { + return Data() +// parentCoinInfo.hexadecimal + puzzleHash.hexadecimal + amount. + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 4a1f19a58..a515e6c13 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -35,7 +35,7 @@ final class ChiaWalletManager: BaseManager, WalletManager { // MARK: - Implementation - func update(completion: @escaping (Result) -> Void) { + override func update(completion: @escaping (Result) -> Void) { cancellable = networkService .getUnspents(puzzleHash: puzzleHash) .sink( diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift index ab0a3b33c..23b3cce85 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift @@ -24,3 +24,12 @@ struct CreateCoinCondition { self.amount = amount } } + +// always valid condition +struct RemarkCondition: ChiaCondition { + var conditionCode: Int64 = 1 + + func toProgram() -> ClvmProgram { + ClvmProgram.fromList(list: []) + } +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index bc9e99276..709f70872 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -23,6 +23,22 @@ class ClvmProgram { self.right = right } + // MARK: - Static + + static func fromBytes(bytes: Array) -> ClvmProgram { + return ClvmProgram(atom: bytes, left: nil, right: nil) + } + + static func fromList(list: [ClvmProgram]) -> ClvmProgram { + var result: ClvmProgram? = nil + + for item in list.reversed() { + result = ClvmProgram(atom: nil, left: item, right: result) + } + + return result ?? .init() + } + // MARK: - Hashable func hash() throws -> Data { diff --git a/Podfile b/Podfile index 2f93a1f23..38a0d0dd7 100644 --- a/Podfile +++ b/Podfile @@ -11,6 +11,9 @@ def common_pods pod 'TangemWalletCore', :git => 'https://github.com/tangem/wallet-core-binaries-ios.git', :tag => '3.2.1-tangem2' # pod 'TangemWalletCore', :path => '../wallet-core-binaries-ios' + + # Pods for Chia-BLS + pod 'Chia-BLS', :path => '../chia-bls' end diff --git a/Podfile.lock b/Podfile.lock index 4c2f6a0fb..184f16a75 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -20,6 +20,7 @@ PODS: - BinanceChain/Protobuf (1.0.1-beta) - BinanceChain/Util (1.0.1-beta) - BitcoinCore.swift (0.15.4) + - Chia-BLS (0.0.1) - CryptoSwift (1.5.1) - HDWalletKit (0.3.6): - CryptoSwift @@ -75,6 +76,7 @@ DEPENDENCIES: - BigInt - BinanceChain (from `https://github.com/tangem/swiftbinancechain.git`, tag `0.0.9`) - BitcoinCore.swift (from `https://github.com/tangem/bitcoincore.git`, tag `0.0.19`) + - Chia-BLS (from `../chia-bls`) - HDWalletKit (from `https://github.com/tangem/hdwallet.git`, tag `0.3.12`) - Moya - ScaleCodec @@ -116,6 +118,8 @@ EXTERNAL SOURCES: BitcoinCore.swift: :git: https://github.com/tangem/bitcoincore.git :tag: 0.0.19 + Chia-BLS: + :path: "../chia-bls" HDWalletKit: :git: https://github.com/tangem/hdwallet.git :tag: 0.3.12 @@ -161,6 +165,7 @@ SPEC CHECKSUMS: BigInt: f668a80089607f521586bbe29513d708491ef2f7 BinanceChain: b77d4c0e496efbf13bdb1f428621480fd52f4ba1 BitcoinCore.swift: 64ac4e69d9a6ef917bcbb0c23f1324cf57a822fb + Chia-BLS: cc61e286b028fa584303f969bb2f34251869cb82 CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 HDWalletKit: 602ec664633cc6bae1c697e4e17af42efb69bfad Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee @@ -182,6 +187,6 @@ SPEC CHECKSUMS: web3swift: 93f68f5430c11a78bba2351c139d2d22f2c04b5e XCGLogger: 1943831ef907df55108b0b18657953f868de973b -PODFILE CHECKSUM: 820c811ad5556a1a0d7fc3dfd9678549fc46ef80 +PODFILE CHECKSUM: 71b03247ab1f0a984263e136e8f729581610a1fa COCOAPODS: 1.12.1 From 7126f92d7c4ed1cd317a8c1f5aa7704b028a13cd Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Mon, 24 Jul 2023 17:14:40 +0300 Subject: [PATCH 08/49] IOS-3913 Add acc value for reduce --- .../WalletManagers/Chia/ChiaTransactionBuilder.swift | 11 ++++++----- .../WalletManagers/Chia/ChiaWalletManager.swift | 5 +---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index a88541efa..0a42be58c 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -33,13 +33,13 @@ final class ChiaTransactionBuilder { /// - amount: Amount transaction /// - destination: Destination address transaction /// - Returns: Array of bytes for transaction - func buildForSign(amount: Amount, destination: String) throws -> Data { + func buildForSign(transaction: Transaction) throws -> Data { guard !unspentCoins.isEmpty else { throw WalletError.failedToBuildTx } - let change = try calculateChange(amount: amount, destination: destination) - let coinSpends = try toChiaCoinSpends(change: change, destination: destination, amount: amount) + let change = try calculateChange(transaction: transaction, unspentCoins: unspentCoins) + let coinSpends = try toChiaCoinSpends(change: change, destination: transaction.destinationAddress, amount: transaction.amount) let hashesForSign = coinSpends.map { _ in // let solutionHash = ClvmNode.Decoder( @@ -74,8 +74,9 @@ final class ChiaTransactionBuilder { throw WalletError.empty } - private func calculateChange(amount: Amount, destination: String) throws -> Int64 { - throw WalletError.empty + private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> Int64 { + let fullAmount = unspentCoins.map { $0.amount }.reduce(0, +) + return fullAmount - (transaction.amount.value.int64Value + transaction.fee.amount.value.int64Value) } } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index a515e6c13..7b49989e4 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -58,10 +58,7 @@ final class ChiaWalletManager: BaseManager, WalletManager { throw WalletError.failedToBuildTx } - let input = try self.txBuilder.buildForSign( - amount: transaction.amount, - destination: transaction.destinationAddress - ) + let input = try self.txBuilder.buildForSign(transaction: transaction) throw WalletError.empty } From 27b43c552791c3054a17d4234f0ddbffc05fc95a Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Mon, 24 Jul 2023 23:09:47 +0300 Subject: [PATCH 09/49] IOS-3913 Add chia condition transaction builder --- .../Chia/ChiaTransactionBuilder.swift | 57 ++++++++++++++++--- .../Chia/Common/ChiaCondition.swift | 27 ++++++++- .../Chia/Common/ChiaModels.swift | 2 +- .../Chia/Common/ClvmProgram.swift | 4 +- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 0a42be58c..6dbaa3334 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -38,8 +38,17 @@ final class ChiaTransactionBuilder { throw WalletError.failedToBuildTx } - let change = try calculateChange(transaction: transaction, unspentCoins: unspentCoins) - let coinSpends = try toChiaCoinSpends(change: change, destination: transaction.destinationAddress, amount: transaction.amount) + let change = try calculateChange( + transaction: transaction, + unspentCoins: unspentCoins + ) + + let coinSpends = try toChiaCoinSpends( + change: change, + destination: transaction.destinationAddress, + source: transaction.sourceAddress, + amount: transaction.amount + ) let hashesForSign = coinSpends.map { _ in // let solutionHash = ClvmNode.Decoder( @@ -61,17 +70,29 @@ final class ChiaTransactionBuilder { // MARK: - Private Implementation - private func toChiaCoinSpends(change: Int64, destination: String, amount: Amount) throws -> [ChiaCoinSpend] { + private func toChiaCoinSpends(change: Int64, destination: String, source: String, amount: Amount) throws -> [ChiaCoinSpend] { let coinSpends = unspentCoins.map { - ChiaCoinSpend(coin: $0, puzzleReveal: ChiaConstant.getPuzzle(walletPublicKey: walletPublicKey).hex, solution: "") + ChiaCoinSpend( + coin: $0, + puzzleReveal: ChiaConstant.getPuzzle(walletPublicKey: walletPublicKey).hex, + solution: "" + ) } - let sendCondition = try CreateCoinCondition( - destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: destination), - amount: amount.value.int64Value - ) + let sendCondition = try createCoinCondition(for: destination, with: amount.value.int64Value) + let changeCondition = try change != 0 ? createCoinCondition(for: source, with: change) : nil - throw WalletError.empty + let solutions = [sendCondition, changeCondition].compactMap { $0 } + + sol + + self.coinSpends[0].solution = [sendCondition, changeCondition].compactMap { $0 }.toSolution().toHexString() + +// for (coinSpend in coinSpends.drop(1)) { +// coinSpend.solution = listOf(RemarkCondition()).toSolution().toHexString() +// } + + return coinSpends } private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> Int64 { @@ -79,6 +100,13 @@ final class ChiaTransactionBuilder { return fullAmount - (transaction.amount.value.int64Value + transaction.fee.amount.value.int64Value) } + private func createCoinCondition(for address: String, with change: Int64) throws -> CreateCoinCondition { + return try CreateCoinCondition( + destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), + amount: change + ) + } + } extension ChiaCoin { @@ -89,3 +117,14 @@ extension ChiaCoin { } } + +extension Array where Element == ChiaCondition { + + func toSolution() throws -> Data { + let conditions = ClvmProgram.from(list: self.map { $0.toProgram() }) + let solutionArguments = ClvmProgram.from(list: [conditions]) // might be more than one for other puzzles + + return try solutionArguments.serialize() + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift index 23b3cce85..9cc7742bb 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift @@ -17,11 +17,32 @@ protocol ChiaCondition { struct CreateCoinCondition { private let destinationPuzzleHash: Data private let amount: Int64 - private let memos: Data = Data() + private let memos: Data - init(destinationPuzzleHash: Data, amount: Int64) { + init(destinationPuzzleHash: Data, amount: Int64, memos: Data = Data()) { self.destinationPuzzleHash = destinationPuzzleHash self.amount = amount + self.memos = memos + } +} + +extension CreateCoinCondition: ChiaCondition { + var conditionCode = 51 + + func toProgram() -> ClvmProgram { + var programList = [ + ClvmProgram.from(long: conditionCode), + ClvmProgram.from(bytes: destinationPuzzleHash), + ClvmProgram.from(long: amount) + ] + + if memos.isEmpty { + programList.append( + ClvmProgram.from(list: [ClvmProgram.from(bytes: memos.bytes)]) + ) + } + + return ClvmProgram.from(list: programList) } } @@ -30,6 +51,6 @@ struct RemarkCondition: ChiaCondition { var conditionCode: Int64 = 1 func toProgram() -> ClvmProgram { - ClvmProgram.fromList(list: []) + ClvmProgram.from(list: []) } } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift index c7ab6de09..f31ceda01 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift @@ -16,7 +16,7 @@ struct ChiaSpendBundle: Codable { struct ChiaCoinSpend: Codable { let coin: ChiaCoin let puzzleReveal: String - let solution: String + var solution: String } struct ChiaCoin: Codable { diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index 709f70872..0bee4a2d9 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -25,11 +25,11 @@ class ClvmProgram { // MARK: - Static - static func fromBytes(bytes: Array) -> ClvmProgram { + static func from(bytes: Array) -> ClvmProgram { return ClvmProgram(atom: bytes, left: nil, right: nil) } - static func fromList(list: [ClvmProgram]) -> ClvmProgram { + static func from(list: [ClvmProgram]) -> ClvmProgram { var result: ClvmProgram? = nil for item in list.reversed() { From f84a218ca4d829dfef971394a7149f37658ea140 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 25 Jul 2023 12:20:38 +0300 Subject: [PATCH 10/49] IOS-3913 Add implementation befor aug scheme --- BlockchainSdk.xcodeproj/project.pbxproj | 12 +++ .../Common/Blockchain+AllCases.swift | 2 +- .../WalletAssembly/ChiaWalletAssembly.swift | 1 + .../Chia/ChiaTransactionBuilder.swift | 78 ++++++++----------- .../Chia/Common/Chia+Array.swift | 20 +++++ .../WalletManagers/Chia/Common/Chia+Aug.swift | 17 ++++ .../Chia/Common/Chia+Int64.swift | 18 +++++ .../Chia/Common/ChiaCondition.swift | 10 +-- .../Chia/Common/ChiaConstant.swift | 5 ++ .../Chia/Common/ChiaModels.swift | 10 ++- .../Chia/Common/ClvmProgram.swift | 6 +- .../BlockchainSdkExampleViewModel.swift | 2 +- 12 files changed, 127 insertions(+), 54 deletions(-) create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/Chia+Array.swift create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift create mode 100644 BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index 8c13fb154..eb88a6226 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -24,6 +24,9 @@ 2D19768D2A63E82B006C4D3E /* TONProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976882A63E82B006C4D3E /* TONProvider.swift */; }; 2D19768E2A63E82B006C4D3E /* TONProviderRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1976892A63E82B006C4D3E /* TONProviderRequest.swift */; }; 2D29A7F729D5C2AE00359A0C /* TWPublicKeyType+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */; }; + 2D2CB45B2A6FBE2A00AE24EC /* Chia+Int64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D2CB45A2A6FBE2A00AE24EC /* Chia+Int64.swift */; }; + 2D2CB45D2A6FC94F00AE24EC /* Chia+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D2CB45C2A6FC94F00AE24EC /* Chia+Array.swift */; }; + 2D2CB45F2A6FC95C00AE24EC /* Chia+Aug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D2CB45E2A6FC95C00AE24EC /* Chia+Aug.swift */; }; 2D3829C929D34A93001D4785 /* TWCoin+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829C829D34A93001D4785 /* TWCoin+.swift */; }; 2D3829CE29D350D1001D4785 /* AddressServiceManagerUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */; }; 2D535E772A0CC5E50081EB76 /* DecodableVectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D535E742A0CC5E50081EB76 /* DecodableVectors.swift */; }; @@ -412,6 +415,9 @@ 2D1976882A63E82B006C4D3E /* TONProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProvider.swift; sourceTree = ""; }; 2D1976892A63E82B006C4D3E /* TONProviderRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TONProviderRequest.swift; sourceTree = ""; }; 2D29A7F629D5C2AE00359A0C /* TWPublicKeyType+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWPublicKeyType+.swift"; sourceTree = ""; }; + 2D2CB45A2A6FBE2A00AE24EC /* Chia+Int64.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Chia+Int64.swift"; sourceTree = ""; }; + 2D2CB45C2A6FC94F00AE24EC /* Chia+Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Chia+Array.swift"; sourceTree = ""; }; + 2D2CB45E2A6FC95C00AE24EC /* Chia+Aug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Chia+Aug.swift"; sourceTree = ""; }; 2D3829C829D34A93001D4785 /* TWCoin+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TWCoin+.swift"; sourceTree = ""; }; 2D3829CD29D350D1001D4785 /* AddressServiceManagerUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressServiceManagerUtility.swift; sourceTree = ""; }; 2D535E742A0CC5E50081EB76 /* DecodableVectors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodableVectors.swift; sourceTree = ""; }; @@ -819,6 +825,9 @@ 2D0F67972A66C491000865A5 /* ChiaCondition.swift */, 2D0F678F2A6542EE000865A5 /* ChiaModels.swift */, 2D0F67912A658DBE000865A5 /* ChiaConstant.swift */, + 2D2CB45A2A6FBE2A00AE24EC /* Chia+Int64.swift */, + 2D2CB45C2A6FC94F00AE24EC /* Chia+Array.swift */, + 2D2CB45E2A6FC95C00AE24EC /* Chia+Aug.swift */, ); path = Common; sourceTree = ""; @@ -2483,8 +2492,11 @@ EF5F1B9729C9C0500093307B /* Fee.swift in Sources */, DA82433F27A2B07800CFC2C0 /* PolkadotNetwork.swift in Sources */, 5D7D243025136254001B9A4F /* XRPKeypair.swift in Sources */, + 2D2CB45D2A6FC94F00AE24EC /* Chia+Array.swift in Sources */, B04E8D5025F8F67F00821CBE /* RosettaNetworkProvider.swift in Sources */, + 2D2CB45B2A6FBE2A00AE24EC /* Chia+Int64.swift in Sources */, 5D845516243DEAC80072155E /* AdaliteTarget.swift in Sources */, + 2D2CB45F2A6FC95C00AE24EC /* Chia+Aug.swift in Sources */, 5DCC817823FAE6F700DFC460 /* MoyaPublisher.swift in Sources */, 5D7D242B25136254001B9A4F /* HTTP.swift in Sources */, 5D7D242E25136254001B9A4F /* XrpData.swift in Sources */, diff --git a/BlockchainSdk/Common/Blockchain+AllCases.swift b/BlockchainSdk/Common/Blockchain+AllCases.swift index 67d7f16a3..8f32341ea 100644 --- a/BlockchainSdk/Common/Blockchain+AllCases.swift +++ b/BlockchainSdk/Common/Blockchain+AllCases.swift @@ -97,7 +97,7 @@ public extension Blockchain { .terraV2, .cronos, .telos(testnet: false), - .octa + .octa, .chia(testnet: false) ] } diff --git a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift index eada4764e..2bf839bfa 100644 --- a/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift +++ b/BlockchainSdk/Common/WalletAssembly/ChiaWalletAssembly.swift @@ -29,6 +29,7 @@ struct ChiaWalletAssembly: WalletManagerAssembly { blockchain: input.blockchain ), txBuilder: .init( + isTestnet: input.blockchain.isTestnet, walletPublicKey: input.wallet.publicKey.blockchainKey ) ) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 6dbaa3334..c6cdfecaa 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -16,12 +16,18 @@ final class ChiaTransactionBuilder { // MARK: - Private Properties + private let isTestnet: Bool private let walletPublicKey: Data private var coinSpends: [ChiaCoinSpend] = [] + private var genesisChallenge: Data { + Data(hex: ChiaConstant.genesisChallenge(isTestnet: isTestnet)) + } + // MARK: - Init - init(walletPublicKey: Data, unspentCoins: [ChiaCoin] = []) { + init(isTestnet: Bool, walletPublicKey: Data, unspentCoins: [ChiaCoin] = []) { + self.isTestnet = isTestnet self.walletPublicKey = walletPublicKey self.unspentCoins = unspentCoins } @@ -33,7 +39,7 @@ final class ChiaTransactionBuilder { /// - amount: Amount transaction /// - destination: Destination address transaction /// - Returns: Array of bytes for transaction - func buildForSign(transaction: Transaction) throws -> Data { + func buildForSign(transaction: Transaction) throws -> [Data] { guard !unspentCoins.isEmpty else { throw WalletError.failedToBuildTx } @@ -50,26 +56,37 @@ final class ChiaTransactionBuilder { amount: transaction.amount ) - let hashesForSign = coinSpends.map { _ in -// let solutionHash = ClvmNode.Decoder( -// programBytes: Data(hex: $0.solution).dro .hexToBytes().drop(1).dropLast(1).toByteArray() -// ).deserialize().hash() + let hashesForSign = try coinSpends.map { + let solutionHash = try ClvmProgram.Decoder( + programBytes: Data(hex: $0.solution).dropFirst(1).dropLast(1).bytes + ).deserialize().hash() -// (solutionHash + it.coin.calculateId() + genesisChallenge).hashAugScheme() -// return Data() + return try (solutionHash + $0.coin.calculateId() + genesisChallenge).hashAugScheme() } -// return Data(hashesForSign) - - return Data() + return hashesForSign } func buildToSend(signatures: Data) throws -> ChiaTransactionBody { - throw WalletError.empty +// let aggregatedSignature = AugSchemeMPL.aggregate( +// signatures.map { JacobianPoint.fromBytesG2(it.toUByteArray()) } +// ).toHex().value + + return ChiaTransactionBody( + spendBundle: ChiaSpendBundle( + aggregatedSignature: "", + coinSpends: coinSpends + ) + ) } // MARK: - Private Implementation + private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> Int64 { + let fullAmount = unspentCoins.map { $0.amount }.reduce(0, +) + return fullAmount - (transaction.amount.value.int64Value + transaction.fee.amount.value.int64Value) + } + private func toChiaCoinSpends(change: Int64, destination: String, source: String, amount: Amount) throws -> [ChiaCoinSpend] { let coinSpends = unspentCoins.map { ChiaCoinSpend( @@ -82,24 +99,15 @@ final class ChiaTransactionBuilder { let sendCondition = try createCoinCondition(for: destination, with: amount.value.int64Value) let changeCondition = try change != 0 ? createCoinCondition(for: source, with: change) : nil - let solutions = [sendCondition, changeCondition].compactMap { $0 } - - sol + self.coinSpends[0].solution = try [sendCondition, changeCondition].compactMap { $0 }.toSolution().hex - self.coinSpends[0].solution = [sendCondition, changeCondition].compactMap { $0 }.toSolution().toHexString() - -// for (coinSpend in coinSpends.drop(1)) { -// coinSpend.solution = listOf(RemarkCondition()).toSolution().toHexString() -// } + for var coinSpend in coinSpends.dropFirst(1) { + coinSpend.solution = try [RemarkCondition()].toSolution().hex + } return coinSpends } - private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> Int64 { - let fullAmount = unspentCoins.map { $0.amount }.reduce(0, +) - return fullAmount - (transaction.amount.value.int64Value + transaction.fee.amount.value.int64Value) - } - private func createCoinCondition(for address: String, with change: Int64) throws -> CreateCoinCondition { return try CreateCoinCondition( destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), @@ -108,23 +116,3 @@ final class ChiaTransactionBuilder { } } - -extension ChiaCoin { - - private func calculateId() -> Data { - return Data() -// parentCoinInfo.hexadecimal + puzzleHash.hexadecimal + amount. - } - -} - -extension Array where Element == ChiaCondition { - - func toSolution() throws -> Data { - let conditions = ClvmProgram.from(list: self.map { $0.toProgram() }) - let solutionArguments = ClvmProgram.from(list: [conditions]) // might be more than one for other puzzles - - return try solutionArguments.serialize() - } - -} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Array.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Array.swift new file mode 100644 index 000000000..0803cd952 --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Array.swift @@ -0,0 +1,20 @@ +// +// Chia+Array.swift +// BlockchainSdk +// +// Created by skibinalexander on 25.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +extension Array where Element == ChiaCondition { + + func toSolution() throws -> Data { + let conditions = ClvmProgram.from(list: self.map { $0.toProgram() }) + let solutionArguments = ClvmProgram.from(list: [conditions]) // might be more than one for other puzzles + + return try solutionArguments.serialize() + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift new file mode 100644 index 000000000..52d4af0b2 --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift @@ -0,0 +1,17 @@ +// +// Chia+Aug.swift +// BlockchainSdk +// +// Created by skibinalexander on 25.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +extension Data { + + func hashAugScheme() throws -> Data { + return Data() + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift new file mode 100644 index 000000000..d44a6c933 --- /dev/null +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift @@ -0,0 +1,18 @@ +// +// Chia+Int64.swift +// BlockchainSdk +// +// Created by skibinalexander on 25.07.2023. +// Copyright © 2023 Tangem AG. All rights reserved. +// + +import Foundation + +extension Int64 { + + func chiaEncode() -> Data { + let data = withUnsafeBytes(of: self) { Data($0) } + return Data(data.bytes.drop(while: { $0 == 0x00 })) + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift index 9cc7742bb..d1a7c7c62 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift @@ -14,7 +14,9 @@ protocol ChiaCondition { func toProgram() -> ClvmProgram } -struct CreateCoinCondition { +struct CreateCoinCondition: ChiaCondition { + var conditionCode: Int64 = 51 + private let destinationPuzzleHash: Data private let amount: Int64 private let memos: Data @@ -26,13 +28,11 @@ struct CreateCoinCondition { } } -extension CreateCoinCondition: ChiaCondition { - var conditionCode = 51 - +extension CreateCoinCondition { func toProgram() -> ClvmProgram { var programList = [ ClvmProgram.from(long: conditionCode), - ClvmProgram.from(bytes: destinationPuzzleHash), + ClvmProgram.from(bytes: destinationPuzzleHash.bytes), ClvmProgram.from(long: amount) ] diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift index 74d0e53fe..bb5905152 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift @@ -18,6 +18,7 @@ enum ChiaConstant: String { case fingerprint = "ff018080" case genesisChallengeMainnet = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb" case genesisChallengeTestnet = "ae83525ba8d1dd3f09b277de18ca3e43fc0af20d20c4b3e92ef2a48bd291ccb2" + case AUG_SCHEME_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_" static func getPuzzle(walletPublicKey: Data) -> Data { return Data(hex: ChiaConstant.puzzleReveal.rawValue) + walletPublicKey + Data(hex: ChiaConstant.fingerprint.rawValue) @@ -28,6 +29,10 @@ enum ChiaConstant: String { let dataBytes = try bech32.decode(address).checksum return try Data(bech32.convertBits(data: dataBytes.bytes, fromBits: 5, toBits: 8, pad: false)) } + + static func genesisChallenge(isTestnet: Bool) -> String { + return isTestnet ? ChiaConstant.genesisChallengeTestnet.rawValue : ChiaConstant.genesisChallengeMainnet.rawValue + } } extension ChiaConstant { diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift index f31ceda01..ecd40bebe 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift @@ -10,7 +10,7 @@ import Foundation struct ChiaSpendBundle: Codable { let aggregatedSignature: String - let coinSpends: ChiaCoinSpend + let coinSpends: [ChiaCoinSpend] } struct ChiaCoinSpend: Codable { @@ -25,3 +25,11 @@ struct ChiaCoin: Codable { let parentCoinInfo: String let puzzleHash: String } + +extension ChiaCoin { + + func calculateId() -> Data { + (Data(hex: parentCoinInfo) + Data(hex: puzzleHash) + amount.chiaEncode()).sha256() + } + +} diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index 0bee4a2d9..91ba87e5a 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -25,8 +25,12 @@ class ClvmProgram { // MARK: - Static + static func from(long: Int64) -> ClvmProgram { + return .init(atom: long.chiaEncode().bytes) + } + static func from(bytes: Array) -> ClvmProgram { - return ClvmProgram(atom: bytes, left: nil, right: nil) + return .init(atom: bytes, left: nil, right: nil) } static func from(list: [ClvmProgram]) -> ClvmProgram { diff --git a/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift b/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift index 75b3754f3..bc667d30a 100644 --- a/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift +++ b/BlockchainSdkExample/BlockchainSdkExampleViewModel.swift @@ -471,7 +471,7 @@ class BlockchainSdkExampleViewModel: ObservableObject { .terraV1, .terraV2, .cronos, - .octa + .octa, .chia(testnet: false) ] From a87aff717a269d0f576481487491e4cd96ea0e0c Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 25 Jul 2023 12:55:45 +0300 Subject: [PATCH 11/49] IOS-3913 Add aug scheme for aggregate g2map point --- .../WalletManagers/Chia/ChiaTransactionBuilder.swift | 7 +++---- BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index c6cdfecaa..fe953c42f 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -8,6 +8,7 @@ import Foundation import CryptoKit +import ChiaBLS final class ChiaTransactionBuilder { // MARK: - Public Properties @@ -68,13 +69,11 @@ final class ChiaTransactionBuilder { } func buildToSend(signatures: Data) throws -> ChiaTransactionBody { -// let aggregatedSignature = AugSchemeMPL.aggregate( -// signatures.map { JacobianPoint.fromBytesG2(it.toUByteArray()) } -// ).toHex().value + let aggregatedSignature = try ChiaBLS.aggregate(signatures: signatures.map { $0.hexString }) return ChiaTransactionBody( spendBundle: ChiaSpendBundle( - aggregatedSignature: "", + aggregatedSignature: aggregatedSignature, coinSpends: coinSpends ) ) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift index 52d4af0b2..5a497ab69 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift @@ -7,11 +7,12 @@ // import Foundation +import ChiaBLS extension Data { func hashAugScheme() throws -> Data { - return Data() + try Data(hex: ChiaBLS.augSchemeMplG2Map(hashPublicKey: self.hex)) } } From 1e1c99937fa8182e7030675e63be000d477a3910 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 25 Jul 2023 17:33:48 +0300 Subject: [PATCH 12/49] IOS-3913 Add encode value chia transaction --- .../Common/Factories/WalletFactory.swift | 10 +++-- .../Chia/ChiaTransactionBuilder.swift | 2 +- .../Chia/ChiaWalletManager.swift | 10 ++++- .../WalletManagers/Chia/Common/Chia+Aug.swift | 4 +- .../Chia/Common/ClvmProgram.swift | 38 +++++++++++++++++-- 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/BlockchainSdk/Common/Factories/WalletFactory.swift b/BlockchainSdk/Common/Factories/WalletFactory.swift index ee7abfa1f..d536e2873 100644 --- a/BlockchainSdk/Common/Factories/WalletFactory.swift +++ b/BlockchainSdk/Common/Factories/WalletFactory.swift @@ -23,11 +23,13 @@ public struct WalletFactory { // Temporary for get count on addresses var addressTypes: [AddressType] = Array(blockchain.derivationPaths(for: .v2).keys) - let addresses: [AddressType: PlainAddress] = try addressTypes.reduce(into: [:]) { result, addressType in - result[addressType] = try addressProvider.makeAddress(for: publicKey, with: addressType) - } +// let addresses: [AddressType: PlainAddress] = try addressTypes.reduce(into: [:]) { result, addressType in +// result[addressType] = try addressProvider.makeAddress(for: publicKey, with: addressType) +// } + + let address = try addressProvider.makeAddress(for: publicKey, with: .default) - return Wallet(blockchain: blockchain, addresses: addresses) + return Wallet(blockchain: blockchain, addresses: [.default: address]) } /// With multisig script public key diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index fe953c42f..dafee8f4c 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -62,7 +62,7 @@ final class ChiaTransactionBuilder { programBytes: Data(hex: $0.solution).dropFirst(1).dropLast(1).bytes ).deserialize().hash() - return try (solutionHash + $0.coin.calculateId() + genesisChallenge).hashAugScheme() + return try (solutionHash + $0.coin.calculateId() + genesisChallenge).hashAugScheme(with: walletPublicKey) } return hashesForSign diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 7b49989e4..c937f1cc2 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -83,7 +83,15 @@ final class ChiaWalletManager: BaseManager, WalletManager { } func getFee(amount: Amount, destination: String) -> AnyPublisher<[Fee], Error> { - return .emptyFail + Just(()) + .receive(on: DispatchQueue.global()) + .map { [weak self] hash in + return [.init(.zeroCoin(for: .chia(testnet: true)))] + } + .mapError({ res in + return WalletError.empty + }) + .eraseToAnyPublisher() } } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift index 5a497ab69..ca1773ad5 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift @@ -11,8 +11,8 @@ import ChiaBLS extension Data { - func hashAugScheme() throws -> Data { - try Data(hex: ChiaBLS.augSchemeMplG2Map(hashPublicKey: self.hex)) + func hashAugScheme(with publicKey: Data) throws -> Data { + try Data(hex: ChiaBLS.augSchemeMplG2Map(publicKeyHash: publicKey.hex, messageHash: self.hex)) } } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index 91ba87e5a..4b291b28c 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -68,19 +68,49 @@ class ClvmProgram { } else if atom.count == 1 && atom[0] <= 0x7F { return Data(atom[0]) } else { - // TODO: - Make serialize - let size = atom.count + let size = UInt64(atom.count) var result = [Byte]() - throw NSError() + + if size < 0x40 { + result.append(Byte(size & 0x0F)) + } else if size < 0x2000 { + result.append(Byte((size >> 8) | 0xC0)) + result.append(Byte(size & 0xFF)) + } else if size < 0x100000 { + result.append(Byte((size >> 16) & 0xE0)) + result.append(Byte((size >> 8) & 0xFF)) + result.append(Byte(size & 0xFF)) + } else if size < 0x8000000 { + result.append(Byte((size >> 24) | 0xF0)) + result.append(Byte((size >> 16) & 0xFF)) + result.append(Byte((size >> 8) & 0xFF)) + result.append(Byte(size & 0xFF)) + } else if size < 0x400000000 { + result.append(Byte((size >> 32) | 0xF8)) + result.append(Byte((size >> 24) & 0xFF)) + result.append(Byte((size >> 16) & 0xFF)) + result.append(Byte((size >> 8) & 0xFF)) + result.append(Byte(size & 0xFF)) + } else { + throw EncoderError.manyBytesToEncode + } + + result.append(contentsOf: atom) + return Data(result) } } else { if let left = left, let right = right { return try Data(Byte(0xff)) + left.serialize() + right.serialize() } else { - throw NSError() + throw EncoderError.undefinedEncodeException } } } + + enum EncoderError: Error { + case manyBytesToEncode + case undefinedEncodeException + } } extension ClvmProgram { From e937981134d32acdd9faf0a50a3fe9b0a7b35d46 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Tue, 25 Jul 2023 19:34:33 +0300 Subject: [PATCH 13/49] IOS-3913 Add chia transaction completed building --- .../Chia/ChiaTransactionBuilder.swift | 22 +++++++++++++++++++ .../Chia/ChiaWalletManager.swift | 2 ++ Podfile | 1 + Podfile.lock | 2 +- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index dafee8f4c..938b4f730 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -33,6 +33,28 @@ final class ChiaTransactionBuilder { self.unspentCoins = unspentCoins } + + // MARK: - Need after test remove + + func test() { + let address = "txch14gxuvfmw2xdxqnws5agt3ma483wktd2lrzwvpj3f6jvdgkmf5gtq8g3aw3" + let amount = 235834596465 + let encodedAmount = amount.data.bytes.drop(while: { $0 == 0x00 }) + + let solution1 = try! "ffffff33ffa0" + + ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + "808080" + let condition = try! CreateCoinCondition( + destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), + amount: Int64(amount) + ).toProgram() + + let solution2 = try! ClvmProgram.from(list: [ClvmProgram.from(list: [condition])]).serialize().hex + + let equal = solution1.lowercased() == solution2.lowercased() + + print(equal) + } + // MARK: - Implementation /// Build input for sign transaction from Parameters diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index c937f1cc2..ff28fbabb 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -36,6 +36,8 @@ final class ChiaWalletManager: BaseManager, WalletManager { // MARK: - Implementation override func update(completion: @escaping (Result) -> Void) { + txBuilder.test() + cancellable = networkService .getUnspents(puzzleHash: puzzleHash) .sink( diff --git a/Podfile b/Podfile index 38a0d0dd7..00174767c 100644 --- a/Podfile +++ b/Podfile @@ -84,4 +84,5 @@ post_install do |installer| end end + end diff --git a/Podfile.lock b/Podfile.lock index 184f16a75..f14be5636 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -187,6 +187,6 @@ SPEC CHECKSUMS: web3swift: 93f68f5430c11a78bba2351c139d2d22f2c04b5e XCGLogger: 1943831ef907df55108b0b18657953f868de973b -PODFILE CHECKSUM: 71b03247ab1f0a984263e136e8f729581610a1fa +PODFILE CHECKSUM: cda7d39f894e7a43d9a6414711f8bb07be6d788e COCOAPODS: 1.12.1 From 57fef3267cac02545c6fa6f4a35bbbddbbb1226c Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Wed, 26 Jul 2023 16:30:20 +0300 Subject: [PATCH 14/49] IOS-3913 Make chia transaction uint64 amount --- .../Chia/ChiaTransactionBuilder.swift | 20 +++++++++++-------- .../Chia/ChiaWalletManager.swift | 4 ++-- .../Chia/Common/Chia+Int64.swift | 2 +- .../Chia/Common/ChiaCondition.swift | 12 +++++------ .../Chia/Common/ChiaModels.swift | 2 +- .../Chia/Common/ClvmProgram.swift | 10 +++++----- Podfile.lock | 2 +- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 938b4f730..4b2695504 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -38,20 +38,24 @@ final class ChiaTransactionBuilder { func test() { let address = "txch14gxuvfmw2xdxqnws5agt3ma483wktd2lrzwvpj3f6jvdgkmf5gtq8g3aw3" - let amount = 235834596465 + let amount: UInt64 = 235834596465 let encodedAmount = amount.data.bytes.drop(while: { $0 == 0x00 }) let solution1 = try! "ffffff33ffa0" + - ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + "808080" + ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + + Data(encodedAmount).hex + "808080" + let condition = try! CreateCoinCondition( destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), - amount: Int64(amount) + amount: amount ).toProgram() let solution2 = try! ClvmProgram.from(list: [ClvmProgram.from(list: [condition])]).serialize().hex let equal = solution1.lowercased() == solution2.lowercased() + print(solution1) + print(solution2) print(equal) } @@ -103,12 +107,12 @@ final class ChiaTransactionBuilder { // MARK: - Private Implementation - private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> Int64 { + private func calculateChange(transaction: Transaction, unspentCoins: [ChiaCoin]) throws -> UInt64 { let fullAmount = unspentCoins.map { $0.amount }.reduce(0, +) - return fullAmount - (transaction.amount.value.int64Value + transaction.fee.amount.value.int64Value) + return fullAmount - (transaction.amount.value.uint64Value + transaction.fee.amount.value.uint64Value) } - private func toChiaCoinSpends(change: Int64, destination: String, source: String, amount: Amount) throws -> [ChiaCoinSpend] { + private func toChiaCoinSpends(change: UInt64, destination: String, source: String, amount: Amount) throws -> [ChiaCoinSpend] { let coinSpends = unspentCoins.map { ChiaCoinSpend( coin: $0, @@ -117,7 +121,7 @@ final class ChiaTransactionBuilder { ) } - let sendCondition = try createCoinCondition(for: destination, with: amount.value.int64Value) + let sendCondition = try createCoinCondition(for: destination, with: amount.value.uint64Value) let changeCondition = try change != 0 ? createCoinCondition(for: source, with: change) : nil self.coinSpends[0].solution = try [sendCondition, changeCondition].compactMap { $0 }.toSolution().hex @@ -129,7 +133,7 @@ final class ChiaTransactionBuilder { return coinSpends } - private func createCoinCondition(for address: String, with change: Int64) throws -> CreateCoinCondition { + private func createCoinCondition(for address: String, with change: UInt64) throws -> CreateCoinCondition { return try CreateCoinCondition( destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), amount: change diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index ff28fbabb..73f0b1a81 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -104,11 +104,11 @@ private extension ChiaWalletManager { private func update(with coins: [ChiaCoin], completion: @escaping (Result) -> Void) { let balance = coins.map { $0.amount }.reduce(0, +) - if balance != wallet.amounts[.coin]?.value.int64Value { + if balance != wallet.amounts[.coin]?.value.uint64Value { wallet.transactions = [] } - wallet.add(coinValue: .init(balance / wallet.blockchain.decimalValue.int64Value)) + wallet.add(coinValue: .init(balance / wallet.blockchain.decimalValue.uint64Value)) txBuilder.unspentCoins = coins completion(.success(())) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift index d44a6c933..f066e604d 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift @@ -8,7 +8,7 @@ import Foundation -extension Int64 { +extension UInt64 { func chiaEncode() -> Data { let data = withUnsafeBytes(of: self) { Data($0) } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift index d1a7c7c62..c8cdef1bf 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaCondition.swift @@ -9,19 +9,19 @@ import Foundation protocol ChiaCondition { - var conditionCode: Int64 { get set } + var conditionCode: UInt64 { get set } func toProgram() -> ClvmProgram } struct CreateCoinCondition: ChiaCondition { - var conditionCode: Int64 = 51 + var conditionCode: UInt64 = 51 private let destinationPuzzleHash: Data - private let amount: Int64 + private let amount: UInt64 private let memos: Data - init(destinationPuzzleHash: Data, amount: Int64, memos: Data = Data()) { + init(destinationPuzzleHash: Data, amount: UInt64, memos: Data = Data()) { self.destinationPuzzleHash = destinationPuzzleHash self.amount = amount self.memos = memos @@ -36,7 +36,7 @@ extension CreateCoinCondition { ClvmProgram.from(long: amount) ] - if memos.isEmpty { + if !memos.isEmpty { programList.append( ClvmProgram.from(list: [ClvmProgram.from(bytes: memos.bytes)]) ) @@ -48,7 +48,7 @@ extension CreateCoinCondition { // always valid condition struct RemarkCondition: ChiaCondition { - var conditionCode: Int64 = 1 + var conditionCode: UInt64 = 1 func toProgram() -> ClvmProgram { ClvmProgram.from(list: []) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift index ecd40bebe..45509821f 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaModels.swift @@ -21,7 +21,7 @@ struct ChiaCoinSpend: Codable { struct ChiaCoin: Codable { // Has to be encoded as a number in JSON, therefore Long is used. It's enough to encode ~1/3 of Chia total supply. - let amount: Int64 + let amount: UInt64 let parentCoinInfo: String let puzzleHash: String } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index 51bc439ca..81f1822eb 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -25,7 +25,7 @@ class ClvmProgram { // MARK: - Static - static func from(long: Int64) -> ClvmProgram { + static func from(long: UInt64) -> ClvmProgram { return .init(atom: long.chiaEncode().bytes) } @@ -34,13 +34,13 @@ class ClvmProgram { } static func from(list: [ClvmProgram]) -> ClvmProgram { - var result: ClvmProgram? = nil + var result: ClvmProgram = ClvmProgram(atom: []) for item in list.reversed() { result = ClvmProgram(atom: nil, left: item, right: result) } - return result ?? .init() + return result } // MARK: - Hashable @@ -66,12 +66,12 @@ class ClvmProgram { var result = [Byte]() if size < 0x40 { - result.append(Byte(size & 0x0F)) + result.append(Byte(size | 0x0F)) } else if size < 0x2000 { result.append(Byte((size >> 8) | 0xC0)) result.append(Byte(size & 0xFF)) } else if size < 0x100000 { - result.append(Byte((size >> 16) & 0xE0)) + result.append(Byte((size >> 16) | 0xE0)) result.append(Byte((size >> 8) & 0xFF)) result.append(Byte(size & 0xFF)) } else if size < 0x8000000 { diff --git a/Podfile.lock b/Podfile.lock index f14be5636..4ce3cac6b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -165,7 +165,7 @@ SPEC CHECKSUMS: BigInt: f668a80089607f521586bbe29513d708491ef2f7 BinanceChain: b77d4c0e496efbf13bdb1f428621480fd52f4ba1 BitcoinCore.swift: 64ac4e69d9a6ef917bcbb0c23f1324cf57a822fb - Chia-BLS: cc61e286b028fa584303f969bb2f34251869cb82 + Chia-BLS: 27c004fcab3852ac3bd128c86c445b13a74124b4 CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 HDWalletKit: 602ec664633cc6bae1c697e4e17af42efb69bfad Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee From 5fe78ef5bd8edf86a4ca7eac1ffdb0ed4a07f2e8 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Thu, 27 Jul 2023 10:49:46 +0300 Subject: [PATCH 15/49] IOS-3913 Add send transaction model --- .../Chia/ChiaNetworkService.swift | 15 +++++++++ .../Chia/Provider/ChiaNetworkProvider.swift | 2 +- .../Chia/Provider/ChiaProviderResponses.swift | 4 ++- .../Chia/ChiaTransactionBuilder.swift | 14 ++++---- .../Chia/ChiaWalletManager.swift | 32 +++++++++---------- .../Chia/Common/Chia+Int64.swift | 3 +- .../Chia/Common/ClvmProgram.swift | 2 +- 7 files changed, 43 insertions(+), 29 deletions(-) diff --git a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift index d13e32d8a..f18f226de 100644 --- a/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift +++ b/BlockchainSdk/BlockchainService/Chia/ChiaNetworkService.swift @@ -38,4 +38,19 @@ class ChiaNetworkService: MultiNetworkProvider { } } + func send(_ spendBundle: ChiaSpendBundle) -> AnyPublisher { + providerPublisher { provider in + provider + .sendTransaction(body: ChiaTransactionBody(spendBundle: spendBundle)) + .tryMap { response in + guard response.success else { + throw WalletError.failedToSendTx + } + + return "" + } + .eraseToAnyPublisher() + } + } + } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift index 5c5e9c538..c97eafa45 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift @@ -47,7 +47,7 @@ struct ChiaNetworkProvider: HostProvider { return requestPublisher(for: target) } - func sendTransaction(body: ChiaTransactionBody) -> AnyPublisher { + func sendTransaction(body: ChiaTransactionBody) -> AnyPublisher { return .emptyFail } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift index 5b0f2e1a0..d315eed16 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderResponses.swift @@ -17,7 +17,9 @@ struct ChiaCoinRecordsResponse: Decodable { } struct ChiaSendTransactionResponse: Decodable { - let status: String + let success: Bool + let status: String? + let error: String? } struct ChiaCoinRecord: Decodable { diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 4b2695504..34657635e 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -39,7 +39,7 @@ final class ChiaTransactionBuilder { func test() { let address = "txch14gxuvfmw2xdxqnws5agt3ma483wktd2lrzwvpj3f6jvdgkmf5gtq8g3aw3" let amount: UInt64 = 235834596465 - let encodedAmount = amount.data.bytes.drop(while: { $0 == 0x00 }) + let encodedAmount = amount.chiaEncode() let solution1 = try! "ffffff33ffa0" + ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + @@ -94,14 +94,12 @@ final class ChiaTransactionBuilder { return hashesForSign } - func buildToSend(signatures: Data) throws -> ChiaTransactionBody { + func buildToSend(signatures: [Data]) throws -> ChiaSpendBundle { let aggregatedSignature = try ChiaBLS.aggregate(signatures: signatures.map { $0.hexString }) - - return ChiaTransactionBody( - spendBundle: ChiaSpendBundle( - aggregatedSignature: aggregatedSignature, - coinSpends: coinSpends - ) + + return ChiaSpendBundle( + aggregatedSignature: aggregatedSignature, + coinSpends: coinSpends ) } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 73f0b1a81..79fd5b33e 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -53,35 +53,33 @@ final class ChiaWalletManager: BaseManager, WalletManager { } func send(_ transaction: Transaction, signer: TransactionSigner) -> AnyPublisher { - Just(()) - .receive(on: DispatchQueue.global()) - .tryMap { [weak self] _ -> String in - guard let self = self else { - throw WalletError.failedToBuildTx - } - - let input = try self.txBuilder.buildForSign(transaction: transaction) + do { + let hashesForSign = try self.txBuilder.buildForSign(transaction: transaction) + + return signer.sign( + hashes: hashesForSign, + walletPublicKey: self.wallet.publicKey + ) + .tryMap { [weak self] signatures -> ChiaSpendBundle in + guard let self = self else { throw WalletError.empty } - throw WalletError.empty + return try self.txBuilder.buildToSend(signatures: signatures) } - .flatMap { [weak self] message -> AnyPublisher in + .flatMap { [weak self] spendBundle -> AnyPublisher in guard let self = self else { return Fail(error: WalletError.failedToBuildTx).eraseToAnyPublisher() } - return .emptyFail - -// return self.networkService.send(message: message) + return self.networkService.send(spendBundle) } .map { [weak self] hash in self?.wallet.add(transaction: transaction) return TransactionSendResult(hash: hash) } .eraseToAnyPublisher() - } - - func build(transaction: TheOpenNetworkSigningInput, with signer: TransactionSigner? = nil) throws -> String { - throw WalletError.empty + } catch { + return .anyFail(error: error) + } } func getFee(amount: Amount, destination: String) -> AnyPublisher<[Fee], Error> { diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift index f066e604d..6ddc29eef 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Int64.swift @@ -12,7 +12,8 @@ extension UInt64 { func chiaEncode() -> Data { let data = withUnsafeBytes(of: self) { Data($0) } - return Data(data.bytes.drop(while: { $0 == 0x00 })) + let result = data.bytes.reversed().drop(while: { $0 == 0x00 }) + return Data(result) } } diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift index 81f1822eb..5ec903693 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ClvmProgram.swift @@ -66,7 +66,7 @@ class ClvmProgram { var result = [Byte]() if size < 0x40 { - result.append(Byte(size | 0x0F)) + result.append(Byte(size | 0x80)) } else if size < 0x2000 { result.append(Byte((size >> 8) | 0xC0)) result.append(Byte(size & 0xFF)) From e85c2f2a3b85d751b4329084fa65c9e08c69a7e2 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Thu, 27 Jul 2023 15:21:05 +0300 Subject: [PATCH 16/49] IOS-3913 Fix review constants --- .../Chia/Common/ChiaConstant.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift index fd7f8ca3b..c7163cdef 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/ChiaConstant.swift @@ -13,15 +13,15 @@ import Foundation - Сurried and serialized signature.clsp (https://github.com/Chia-Network/chialisp-crash-course/blob/af620db2505db507b348d4f036dc4955fa81a004/signature.clsp) */ -enum ChiaConstant: String { - case puzzleReveal = "ff02ffff01ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0" - case fingerprint = "ff018080" - case genesisChallengeMainnet = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb" - case genesisChallengeTestnet = "ae83525ba8d1dd3f09b277de18ca3e43fc0af20d20c4b3e92ef2a48bd291ccb2" - case AUG_SCHEME_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_" +enum ChiaConstant { + static let puzzleReveal = "ff02ffff01ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080ffff04ffff01b0" + static let fingerprint = "ff018080" + static let genesisChallengeMainnet = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb" + static let genesisChallengeTestnet = "ae83525ba8d1dd3f09b277de18ca3e43fc0af20d20c4b3e92ef2a48bd291ccb2" + static let AUG_SCHEME_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_" static func getPuzzle(walletPublicKey: Data) -> Data { - return Data(hex: ChiaConstant.puzzleReveal.rawValue) + walletPublicKey + Data(hex: ChiaConstant.fingerprint.rawValue) + return Data(hex: ChiaConstant.puzzleReveal) + walletPublicKey + Data(hex: ChiaConstant.fingerprint) } static func getPuzzleHash(address: String) throws -> Data { @@ -31,7 +31,7 @@ enum ChiaConstant: String { } static func genesisChallenge(isTestnet: Bool) -> String { - return isTestnet ? ChiaConstant.genesisChallengeTestnet.rawValue : ChiaConstant.genesisChallengeMainnet.rawValue + return isTestnet ? ChiaConstant.genesisChallengeTestnet : ChiaConstant.genesisChallengeMainnet } } From 8ecf94382d5d1446755f6f70343377663d674511 Mon Sep 17 00:00:00 2001 From: Skibin Alexander Date: Mon, 31 Jul 2023 09:43:37 +0300 Subject: [PATCH 17/49] IOS-3913 Add send transaction logic --- BlockchainSdk.xcodeproj/project.pbxproj | 8 + .../Chia/Provider/ChiaNetworkProvider.swift | 15 +- .../Chia/Provider/ChiaProviderTarget.swift | 4 +- BlockchainSdk/Common/Blockchain.swift | 2 - .../Chia/ChiaTransactionBuilder.swift | 35 +- .../Chia/ChiaWalletManager.swift | 11 +- .../WalletManagers/Chia/Common/Chia+Aug.swift | 4 +- BlockchainSdkTests/Chia/ChiaTests.swift | 19 + BlsSignature.xcframework/Info.plist | 40 ++ .../Bls_Signature.framework/Bls_Signature | Bin 0 -> 324448 bytes .../Headers/BlsSignature.h | 13 + .../Headers/Bls_Signature-Swift.h | 294 +++++++++ .../Headers/Bls_Signature.h | 18 + .../Bls_Signature.framework/Info.plist | Bin 0 -> 754 bytes .../arm64-apple-ios.abi.json | 107 ++++ .../arm64-apple-ios.private.swiftinterface | 13 + .../arm64-apple-ios.swiftdoc | Bin 0 -> 404 bytes .../arm64-apple-ios.swiftinterface | 13 + .../Modules/module.modulemap | 11 + .../_CodeSignature/CodeResources | 201 ++++++ .../Bls_Signature.framework/Bls_Signature | Bin 0 -> 668096 bytes .../Headers/BlsSignature.h | 13 + .../Headers/Bls_Signature-Swift.h | 584 ++++++++++++++++++ .../Headers/Bls_Signature.h | 18 + .../Bls_Signature.framework/Info.plist | Bin 0 -> 734 bytes .../arm64-apple-ios-simulator.abi.json | 107 ++++ ...apple-ios-simulator.private.swiftinterface | 13 + .../arm64-apple-ios-simulator.swiftdoc | Bin 0 -> 416 bytes .../arm64-apple-ios-simulator.swiftinterface | 13 + .../x86_64-apple-ios-simulator.abi.json | 107 ++++ ...apple-ios-simulator.private.swiftinterface | 13 + .../x86_64-apple-ios-simulator.swiftdoc | Bin 0 -> 416 bytes .../x86_64-apple-ios-simulator.swiftinterface | 13 + .../Modules/module.modulemap | 11 + .../_CodeSignature/CodeResources | 256 ++++++++ Podfile | 2 +- Podfile.lock | 7 +- 37 files changed, 1911 insertions(+), 54 deletions(-) create mode 100644 BlsSignature.xcframework/Info.plist create mode 100755 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Bls_Signature create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/BlsSignature.h create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature-Swift.h create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature.h create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Info.plist create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftdoc create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/module.modulemap create mode 100644 BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/_CodeSignature/CodeResources create mode 100755 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Bls_Signature create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Headers/BlsSignature.h create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Headers/Bls_Signature-Swift.h create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Headers/Bls_Signature.h create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Info.plist create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios-simulator.abi.json create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios-simulator.swiftdoc create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios-simulator.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/x86_64-apple-ios-simulator.abi.json create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/x86_64-apple-ios-simulator.swiftdoc create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/x86_64-apple-ios-simulator.swiftinterface create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Modules/module.modulemap create mode 100644 BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/_CodeSignature/CodeResources diff --git a/BlockchainSdk.xcodeproj/project.pbxproj b/BlockchainSdk.xcodeproj/project.pbxproj index eb88a6226..17c1318f0 100644 --- a/BlockchainSdk.xcodeproj/project.pbxproj +++ b/BlockchainSdk.xcodeproj/project.pbxproj @@ -56,6 +56,9 @@ 2DBBE95029C8DBEA00971539 /* TONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBBE94F29C8DBEA00971539 /* TONTests.swift */; }; 2DC5796129C9CBB1004312AE /* WalletCoreSignerTesterUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DC5796029C9CBB1004312AE /* WalletCoreSignerTesterUtility.swift */; }; 2DC5DAB429B9E6A10039154A /* WalletCoreSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DC5DAB329B9E6A10039154A /* WalletCoreSigner.swift */; }; + 2DD6C5E62A73F19C00AE2C15 /* BlsSignature.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD6C5E52A73F19C00AE2C15 /* BlsSignature.xcframework */; }; + 2DD6C5EB2A73FED500AE2C15 /* BlsSignature.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD6C5E52A73F19C00AE2C15 /* BlsSignature.xcframework */; }; + 2DD6C5EC2A73FED500AE2C15 /* BlsSignature.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD6C5E52A73F19C00AE2C15 /* BlsSignature.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 2DDE5B9F29C4F8D200A5B708 /* NetworkProviderAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DDE5B8C29C4F8D200A5B708 /* NetworkProviderAssembly.swift */; }; 2DDE5BA029C4F8D200A5B708 /* BlockBookProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DDE5B8D29C4F8D200A5B708 /* BlockBookProviderType.swift */; }; 2DDE5BA129C4F8D200A5B708 /* DucatusWalletAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DDE5B8F29C4F8D200A5B708 /* DucatusWalletAssembly.swift */; }; @@ -389,6 +392,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 2DD6C5EC2A73FED500AE2C15 /* BlsSignature.xcframework in Embed Frameworks */, DA59751727D747CD009F0A1F /* BlockchainSdk.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -448,6 +452,7 @@ 2DBBE94F29C8DBEA00971539 /* TONTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TONTests.swift; sourceTree = ""; }; 2DC5796029C9CBB1004312AE /* WalletCoreSignerTesterUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletCoreSignerTesterUtility.swift; sourceTree = ""; }; 2DC5DAB329B9E6A10039154A /* WalletCoreSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletCoreSigner.swift; sourceTree = ""; }; + 2DD6C5E52A73F19C00AE2C15 /* BlsSignature.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = BlsSignature.xcframework; sourceTree = ""; }; 2DDE5B8C29C4F8D200A5B708 /* NetworkProviderAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProviderAssembly.swift; sourceTree = ""; }; 2DDE5B8D29C4F8D200A5B708 /* BlockBookProviderType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockBookProviderType.swift; sourceTree = ""; }; 2DDE5B8F29C4F8D200A5B708 /* DucatusWalletAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DucatusWalletAssembly.swift; sourceTree = ""; }; @@ -782,6 +787,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2DD6C5E62A73F19C00AE2C15 /* BlsSignature.xcframework in Frameworks */, 88095B618D07D706BB871FE6 /* Pods_BlockchainSdk.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -801,6 +807,7 @@ files = ( DA59751E27D749A9009F0A1F /* MapKit.framework in Frameworks */, DA59751627D747CD009F0A1F /* BlockchainSdk.framework in Frameworks */, + 2DD6C5EB2A73FED500AE2C15 /* BlsSignature.xcframework in Frameworks */, BFD88160E080534F13A7C7A6 /* Pods_BlockchainSdkExample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -973,6 +980,7 @@ 5D14E4642397B80F00C15FC8 = { isa = PBXGroup; children = ( + 2DD6C5E52A73F19C00AE2C15 /* BlsSignature.xcframework */, 5D14E4722397B80F00C15FC8 /* Info.plist */, 5D14E4702397B80F00C15FC8 /* BlockchainSdk */, 5D14E47B2397B80F00C15FC8 /* BlockchainSdkTests */, diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift index c97eafa45..bf233bf50 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaNetworkProvider.swift @@ -8,6 +8,7 @@ import Foundation import Combine +import Moya struct ChiaNetworkProvider: HostProvider { @@ -44,16 +45,21 @@ struct ChiaNetworkProvider: HostProvider { targetType: .getCoinRecordsBy(puzzleHashBody: .init(puzzleHash: puzzleHash)) ) - return requestPublisher(for: target) + return requestPublisher(for: target, completionError: { _ in return .failedToParseNetworkResponse }) } func sendTransaction(body: ChiaTransactionBody) -> AnyPublisher { - return .emptyFail + let target = ChiaProviderTarget( + node: node, + targetType: .sendTransaction(body: body) + ) + + return requestPublisher(for: target, completionError: { _ in return .failedToParseNetworkResponse }) } // MARK: - Private Implementation - private func requestPublisher(for target: ChiaProviderTarget) -> AnyPublisher { + private func requestPublisher(for target: ChiaProviderTarget, completionError: @escaping (MoyaError) -> WalletError) -> AnyPublisher { let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase @@ -61,8 +67,7 @@ struct ChiaNetworkProvider: HostProvider { .filterSuccessfulStatusAndRedirectCodes() .map(T.self, using: decoder) .mapError { error in - print(error.localizedDescription) - return WalletError.empty + return completionError(error) } .eraseToAnyPublisher() } diff --git a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift index 2dbb6251d..b3924df3e 100644 --- a/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift +++ b/BlockchainSdk/BlockchainService/Chia/Provider/ChiaProviderTarget.swift @@ -48,8 +48,8 @@ struct ChiaProviderTarget: TargetType { switch targetType { case .getCoinRecordsBy(let puzzleHashBody): jrpcRequest = (try? puzzleHashBody.asDictionary(with: encoder)) ?? [:] - default: - jrpcRequest = [:] + case .sendTransaction(let body): + jrpcRequest = (try? body.asDictionary(with: encoder)) ?? [:] } return .requestParameters(parameters: jrpcRequest, encoding: JSONEncoding.default) diff --git a/BlockchainSdk/Common/Blockchain.swift b/BlockchainSdk/Common/Blockchain.swift index a5b611be5..bd1b23f5f 100644 --- a/BlockchainSdk/Common/Blockchain.swift +++ b/BlockchainSdk/Common/Blockchain.swift @@ -147,8 +147,6 @@ public enum Blockchain: Equatable, Hashable { return testnet ? 12 : 10 case .kusama, .azero, .chia: return 12 - case .chia: - return 18 } } diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift index 34657635e..43688a2ff 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaTransactionBuilder.swift @@ -8,7 +8,7 @@ import Foundation import CryptoKit -import ChiaBLS +import Bls_Signature final class ChiaTransactionBuilder { // MARK: - Public Properties @@ -33,32 +33,6 @@ final class ChiaTransactionBuilder { self.unspentCoins = unspentCoins } - - // MARK: - Need after test remove - - func test() { - let address = "txch14gxuvfmw2xdxqnws5agt3ma483wktd2lrzwvpj3f6jvdgkmf5gtq8g3aw3" - let amount: UInt64 = 235834596465 - let encodedAmount = amount.chiaEncode() - - let solution1 = try! "ffffff33ffa0" + - ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + - Data(encodedAmount).hex + "808080" - - let condition = try! CreateCoinCondition( - destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), - amount: amount - ).toProgram() - - let solution2 = try! ClvmProgram.from(list: [ClvmProgram.from(list: [condition])]).serialize().hex - - let equal = solution1.lowercased() == solution2.lowercased() - - print(solution1) - print(solution2) - print(equal) - } - // MARK: - Implementation /// Build input for sign transaction from Parameters @@ -95,7 +69,7 @@ final class ChiaTransactionBuilder { } func buildToSend(signatures: [Data]) throws -> ChiaSpendBundle { - let aggregatedSignature = try ChiaBLS.aggregate(signatures: signatures.map { $0.hexString }) + let aggregatedSignature = try BlsSignatureSwift.aggregate(signatures: signatures.map { $0.hexString }) return ChiaSpendBundle( aggregatedSignature: aggregatedSignature, @@ -111,7 +85,7 @@ final class ChiaTransactionBuilder { } private func toChiaCoinSpends(change: UInt64, destination: String, source: String, amount: Amount) throws -> [ChiaCoinSpend] { - let coinSpends = unspentCoins.map { + var coinSpends = unspentCoins.map { ChiaCoinSpend( coin: $0, puzzleReveal: ChiaConstant.getPuzzle(walletPublicKey: walletPublicKey).hex, @@ -122,7 +96,8 @@ final class ChiaTransactionBuilder { let sendCondition = try createCoinCondition(for: destination, with: amount.value.uint64Value) let changeCondition = try change != 0 ? createCoinCondition(for: source, with: change) : nil - self.coinSpends[0].solution = try [sendCondition, changeCondition].compactMap { $0 }.toSolution().hex + let solution: [ChiaCondition] = [sendCondition, changeCondition].compactMap { $0 } + coinSpends[0].solution = try solution.toSolution().hex for var coinSpend in coinSpends.dropFirst(1) { coinSpend.solution = try [RemarkCondition()].toSolution().hex diff --git a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift index 79fd5b33e..f70ac162c 100644 --- a/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift +++ b/BlockchainSdk/WalletManagers/Chia/ChiaWalletManager.swift @@ -36,8 +36,6 @@ final class ChiaWalletManager: BaseManager, WalletManager { // MARK: - Implementation override func update(completion: @escaping (Result) -> Void) { - txBuilder.test() - cancellable = networkService .getUnspents(puzzleHash: puzzleHash) .sink( @@ -62,7 +60,6 @@ final class ChiaWalletManager: BaseManager, WalletManager { ) .tryMap { [weak self] signatures -> ChiaSpendBundle in guard let self = self else { throw WalletError.empty } - return try self.txBuilder.buildToSend(signatures: signatures) } .flatMap { [weak self] spendBundle -> AnyPublisher in @@ -100,13 +97,15 @@ final class ChiaWalletManager: BaseManager, WalletManager { private extension ChiaWalletManager { private func update(with coins: [ChiaCoin], completion: @escaping (Result) -> Void) { - let balance = coins.map { $0.amount }.reduce(0, +) + let decimalBalance = coins.map { Decimal($0.amount) }.reduce(0, +) - if balance != wallet.amounts[.coin]?.value.uint64Value { + if decimalBalance != wallet.amounts[.coin]?.value { wallet.transactions = [] } - wallet.add(coinValue: .init(balance / wallet.blockchain.decimalValue.uint64Value)) + let coinBalance = decimalBalance / wallet.blockchain.decimalValue + + wallet.add(coinValue: coinBalance) txBuilder.unspentCoins = coins completion(.success(())) diff --git a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift index ca1773ad5..717978a6c 100644 --- a/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift +++ b/BlockchainSdk/WalletManagers/Chia/Common/Chia+Aug.swift @@ -7,12 +7,12 @@ // import Foundation -import ChiaBLS +import Bls_Signature extension Data { func hashAugScheme(with publicKey: Data) throws -> Data { - try Data(hex: ChiaBLS.augSchemeMplG2Map(publicKeyHash: publicKey.hex, messageHash: self.hex)) + try Data(hex: BlsSignatureSwift.augSchemeMplG2Map(publicKeyHash: publicKey.hex, messageHash: self.hex)) } } diff --git a/BlockchainSdkTests/Chia/ChiaTests.swift b/BlockchainSdkTests/Chia/ChiaTests.swift index df1602a1d..18f5571c3 100644 --- a/BlockchainSdkTests/Chia/ChiaTests.swift +++ b/BlockchainSdkTests/Chia/ChiaTests.swift @@ -14,4 +14,23 @@ import TangemSdk class ChiaTests: XCTestCase { + func testConditionSpend() { + let address = "txch14gxuvfmw2xdxqnws5agt3ma483wktd2lrzwvpj3f6jvdgkmf5gtq8g3aw3" + let amount: UInt64 = 235834596465 + let encodedAmount = amount.chiaEncode() + + let solution1 = try! "ffffff33ffa0" + + ChiaConstant.getPuzzleHash(address: address).hex + "ff8" + String(encodedAmount.count) + + Data(encodedAmount).hex + "808080" + + let condition = try! CreateCoinCondition( + destinationPuzzleHash: ChiaConstant.getPuzzleHash(address: address), + amount: amount + ).toProgram() + + let solution2 = try! ClvmProgram.from(list: [ClvmProgram.from(list: [condition])]).serialize().hex + + let equal = solution1.lowercased() == solution2.lowercased() + } + } diff --git a/BlsSignature.xcframework/Info.plist b/BlsSignature.xcframework/Info.plist new file mode 100644 index 000000000..9b3437b5a --- /dev/null +++ b/BlsSignature.xcframework/Info.plist @@ -0,0 +1,40 @@ + + + + + AvailableLibraries + + + LibraryIdentifier + ios-arm64 + LibraryPath + Bls_Signature.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + Bls_Signature.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Bls_Signature b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Bls_Signature new file mode 100755 index 0000000000000000000000000000000000000000..1be61776116efc79b0dc5231f96b2d7946c388f1 GIT binary patch literal 324448 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

lQPEu{sQALs_XKR{js-csaDP=7ogb-q5LkO|4 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

Bo!1kMX8!136?5w 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 J0{_?o{|`8jQy%~T literal 0 HcmV?d00001 diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/BlsSignature.h b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/BlsSignature.h new file mode 100644 index 000000000..4f61b1124 --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/BlsSignature.h @@ -0,0 +1,13 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BlsSignature: NSObject + ++ (NSString *)augSchemeMplG2Map:(NSString *)hashPublicKey and:(NSString*)hashMessage with:(NSError **)error; ++ (NSString *)aggregate: (NSArray *)signatures with:(NSError **)error; ++ (NSString *)verify:(NSArray *)signatures with:(NSString *)publicKey and:(NSString*)message with:(NSError **)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature-Swift.h b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature-Swift.h new file mode 100644 index 000000000..f0032d62c --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature-Swift.h @@ -0,0 +1,294 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100) +#ifndef BLS_SIGNATURE_SWIFT_H +#define BLS_SIGNATURE_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if __has_include() +# include +#else +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="Bls_Signature",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) +#endif +#if defined(__cplusplus) +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature.h b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature.h new file mode 100644 index 000000000..0b757d61f --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Headers/Bls_Signature.h @@ -0,0 +1,18 @@ +// +// Bls_Signature.h +// Bls-Signature +// +// Created by skibinalexander on 26.07.2023. +// + +#import + +//! Project version number for Bls_Signature. +FOUNDATION_EXPORT double Bls_SignatureVersionNumber; + +//! Project version string for Bls_Signature. +FOUNDATION_EXPORT const unsigned char Bls_SignatureVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Info.plist b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..e77f96d4bdaf85b3fd7471e0192c80f7b37afc17 GIT binary patch literal 754 zcmYjOOK#IZ81@WMN-2%o5So@2`ruu#>?A}iV3RnJqBJy(ohG0VGqESmDB}lyR0P2V z*l_?BWzB{QZ~<0G-6L@W4uHfYu}Nq1|KID^%s)Ms5}2p-rU;W+191IG)Zq!M_oOS|b&7(%<5|AOC*oujdMT?# z$8rfB-z*`kv32s|?hH?Fvpgeac}1>H+%II6wPRyTR@=H`;7(Md_3<@g6Dzb1lqlS7 zR@f$qj?2g*bfobc%}N8m35kb|sZc~N>Jdr;g8gPDQ_klb*nU-@zNQe6T2)07#FHCsQXe?u?>v+=erFs)u1m4Ny2%23fzo43&?y@w zNSb(*5lflulQwb3F~?V>ypZd}Xbe;-mz7#lu9Ou;{mZ@kJmBHUUK4p%KF7^-kGU#m za__lM+&At!cgp<%OJED^foEVJyaq!Mf)C&$_zb>+AK)iA1;4>x2;dxCfQv8%SK(7w dg!}LicA*Z3(1tGbV8Bfd1k=hrjA~TiyMI@Y=IQ_d literal 0 HcmV?d00001 diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json new file mode 100644 index 000000000..806d774a0 --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json @@ -0,0 +1,107 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "Foundation", + "printedName": "Foundation", + "declKind": "Import", + "moduleName": "Bls_Signature", + "declAttributes": [ + "RawDocComment" + ] + }, + { + "kind": "TypeDecl", + "name": "BlsSignatureSwift", + "printedName": "BlsSignatureSwift", + "children": [ + { + "kind": "Function", + "name": "augSchemeMplG2Map", + "printedName": "augSchemeMplG2Map(publicKeyHash:messageHash:)", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + } + ], + "declKind": "Func", + "usr": "s:13Bls_Signature0aB5SwiftV17augSchemeMplG2Map13publicKeyHash07messageK0S2S_SStKFZ", + "mangledName": "$s13Bls_Signature0aB5SwiftV17augSchemeMplG2Map13publicKeyHash07messageK0S2S_SStKFZ", + "moduleName": "Bls_Signature", + "static": true, + "declAttributes": [ + "AccessControl" + ], + "throwing": true, + "funcSelfKind": "NonMutating" + }, + { + "kind": "Function", + "name": "aggregate", + "printedName": "aggregate(signatures:)", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Array", + "printedName": "[Swift.String]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + } + ], + "usr": "s:Sa" + } + ], + "declKind": "Func", + "usr": "s:13Bls_Signature0aB5SwiftV9aggregate10signaturesSSSaySSG_tKFZ", + "mangledName": "$s13Bls_Signature0aB5SwiftV9aggregate10signaturesSSSaySSG_tKFZ", + "moduleName": "Bls_Signature", + "static": true, + "declAttributes": [ + "AccessControl" + ], + "throwing": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Struct", + "usr": "s:13Bls_Signature0aB5SwiftV", + "mangledName": "$s13Bls_Signature0aB5SwiftV", + "moduleName": "Bls_Signature", + "declAttributes": [ + "AccessControl" + ] + } + ], + "json_format_version": 8 + }, + "ConstValues": [] +} \ No newline at end of file diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface new file mode 100644 index 000000000..7e4e1669a --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface @@ -0,0 +1,13 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100) +// swift-module-flags: -target arm64-apple-ios16.4 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Bls_Signature +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import Bls_Signature +import Foundation +import Swift +import _Concurrency +import _StringProcessing +public struct BlsSignatureSwift { + public static func augSchemeMplG2Map(publicKeyHash: Swift.String, messageHash: Swift.String) throws -> Swift.String + public static func aggregate(signatures: [Swift.String]) throws -> Swift.String +} diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftdoc b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftdoc new file mode 100644 index 0000000000000000000000000000000000000000..ebcfcfdcedebda3dc999569faea5f35724566d26 GIT binary patch literal 404 zcmaDfX9YVW2Lpp90|Ns)qlJ#c+7Dby0=U-%aP4>CT5rI$Ux91Q2d>2%xY!*xUFbQa zy@N^j#3Ahshx9v`wD%m+SaZl(Xp58P1t*OOP8vYc#=uE?50mBlsEGaEY1@h+sabi)fnTc*9 s$QIqq{9;2hJrkfP14FAI0|Ur@BQ^mZFBS#?kQlP#l(;e!k@+Bb00IDPZ~y=R literal 0 HcmV?d00001 diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface new file mode 100644 index 000000000..7e4e1669a --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface @@ -0,0 +1,13 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100) +// swift-module-flags: -target arm64-apple-ios16.4 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Bls_Signature +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import Bls_Signature +import Foundation +import Swift +import _Concurrency +import _StringProcessing +public struct BlsSignatureSwift { + public static func augSchemeMplG2Map(publicKeyHash: Swift.String, messageHash: Swift.String) throws -> Swift.String + public static func aggregate(signatures: [Swift.String]) throws -> Swift.String +} diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/module.modulemap b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/module.modulemap new file mode 100644 index 000000000..c71e5a7b6 --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/Modules/module.modulemap @@ -0,0 +1,11 @@ +framework module Bls_Signature { + umbrella header "Bls_Signature.h" + + export * + module * { export * } +} + +module Bls_Signature.Swift { + header "Bls_Signature-Swift.h" + requires objc +} diff --git a/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/_CodeSignature/CodeResources b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..ed32a501c --- /dev/null +++ b/BlsSignature.xcframework/ios-arm64/Bls_Signature.framework/_CodeSignature/CodeResources @@ -0,0 +1,201 @@ + + + + + files + + Headers/BlsSignature.h + + WiAnqd3vOaayFwY2kNy/uvf11yM= + + Headers/Bls_Signature-Swift.h + + yMx6Kg5llz8Gw1wRxvt3AW3SD+A= + + Headers/Bls_Signature.h + + xoaMm7e9mNsm0EVpDrIcwyrnUoo= + + Info.plist + + oJzS7uPzssHTfKYXiOLHEU0l1fg= + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json + + 43bO5obPFGkMx+gSf+zPu9btQ1g= + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface + + rdV9Pp3xONU36UwssuADb1L0/BI= + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftdoc + + y/cklfZi+CkK9kpAZA17MJv2XQo= + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface + + rdV9Pp3xONU36UwssuADb1L0/BI= + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftmodule + + HGogKgzH+FhYn6ZRuZzW8VCtlJ4= + + Modules/module.modulemap + + ghmghI8vmx9wjHFBZtMZhCBLm6g= + + + files2 + + Headers/BlsSignature.h + + hash2 + + fzlLnWZaBKZX8iffmqmYXXUZvEoN/XqSaM5amyFhrA4= + + + Headers/Bls_Signature-Swift.h + + hash2 + + 46kUhmiRCysJjRh1PXiR7Ce0RKA/TktsI0kxjCyOa74= + + + Headers/Bls_Signature.h + + hash2 + + qwhpp8pLFkNdsT5tT3zWGIAqRbDFtyWy+LI99hMDVG8= + + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.abi.json + + hash2 + + 7disJED8ZQdiExDdsLjNxdi3R2ShMxgdR0/7crtGaoM= + + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.private.swiftinterface + + hash2 + + QONgmelldwCbgPA1ufOIEO/QoqBIa41zE1lzhZWsXig= + + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftdoc + + hash2 + + kwo/Wm1CVWX5WqdIntJwRrLGDvgMq2bBSAhG+gu+mAo= + + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftinterface + + hash2 + + QONgmelldwCbgPA1ufOIEO/QoqBIa41zE1lzhZWsXig= + + + Modules/Bls_Signature.swiftmodule/arm64-apple-ios.swiftmodule + + hash2 + + yB2Kh83t7p9PMoydnYZNzGYltshYCTrdqISbZeyH97s= + + + Modules/module.modulemap + + hash2 + + vbo04+4rAKYmnBXpcXmyBXlxAYGTkGfFjbNpoarxpEk= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Bls_Signature b/BlsSignature.xcframework/ios-arm64_x86_64-simulator/Bls_Signature.framework/Bls_Signature new file mode 100755 index 0000000000000000000000000000000000000000..b77f41d576aa6f8ca17d09526b0599998fe99036 GIT binary patch literal 668096 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 *0g+ZUMOf|bkVxGQ$AiX`4D2 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

=J!Es?S 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