diff --git a/Wallet/BUCK b/Wallet/BUCK index bfe4922b65..d5b2d2c414 100644 --- a/Wallet/BUCK +++ b/Wallet/BUCK @@ -13,7 +13,6 @@ load("//Config:buck_rule_macros.bzl", ) framework_dependencies = [ - "//submodules/MtProtoKit:MtProtoKit", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/Display:Display", diff --git a/Wallet/Sources/AppDelegate.swift b/Wallet/Sources/AppDelegate.swift index b86d7acf78..080147854c 100644 --- a/Wallet/Sources/AppDelegate.swift +++ b/Wallet/Sources/AppDelegate.swift @@ -5,7 +5,6 @@ import BuildConfig import WalletUI import WalletCore import AVFoundation -import MtProtoKit private func encodeText(_ string: String, _ key: Int) -> String { var result = "" @@ -366,6 +365,7 @@ private final class WalletContextImpl: NSObject, WalletContext, UIImagePickerCon self.storage = WalletStorageInterfaceImpl(path: basePath + "/data") self.window = window + self.tonInstance = TonInstance( basePath: basePath + "/keys", config: config, @@ -544,6 +544,10 @@ final class AppDelegate: NSObject, UIApplicationDelegate { ), backgroundDetailsMode: nil ) + mainWindow.viewController = navigationController + + self.window?.makeKeyAndVisible() + let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] print("Starting with \(documentsPath)") @@ -573,230 +577,87 @@ final class AppDelegate: NSObject, UIApplicationDelegate { } """ - let walletContext = WalletContextImpl(basePath: documentsPath, config: config, blockchainName: "testnet", navigationBarTheme: navigationBarTheme, window: mainWindow) - self.walletContext = walletContext + let updatedConfigSignal: Signal = Signal { subscriber in + let downloadTask = URLSession.shared.downloadTask(with: URL(string: "https://test.ton.org/ton-lite-client-test1.config.json")!, completionHandler: { location, _, error in + if let location = location, let data = try? Data(contentsOf: location), let string = String(data: data, encoding: .utf8) { + subscriber.putNext(string) + subscriber.putCompletion() + } + }) + downloadTask.resume() + + return ActionDisposable { + } + } - let _ = (combineLatest(queue: .mainQueue(), - walletContext.storage.getWalletRecords(), - walletContext.keychain.encryptionPublicKey() - ) - |> deliverOnMainQueue).start(next: { records, publicKey in - if let record = records.first { - if let publicKey = publicKey { - print("publicKey = \(publicKey.base64EncodedString())") - if record.info.encryptedSecret.publicKey == publicKey { - if record.exportCompleted { - let _ = (walletAddress(publicKey: record.info.publicKey, tonInstance: walletContext.tonInstance) - |> deliverOnMainQueue).start(next: { address in - let infoScreen = WalletInfoScreen(context: walletContext, walletInfo: record.info, address: address, enableDebugActions: false) + let updatedConfig = Promise() + updatedConfig.set(updatedConfigSignal) + + let configPath = documentsPath + "/config" + var initialConfig: Signal = .complete() + if let data = try? Data(contentsOf: URL(fileURLWithPath: configPath)), let string = String(data: data, encoding: .utf8) { + initialConfig = .single(string) + } else { + initialConfig = updatedConfig.get() |> take(1) + } + + let _ = (initialConfig + |> deliverOnMainQueue).start(next: { initialConfig in + let walletContext = WalletContextImpl(basePath: documentsPath, config: initialConfig, blockchainName: "testnet", navigationBarTheme: navigationBarTheme, window: mainWindow) + self.walletContext = walletContext + + let _ = (updatedConfig.get() + |> deliverOnMainQueue).start(next: { config in + if config != initialConfig { + walletContext.tonInstance.updateConfig(config: config, blockchainName: "testnet") + } + }) + + let _ = (combineLatest(queue: .mainQueue(), + walletContext.storage.getWalletRecords(), + walletContext.keychain.encryptionPublicKey() + ) + |> deliverOnMainQueue).start(next: { records, publicKey in + if let record = records.first { + if let publicKey = publicKey { + print("publicKey = \(publicKey.base64EncodedString())") + if record.info.encryptedSecret.publicKey == publicKey { + if record.exportCompleted { + let _ = (walletAddress(publicKey: record.info.publicKey, tonInstance: walletContext.tonInstance) + |> deliverOnMainQueue).start(next: { address in + let infoScreen = WalletInfoScreen(context: walletContext, walletInfo: record.info, address: address, enableDebugActions: false) - navigationController.setViewControllers([infoScreen], animated: false) - }) + navigationController.setViewControllers([infoScreen], animated: false) + }) + } else { + let createdScreen = WalletSplashScreen(context: walletContext, mode: .created(record.info, nil), walletCreatedPreloadState: nil) + + navigationController.setViewControllers([createdScreen], animated: false) + } } else { - let createdScreen = WalletSplashScreen(context: walletContext, mode: .created(record.info, nil), walletCreatedPreloadState: nil) + let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageReset(.changed), walletCreatedPreloadState: nil) - navigationController.setViewControllers([createdScreen], animated: false) + navigationController.setViewControllers([splashScreen], animated: false) } } else { - let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageReset(.changed), walletCreatedPreloadState: nil) + let splashScreen = WalletSplashScreen(context: walletContext, mode: WalletSplashMode.secureStorageReset(.notAvailable), walletCreatedPreloadState: nil) navigationController.setViewControllers([splashScreen], animated: false) } } else { - let splashScreen = WalletSplashScreen(context: walletContext, mode: WalletSplashMode.secureStorageReset(.notAvailable), walletCreatedPreloadState: nil) - - navigationController.setViewControllers([splashScreen], animated: false) + if publicKey != nil { + let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } else { + let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageNotAvailable, walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } } - } else { - if publicKey != nil { - let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil) - - navigationController.setViewControllers([splashScreen], animated: false) - } else { - let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageNotAvailable, walletCreatedPreloadState: nil) - - navigationController.setViewControllers([splashScreen], animated: false) - } - } + }) }) - mainWindow.viewController = navigationController - - self.window?.makeKeyAndVisible() return true } } - -private final class Serialization: NSObject, MTSerialization { - func currentLayer() -> UInt { - return 106 - } - - func parseMessage(_ data: Data!) -> Any! { - return nil - } - - func exportAuthorization(_ datacenterId: Int32, data: AutoreleasingUnsafeMutablePointer!) -> MTExportAuthorizationResponseParser! { - return nil - } - - func importAuthorization(_ authId: Int32, bytes: Data!) -> Data! { - return Data() - } - - func requestDatacenterAddress(with data: AutoreleasingUnsafeMutablePointer!) -> MTRequestDatacenterAddressListParser! { - return { _ in - return nil - } - } - - func requestNoop(_ data: AutoreleasingUnsafeMutablePointer!) -> MTRequestNoopParser! { - return { _ in - return nil - } - } -} - -private final class Keychain: NSObject, MTKeychain { - let get: (String) -> Data? - let set: (String, Data) -> Void - let remove: (String) -> Void - - init(get: @escaping (String) -> Data?, set: @escaping (String, Data) -> Void, remove: @escaping (String) -> Void) { - self.get = get - self.set = set - self.remove = remove - } - - func setObject(_ object: Any!, forKey aKey: String!, group: String!) { - if let object = object { - let data = NSKeyedArchiver.archivedData(withRootObject: object) - self.set(group + ":" + aKey, data) - } else { - self.remove(group + ":" + aKey) - } - } - - func object(forKey aKey: String!, group: String!) -> Any! { - if let data = self.get(group + ":" + aKey) { - return NSKeyedUnarchiver.unarchiveObject(with: data as Data) - } - return nil - } - - func removeObject(forKey aKey: String!, group: String!) { - self.remove(group + ":" + aKey) - } - - func dropGroup(_ group: String!) { - - } -} - -private final class TonProxyImpl: TonNetworkProxy { - private let context: MTContext - private let mtProto: MTProto - private let requestService: MTRequestMessageService - - init() { - let serialization = Serialization() - - var apiEnvironment = MTApiEnvironment() - - apiEnvironment.apiId = 8 - apiEnvironment.langPack = "ios" - apiEnvironment.layer = serialization.currentLayer() as NSNumber - apiEnvironment.disableUpdates = true - apiEnvironment = apiEnvironment.withUpdatedLangPackCode("en") - - self.context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment, isTestingEnvironment: false, useTempAuthKeys: false) - - let seedAddressList: [Int: [String]] - - seedAddressList = [ - 1: ["149.154.175.50", "2001:b28:f23d:f001::a"], - 2: ["149.154.167.50", "2001:67c:4e8:f002::a"], - 3: ["149.154.175.100", "2001:b28:f23d:f003::a"], - 4: ["149.154.167.91", "2001:67c:4e8:f004::a"], - 5: ["149.154.171.5", "2001:b28:f23f:f005::a"] - ] - - for (id, ips) in seedAddressList { - self.context.setSeedAddressSetForDatacenterWithId(id, seedAddressSet: MTDatacenterAddressSet(addressList: ips.map { MTDatacenterAddress(ip: $0, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false, secret: nil)! })) - } - - let keychainDict = Atomic<[String: Data]>(value: [:]) - self.context.keychain = Keychain(get: { key in - return keychainDict.with { dict -> Data? in - return dict[key] - } - }, set: { key, value in - let _ = keychainDict.modify { dict in - var dict = dict - dict[key] = value - return dict - } - }, remove: { key in - let _ = keychainDict.modify { dict in - var dict = dict - dict.removeValue(forKey: key) - return dict - } - }) - - let mtProto = MTProto(context: self.context, datacenterId: 2, usageCalculationInfo: nil)! - mtProto.useTempAuthKeys = self.context.useTempAuthKeys - mtProto.checkForProxyConnectionIssues = false - - self.mtProto = mtProto - - self.requestService = MTRequestMessageService(context: context)! - mtProto.add(self.requestService) - - self.mtProto.resume() - } - - func request(data: Data, timeout: Double, completion: @escaping (TonNetworkProxyResult) -> Void) -> Disposable { - let request = MTRequest() - let outputStream = MTOutputStream() - - //wallet.sendLiteRequest#e2c9d33e body:bytes = wallet.LiteResponse; - outputStream.write(Int32(bitPattern: 0xe2c9d33e as UInt32)) - outputStream.writeBytes(data) - - request.setPayload(outputStream.currentBytes(), metadata: "wallet.sendLiteRequest", shortMetadata: "wallet.sendLiteRequest", responseParser: { response in - guard let response = response else { - return nil - } - let inputStream = MTInputStream(data: response)! - //wallet.liteResponse#764386d7 response:bytes = wallet.LiteResponse; - let signature = inputStream.readInt32() - if (signature != 0x764386d7 as Int32) { - return nil - } - return inputStream.readBytes() - }) - - request.dependsOnPasswordEntry = false - request.shouldContinueExecutionWithErrorContext = { _ in - return true - }; - - request.completed = { response, _, error in - if let response = response as? Data { - completion(.reponse(response)) - } else { - completion(.error(error?.errorDescription ?? "UNKNOWN ERROR")) - } - } - - let requestId = request.internalId - - self.requestService.add(request) - - return ActionDisposable { [weak self] in - self?.requestService.removeRequest(byInternalId: requestId) - } - } -} - diff --git a/submodules/BuildConfig/BUCK b/submodules/BuildConfig/BUCK index 1acc7024d4..ad29259a3b 100644 --- a/submodules/BuildConfig/BUCK +++ b/submodules/BuildConfig/BUCK @@ -22,7 +22,7 @@ static_library( "Sources/*.h", ]), deps = [ - "//submodules/MtProtoKit:MtProtoKit#shared", + "//submodules/PKCS:PKCS", ], frameworks = [ "$SDKROOT/System/Library/Frameworks/Foundation.framework", diff --git a/submodules/BuildConfig/Sources/BuildConfig.m b/submodules/BuildConfig/Sources/BuildConfig.m index 1472a4e45a..3e9371d03b 100644 --- a/submodules/BuildConfig/Sources/BuildConfig.m +++ b/submodules/BuildConfig/Sources/BuildConfig.m @@ -10,11 +10,17 @@ #include #include -#ifdef BUCK -#import -#else -#import -#endif +#import +#import + +#import + +static NSData *sha1(NSData *data) { + uint8_t digest[20]; + CC_SHA1(data.bytes, (CC_LONG)data.length, digest); + + return [[NSData alloc] initWithBytes:digest length:20]; +} static NSString *telegramApplicationSecretKey = @"telegramApplicationSecretKey_v3"; @@ -376,7 +382,7 @@ API_AVAILABLE(ios(10)) _dataDict[@"name"] = signature.subjectName; } if (signature.data != nil) { - _dataDict[@"data"] = [MTSha1(signature.data) base64EncodedStringWithOptions:0]; + _dataDict[@"data"] = [sha1(signature.data) base64EncodedStringWithOptions:0]; _dataDict[@"data1"] = [signature.data base64EncodedStringWithOptions:0]; } } diff --git a/submodules/Display/Display/StatusBarProxyNode.swift b/submodules/Display/Display/StatusBarProxyNode.swift index c94991ad74..51e8d97832 100644 --- a/submodules/Display/Display/StatusBarProxyNode.swift +++ b/submodules/Display/Display/StatusBarProxyNode.swift @@ -16,6 +16,8 @@ public enum StatusBarStyle { self = .White case .blackOpaque: self = .Black + default: + self = .Black } } diff --git a/submodules/PKCS/BUCK b/submodules/PKCS/BUCK new file mode 100644 index 0000000000..b699dbded7 --- /dev/null +++ b/submodules/PKCS/BUCK @@ -0,0 +1,20 @@ +load("//Config:buck_rule_macros.bzl", "static_library") + +static_library( + name = "PKCS", + srcs = glob([ + "Sources/**/*.m", + ]), + headers = glob([ + "Sources/**/*.h", + ]), + exported_headers = glob([ + "Sources/**/*.h", + ]), + deps = [ + "//submodules/openssl:openssl", + ], + frameworks = [ + "$SDKROOT/System/Library/Frameworks/Foundation.framework", + ], +) diff --git a/submodules/MtProtoKit/MTPKCS.h b/submodules/PKCS/Sources/MTPKCS.h similarity index 100% rename from submodules/MtProtoKit/MTPKCS.h rename to submodules/PKCS/Sources/MTPKCS.h diff --git a/submodules/MtProtoKit/MTPKCS.m b/submodules/PKCS/Sources/MTPKCS.m similarity index 100% rename from submodules/MtProtoKit/MTPKCS.m rename to submodules/PKCS/Sources/MTPKCS.m diff --git a/submodules/TonBinding/BUCK b/submodules/TonBinding/BUCK index 3d8a31a3e2..07e0b121d2 100644 --- a/submodules/TonBinding/BUCK +++ b/submodules/TonBinding/BUCK @@ -4,13 +4,17 @@ static_library( name = "TonBinding", srcs = glob([ "Sources/**/*.m", + "Sources/**/*.mm", ]), - headers = merge_maps([ + headers = glob([ + "Sources/**/*.h", + ]), + exported_headers = glob([ "Sources/**/*.h", ]), visibility = ["PUBLIC"], deps = [ - "//submodules/SSignalKit/SignalKit:SSignalKit", + "//submodules/SSignalKit/SSignalKit:SSignalKit", "//submodules/openssl:openssl", "//submodules/ton:ton", ], diff --git a/submodules/TonBinding/Sources/TON.h b/submodules/TonBinding/Sources/TON.h index 1edd403edb..7919a6b48f 100644 --- a/submodules/TonBinding/Sources/TON.h +++ b/submodules/TonBinding/Sources/TON.h @@ -1,9 +1,8 @@ #import +#import NS_ASSUME_NONNULL_BEGIN -@class MTSignal; - @interface TONError : NSObject @property (nonatomic, strong, readonly) NSString *text; @@ -88,15 +87,17 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config blockchainName:(NSString *)blockchainName performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest enableExternalRequests:(bool)enableExternalRequests; -- (MTSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword; -- (MTSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey; -- (MTSignal *)getAccountStateWithAddress:(NSString *)accountAddress; -- (MTSignal *)sendGramsFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount textMessage:(NSData *)textMessage forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId; -- (MTSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword; -- (MTSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList; -- (MTSignal *)deleteKey:(TONKey *)key; -- (MTSignal *)deleteAllKeys; -- (MTSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash; +- (SSignal *)updateConfig:(NSString *)config blockchainName:(NSString *)blockchainName; + +- (SSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword; +- (SSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey; +- (SSignal *)getAccountStateWithAddress:(NSString *)accountAddress; +- (SSignal *)sendGramsFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount textMessage:(NSData *)textMessage forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId; +- (SSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword; +- (SSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList; +- (SSignal *)deleteKey:(TONKey *)key; +- (SSignal *)deleteAllKeys; +- (SSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash; - (NSData *)encrypt:(NSData *)decryptedData secret:(NSData *)data; - (NSData * __nullable)decrypt:(NSData *)encryptedData secret:(NSData *)data; diff --git a/submodules/TonBinding/Sources/TON.mm b/submodules/TonBinding/Sources/TON.mm index 0abd427c7b..11bc24b962 100644 --- a/submodules/TonBinding/Sources/TON.mm +++ b/submodules/TonBinding/Sources/TON.mm @@ -1,9 +1,6 @@ #import "TON.h" -#import "MTLogging.h" #import "tonlib/Client.h" -#import "MTQueue.h" -#import "MTSignal.h" static td::SecureString makeSecureString(NSData * _Nonnull data) { if (data == nil || data.length == 0) { @@ -226,9 +223,10 @@ typedef enum { uint64_t _nextRequestId; NSLock *_requestHandlersLock; NSMutableDictionary *_requestHandlers; - MTPipe *_initializedStatus; + SPipe *_initializedStatus; NSMutableSet *_sendGramRandomIds; - MTQueue *_queue; + SQueue *_queue; + bool _enableExternalRequests; } @end @@ -247,13 +245,14 @@ typedef enum { - (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config blockchainName:(NSString *)blockchainName performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest enableExternalRequests:(bool)enableExternalRequests { self = [super init]; if (self != nil) { - _queue = [MTQueue mainQueue]; + _queue = [SQueue mainQueue]; _requestHandlersLock = [[NSLock alloc] init]; _requestHandlers = [[NSMutableDictionary alloc] init]; - _initializedStatus = [[MTPipe alloc] initWithReplay:true]; + _initializedStatus = [[SPipe alloc] initWithReplay:true]; _initializedStatus.sink(@(TONInitializationStatusInitializing)); _nextRequestId = 1; _sendGramRandomIds = [[NSMutableSet alloc] init]; + _enableExternalRequests = enableExternalRequests; _client = std::make_shared(); @@ -306,7 +305,7 @@ typedef enum { [[NSFileManager defaultManager] createDirectoryAtPath:keystoreDirectory withIntermediateDirectories:true attributes:nil error:nil]; - MTPipe *initializedStatus = _initializedStatus; + SPipe *initializedStatus = _initializedStatus; [[self requestInitWithConfigString:config blockchainName:blockchainName keystoreDirectory:keystoreDirectory enableExternalRequests:enableExternalRequests] startWithNext:nil error:^(id error) { NSString *errorText = @"Unknown error"; if ([error isKindOfClass:[TONError class]]) { @@ -354,8 +353,8 @@ typedef enum { return readSecureString(value->bytes_); } -- (MTSignal *)requestInitWithConfigString:(NSString *)configString blockchainName:(NSString *)blockchainName keystoreDirectory:(NSString *)keystoreDirectory enableExternalRequests:(bool)enableExternalRequests { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)requestInitWithConfigString:(NSString *)configString blockchainName:(NSString *)blockchainName keystoreDirectory:(NSString *)keystoreDirectory enableExternalRequests:(bool)enableExternalRequests { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { uint64_t requestId = _nextRequestId; _nextRequestId += 1; @@ -381,13 +380,42 @@ typedef enum { )); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)updateConfig:(NSString *)config blockchainName:(NSString *)blockchainName { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { + uint64_t requestId = _nextRequestId; + _nextRequestId += 1; + + _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { + if (object->get_id() == tonlib_api::error::ID) { + auto error = tonlib_api::move_object_as(object); + [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; + } else { + [subscriber putCompletion]; + } + }]; + + auto query = make_object( + make_object( + config.UTF8String, + blockchainName.UTF8String, + _enableExternalRequests, + false + ) + ); + _client->send({ requestId, std::move(query) }); + + return [[SBlockDisposable alloc] initWithBlock:^{ + }]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; +} + +- (SSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { uint64_t requestId = _nextRequestId; _nextRequestId += 1; @@ -417,17 +445,17 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { NSData *publicKeyData = [publicKey dataUsingEncoding:NSUTF8StringEncoding]; if (publicKeyData == nil) { [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in getWalletAccountAddressWithPublicKey"]]; - return [[MTBlockDisposable alloc] initWithBlock:^{}]; + return [[SBlockDisposable alloc] initWithBlock:^{}]; } uint64_t requestId = _nextRequestId; @@ -453,13 +481,13 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)getAccountStateWithAddress:(NSString *)accountAddress { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)getAccountStateWithAddress:(NSString *)accountAddress { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { uint64_t requestId = _nextRequestId; _nextRequestId += 1; @@ -491,34 +519,34 @@ typedef enum { auto query = make_object(make_object(accountAddress.UTF8String)); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)sendGramsFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount textMessage:(NSData *)textMessage forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)sendGramsFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount textMessage:(NSData *)textMessage forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { if ([_sendGramRandomIds containsObject:@(randomId)]) { [_sendGramRandomIds addObject:@(randomId)]; - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; } NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; if (publicKeyData == nil) { [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in sendGramsFromKey"]]; - return [[MTBlockDisposable alloc] initWithBlock:^{}]; + return [[SBlockDisposable alloc] initWithBlock:^{}]; } uint64_t requestId = _nextRequestId; _nextRequestId += 1; __weak TON *weakSelf = self; - MTQueue *queue = _queue; + SQueue *queue = _queue; _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { if (object->get_id() == tonlib_api::error::ID) { - [queue dispatchOnQueue:^{ + [queue dispatch:^{ __strong TON *strongSelf = weakSelf; if (strongSelf != nil) { [_sendGramRandomIds removeObject:@(randomId)]; @@ -553,17 +581,17 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; if (publicKeyData == nil) { [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in exportKey"]]; - return [[MTBlockDisposable alloc] initWithBlock:^{}]; + return [[SBlockDisposable alloc] initWithBlock:^{}]; } uint64_t requestId = _nextRequestId; @@ -601,13 +629,13 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { uint64_t requestId = _nextRequestId; _nextRequestId += 1; @@ -642,17 +670,17 @@ typedef enum { make_object(std::move(wordVector))); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)deleteKey:(TONKey *)key { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)deleteKey:(TONKey *)key { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; if (publicKeyData == nil) { [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in deleteKey"]]; - return [[MTBlockDisposable alloc] initWithBlock:^{}]; + return [[SBlockDisposable alloc] initWithBlock:^{}]; } uint64_t requestId = _nextRequestId; @@ -675,13 +703,13 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)deleteAllKeys { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)deleteAllKeys { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { uint64_t requestId = _nextRequestId; _nextRequestId += 1; @@ -697,17 +725,17 @@ typedef enum { auto query = make_object(); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (MTSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash { - return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { +- (SSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash { + return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { NSData *addressData = [address dataUsingEncoding:NSUTF8StringEncoding]; if (addressData == nil) { [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in getTransactionListWithAddress"]]; - return [[MTBlockDisposable alloc] initWithBlock:^{}]; + return [[SBlockDisposable alloc] initWithBlock:^{}]; } uint64_t requestId = _nextRequestId; @@ -750,9 +778,9 @@ typedef enum { ); _client->send({ requestId, std::move(query) }); - return [[MTBlockDisposable alloc] initWithBlock:^{ + return [[SBlockDisposable alloc] initWithBlock:^{ }]; - }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; + }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } @end diff --git a/submodules/WalletCore/BUCK b/submodules/WalletCore/BUCK index ae7be0dc60..e496db94cd 100644 --- a/submodules/WalletCore/BUCK +++ b/submodules/WalletCore/BUCK @@ -6,7 +6,6 @@ static_library( "Sources/**/*.swift", ]), deps = [ - "//submodules/MtProtoKit:MtProtoKit#shared", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared", "//submodules/TonBinding:TonBinding", ], diff --git a/submodules/WalletCore/Sources/WalletCore.swift b/submodules/WalletCore/Sources/WalletCore.swift index b376a546ec..ae84de5388 100644 --- a/submodules/WalletCore/Sources/WalletCore.swift +++ b/submodules/WalletCore/Sources/WalletCore.swift @@ -4,7 +4,7 @@ import SwiftSignalKitMac import MtProtoKitMac #else import SwiftSignalKit -import MtProtoKit +import TonBinding #endif public struct TonKeychainEncryptedData: Codable, Equatable { @@ -102,6 +102,24 @@ public final class TonInstance { }) } + public func updateConfig(config: String, blockchainName: String) -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + self.impl.with { impl in + impl.withInstance { ton in + let cancel = ton.updateConfig(config, blockchainName: blockchainName).start(next: nil, error: { _ in + }, completed: { + subscriber.putCompletion() + }) + disposable.set(ActionDisposable { + cancel?.dispose() + }) + } + } + return disposable + } + } + fileprivate func exportKey(key: TONKey, localPassword: Data) -> Signal<[String], NoError> { return Signal { subscriber in let disposable = MetaDisposable()