mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-25 09:32:46 +00:00
Add sendGrams method [skip ci]
This commit is contained in:
parent
52b3521a51
commit
fa3bb5d9c5
@ -316,6 +316,36 @@ public final class TonInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func sendGramsFromWallet(keychain: TonKeychain, serverSalt: Data, walletInfo: WalletInfo, fromAddress: String, toAddress: String, amount: Int64) -> Signal<Never, SendGramsFromWalletError> {
|
||||||
|
return keychain.decrypt(walletInfo.encryptedSecret.rawValue)
|
||||||
|
|> introduceError(SendGramsFromWalletError.self)
|
||||||
|
|> mapToSignal { decryptedSecret -> Signal<Never, SendGramsFromWalletError> in
|
||||||
|
guard let decryptedSecret = decryptedSecret else {
|
||||||
|
return .fail(.secretDecryptionFailed)
|
||||||
|
}
|
||||||
|
return Signal { subscriber in
|
||||||
|
let disposable = MetaDisposable()
|
||||||
|
|
||||||
|
self.impl.with { impl in
|
||||||
|
impl.withInstance { ton in
|
||||||
|
let cancel = ton.sendGrams(from: TONKey(publicKey: walletInfo.publicKey.rawValue, secret: decryptedSecret), localPassword: serverSalt, fromAddress: fromAddress, toAddress: toAddress, amount: amount).start(next: { _ in
|
||||||
|
preconditionFailure()
|
||||||
|
}, error: { _ in
|
||||||
|
subscriber.putError(.generic)
|
||||||
|
}, completed: {
|
||||||
|
subscriber.putCompletion()
|
||||||
|
})
|
||||||
|
disposable.set(ActionDisposable {
|
||||||
|
cancel?.dispose()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return disposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileprivate func walletRestoreWords(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<[String], WalletRestoreWordsError> {
|
fileprivate func walletRestoreWords(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<[String], WalletRestoreWordsError> {
|
||||||
return keychain.decrypt(walletInfo.encryptedSecret.rawValue)
|
return keychain.decrypt(walletInfo.encryptedSecret.rawValue)
|
||||||
|> introduceError(WalletRestoreWordsError.self)
|
|> introduceError(WalletRestoreWordsError.self)
|
||||||
@ -524,6 +554,25 @@ public func getGramsFromTestGiver(address: String, amount: Int64, tonInstance: T
|
|||||||
return tonInstance.getGramsFromTestGiver(address: address, amount: amount)
|
return tonInstance.getGramsFromTestGiver(address: address, amount: amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SendGramsFromWalletError {
|
||||||
|
case generic
|
||||||
|
case secretDecryptionFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
public func sendGramsFromWallet(network: Network, tonInstance: TonInstance, keychain: TonKeychain, walletInfo: WalletInfo, toAddress: String, amount: Int64) -> Signal<Never, SendGramsFromWalletError> {
|
||||||
|
return getServerWalletSalt(network: network)
|
||||||
|
|> mapError { _ -> SendGramsFromWalletError in
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
|
|> mapToSignal { serverSalt in
|
||||||
|
return walletAddress(publicKey: walletInfo.publicKey, tonInstance: tonInstance)
|
||||||
|
|> introduceError(SendGramsFromWalletError.self)
|
||||||
|
|> mapToSignal { fromAddress in
|
||||||
|
return tonInstance.sendGramsFromWallet(keychain: keychain, serverSalt: serverSalt, walletInfo: walletInfo, fromAddress: fromAddress, toAddress: toAddress, amount: amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct WalletTransactionId: Hashable {
|
public struct WalletTransactionId: Hashable {
|
||||||
public var lt: Int64
|
public var lt: Int64
|
||||||
public var transactionHash: Data
|
public var transactionHash: Data
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import AnimationUI
|
|||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import OverlayStatusController
|
import OverlayStatusController
|
||||||
import ItemListUI
|
import ItemListUI
|
||||||
|
import TelegramStringFormatting
|
||||||
|
|
||||||
private final class WalletTransactionInfoControllerArguments {
|
private final class WalletTransactionInfoControllerArguments {
|
||||||
let copyWalletAddress: () -> Void
|
let copyWalletAddress: () -> Void
|
||||||
@ -29,7 +30,7 @@ private enum WalletTransactionInfoSection: Int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum WalletTransactionInfoEntry: ItemListNodeEntry {
|
private enum WalletTransactionInfoEntry: ItemListNodeEntry {
|
||||||
case amount(PresentationTheme, WalletTransaction)
|
case amount(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, WalletTransaction)
|
||||||
case infoHeader(PresentationTheme, String)
|
case infoHeader(PresentationTheme, String)
|
||||||
case infoAddress(PresentationTheme, String)
|
case infoAddress(PresentationTheme, String)
|
||||||
case infoCopyAddress(PresentationTheme, String)
|
case infoCopyAddress(PresentationTheme, String)
|
||||||
@ -65,8 +66,8 @@ private enum WalletTransactionInfoEntry: ItemListNodeEntry {
|
|||||||
|
|
||||||
func item(_ arguments: WalletTransactionInfoControllerArguments) -> ListViewItem {
|
func item(_ arguments: WalletTransactionInfoControllerArguments) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .amount(theme, walletTransaction):
|
case let .amount(theme, strings, dateTimeFormat, walletTransaction):
|
||||||
return WalletTransactionHeaderItem(theme: theme, walletTransaction: walletTransaction, sectionId: self.section)
|
return WalletTransactionHeaderItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, walletTransaction: walletTransaction, sectionId: self.section)
|
||||||
case let .infoHeader(theme, text):
|
case let .infoHeader(theme, text):
|
||||||
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
||||||
case let .infoAddress(theme, text):
|
case let .infoAddress(theme, text):
|
||||||
@ -113,7 +114,7 @@ private func extractAddress(_ walletTransaction: WalletTransaction) -> String {
|
|||||||
private func walletTransactionInfoControllerEntries(presentationData: PresentationData, walletTransaction: WalletTransaction, state: WalletTransactionInfoControllerState) -> [WalletTransactionInfoEntry] {
|
private func walletTransactionInfoControllerEntries(presentationData: PresentationData, walletTransaction: WalletTransaction, state: WalletTransactionInfoControllerState) -> [WalletTransactionInfoEntry] {
|
||||||
var entries: [WalletTransactionInfoEntry] = []
|
var entries: [WalletTransactionInfoEntry] = []
|
||||||
|
|
||||||
entries.append(.amount(presentationData.theme, walletTransaction))
|
entries.append(.amount(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, walletTransaction))
|
||||||
|
|
||||||
let transferredValue = walletTransaction.transferredValue
|
let transferredValue = walletTransaction.transferredValue
|
||||||
let text = extractAddress(walletTransaction)
|
let text = extractAddress(walletTransaction)
|
||||||
@ -174,12 +175,16 @@ func walletTransactionInfoController(context: AccountContext, walletTransaction:
|
|||||||
|
|
||||||
class WalletTransactionHeaderItem: ListViewItem, ItemListItem {
|
class WalletTransactionHeaderItem: ListViewItem, ItemListItem {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
|
let strings: PresentationStrings
|
||||||
|
let dateTimeFormat: PresentationDateTimeFormat
|
||||||
let walletTransaction: WalletTransaction
|
let walletTransaction: WalletTransaction
|
||||||
let sectionId: ItemListSectionId
|
let sectionId: ItemListSectionId
|
||||||
let isAlwaysPlain: Bool = true
|
let isAlwaysPlain: Bool = true
|
||||||
|
|
||||||
init(theme: PresentationTheme, walletTransaction: WalletTransaction, sectionId: ItemListSectionId) {
|
init(theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, walletTransaction: WalletTransaction, sectionId: ItemListSectionId) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.strings = strings
|
||||||
|
self.dateTimeFormat = dateTimeFormat
|
||||||
self.walletTransaction = walletTransaction
|
self.walletTransaction = walletTransaction
|
||||||
self.sectionId = sectionId
|
self.sectionId = sectionId
|
||||||
}
|
}
|
||||||
@ -226,6 +231,7 @@ private let titleBoldFont = Font.semibold(14.0)
|
|||||||
|
|
||||||
private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
||||||
private let titleNode: TextNode
|
private let titleNode: TextNode
|
||||||
|
private let subtitleNode: TextNode
|
||||||
private let iconNode: ASImageNode
|
private let iconNode: ASImageNode
|
||||||
private let activateArea: AccessibilityAreaNode
|
private let activateArea: AccessibilityAreaNode
|
||||||
|
|
||||||
@ -237,6 +243,11 @@ private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
|||||||
self.titleNode.contentMode = .left
|
self.titleNode.contentMode = .left
|
||||||
self.titleNode.contentsScale = UIScreen.main.scale
|
self.titleNode.contentsScale = UIScreen.main.scale
|
||||||
|
|
||||||
|
self.subtitleNode = TextNode()
|
||||||
|
self.subtitleNode.isUserInteractionEnabled = false
|
||||||
|
self.subtitleNode.contentMode = .left
|
||||||
|
self.subtitleNode.contentsScale = UIScreen.main.scale
|
||||||
|
|
||||||
self.iconNode = ASImageNode()
|
self.iconNode = ASImageNode()
|
||||||
self.iconNode.displaysAsynchronously = false
|
self.iconNode.displaysAsynchronously = false
|
||||||
self.iconNode.displayWithoutProcessing = true
|
self.iconNode.displayWithoutProcessing = true
|
||||||
@ -248,12 +259,14 @@ private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
|||||||
super.init(layerBacked: false, dynamicBounce: false)
|
super.init(layerBacked: false, dynamicBounce: false)
|
||||||
|
|
||||||
self.addSubnode(self.titleNode)
|
self.addSubnode(self.titleNode)
|
||||||
|
self.addSubnode(self.subtitleNode)
|
||||||
self.addSubnode(self.iconNode)
|
self.addSubnode(self.iconNode)
|
||||||
self.addSubnode(self.activateArea)
|
self.addSubnode(self.activateArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asyncLayout() -> (_ item: WalletTransactionHeaderItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
func asyncLayout() -> (_ item: WalletTransactionHeaderItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||||
|
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
|
||||||
let iconSize = self.iconNode.image?.size ?? CGSize(width: 10.0, height: 10.0)
|
let iconSize = self.iconNode.image?.size ?? CGSize(width: 10.0, height: 10.0)
|
||||||
|
|
||||||
return { item, params, neighbors in
|
return { item, params, neighbors in
|
||||||
@ -271,8 +284,12 @@ private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
|||||||
titleColor = item.theme.chatList.secretTitleColor
|
titleColor = item.theme.chatList.secretTitleColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let subtitle: String = stringForFullDate(timestamp: Int32(clamping: item.walletTransaction.timestamp), strings: item.strings, dateTimeFormat: item.dateTimeFormat)
|
||||||
|
|
||||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: Font.semibold(39.0), textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: Font.semibold(39.0), textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: subtitle, font: Font.regular(13.0), textColor: item.theme.list.freeTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
let contentSize: CGSize
|
let contentSize: CGSize
|
||||||
|
|
||||||
contentSize = CGSize(width: params.width, height: titleLayout.size.height + verticalInset + verticalInset)
|
contentSize = CGSize(width: params.width, height: titleLayout.size.height + verticalInset + verticalInset)
|
||||||
@ -288,11 +305,14 @@ private class WalletTransactionHeaderItemNode: ListViewItemNode {
|
|||||||
//strongSelf.activateArea.accessibilityLabel = attributedText.string
|
//strongSelf.activateArea.accessibilityLabel = attributedText.string
|
||||||
|
|
||||||
let _ = titleApply()
|
let _ = titleApply()
|
||||||
|
let _ = subtitleApply()
|
||||||
|
|
||||||
let iconSpacing: CGFloat = 8.0
|
let iconSpacing: CGFloat = 8.0
|
||||||
let contentWidth = titleLayout.size.width + iconSpacing + iconSize.width / 2.0
|
let contentWidth = titleLayout.size.width + iconSpacing + iconSize.width / 2.0
|
||||||
let titleFrame = CGRect(origin: CGPoint(x: floor((params.width - contentWidth) / 2.0), y: verticalInset), size: titleLayout.size)
|
let titleFrame = CGRect(origin: CGPoint(x: floor((params.width - contentWidth) / 2.0), y: verticalInset), size: titleLayout.size)
|
||||||
|
let subtitleFrame = CGRect(origin: CGPoint(x: floor((params.width - subtitleLayout.size.width) / 2.0), y: titleFrame.maxY - 5.0), size: subtitleLayout.size)
|
||||||
strongSelf.titleNode.frame = titleFrame
|
strongSelf.titleNode.frame = titleFrame
|
||||||
|
strongSelf.subtitleNode.frame = subtitleFrame
|
||||||
strongSelf.iconNode.frame = CGRect(origin: CGPoint(x: titleFrame.maxX + iconSpacing, y: titleFrame.minY + floor((titleFrame.height - iconSize.height) / 2.0)), size: iconSize)
|
strongSelf.iconNode.frame = CGRect(origin: CGPoint(x: titleFrame.maxX + iconSpacing, y: titleFrame.minY + floor((titleFrame.height - iconSize.height) / 2.0)), size: iconSize)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user