mirror of
https://github.com/lil-org/wallet.git
synced 2024-12-29 15:32:31 +03:00
show balance on ios transaction screen
This commit is contained in:
parent
27aeeeaf20
commit
71c602325b
@ -2,6 +2,7 @@
|
||||
|
||||
import Foundation
|
||||
import WalletCore
|
||||
import BigInt
|
||||
|
||||
struct Ethereum {
|
||||
|
||||
@ -16,6 +17,13 @@ struct Ethereum {
|
||||
static let shared = Ethereum()
|
||||
private let rpc = EthereumRPC()
|
||||
|
||||
func getBalance(network: EthereumNetwork, address: String, completion: @escaping (BigInt) -> Void) {
|
||||
rpc.getBalance(rpcUrl: network.nodeURLString, for: address) { result in
|
||||
guard case let .success(hex) = result, let balance = BigInt(hexString: hex) else { return }
|
||||
DispatchQueue.main.async { completion(balance) }
|
||||
}
|
||||
}
|
||||
|
||||
func sign(data: Data, privateKey: WalletCore.PrivateKey) throws -> String {
|
||||
return try sign(data: data, privateKey: privateKey, addPrefix: false)
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ class EthereumRPC {
|
||||
request(method: "eth_gasPrice", params: [], rpcUrl: rpcUrl, completion: completion)
|
||||
}
|
||||
|
||||
func getBalance(rpcUrl: String, for address: String, completion: @escaping (Result<String, Error>) -> Void) {
|
||||
request(method: "eth_getBalance", params: [address, "pending"], rpcUrl: rpcUrl, completion: completion)
|
||||
}
|
||||
|
||||
func fetchNonce(rpcUrl: String, for address: String, completion: @escaping (Result<String, Error>) -> Void) {
|
||||
request(method: "eth_getTransactionCount", params: [address, "pending"], rpcUrl: rpcUrl, completion: completion)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ struct Transaction {
|
||||
let gas = BigInt(hexString: gasString) {
|
||||
let fee = gas * gasPrice
|
||||
let costString = chain.mightShowPrice ? cost(value: fee, price: price) : ""
|
||||
feeString = fee.eth(ofFee: true) + " \(chain.symbol)" + costString
|
||||
feeString = fee.eth(shortest: true) + " \(chain.symbol)" + costString
|
||||
} else {
|
||||
feeString = Strings.calculating
|
||||
}
|
||||
|
@ -13,14 +13,22 @@ extension BigInt {
|
||||
return NSDecimalNumber(string: String(self))
|
||||
}
|
||||
|
||||
func eth(ofFee: Bool = false) -> String {
|
||||
func eth(shortest: Bool = false) -> String {
|
||||
let ethDecimal = decimal.multiplying(byPowerOf10: -18)
|
||||
guard ofFee else { return ethDecimal.stringValue }
|
||||
let formatter = NumberFormatter()
|
||||
|
||||
if shortest {
|
||||
formatter.minimumFractionDigits = 3
|
||||
formatter.maximumFractionDigits = 6
|
||||
formatter.minimumSignificantDigits = 1
|
||||
formatter.maximumSignificantDigits = 2
|
||||
} else {
|
||||
formatter.minimumFractionDigits = 6
|
||||
formatter.maximumFractionDigits = 11
|
||||
formatter.minimumSignificantDigits = 1
|
||||
formatter.maximumSignificantDigits = 11
|
||||
}
|
||||
|
||||
return formatter.string(from: ethDecimal) ?? .zero
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ class ApproveTransactionViewController: UIViewController {
|
||||
|
||||
private enum CellModel {
|
||||
case text(text: String, oneLine: Bool)
|
||||
case textWithImage(text: String, imageURL: String?, image: UIImage?)
|
||||
case textWithImage(text: String, extraText: String?, imageURL: String?, image: UIImage?)
|
||||
case gasPriceSlider
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ class ApproveTransactionViewController: UIViewController {
|
||||
private var completion: ((Transaction?) -> Void)!
|
||||
private var didCallCompletion = false
|
||||
private var peerMeta: PeerMeta?
|
||||
private var balance: String?
|
||||
|
||||
@IBOutlet weak var okButton: UIButton!
|
||||
@IBOutlet weak var cancelButton: UIButton!
|
||||
@ -68,6 +69,11 @@ class ApproveTransactionViewController: UIViewController {
|
||||
updateDisplayedTransactionInfo(initially: true)
|
||||
prepareTransaction()
|
||||
enableSpeedConfigurationIfNeeded()
|
||||
|
||||
ethereum.getBalance(network: chain, address: account.address) { [weak self] balance in
|
||||
self?.balance = balance.eth(shortest: true) + " " + (self?.chain.symbol ?? "")
|
||||
self?.updateDisplayedTransactionInfo(initially: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func prepareTransaction() {
|
||||
@ -80,9 +86,9 @@ class ApproveTransactionViewController: UIViewController {
|
||||
|
||||
private func updateDisplayedTransactionInfo(initially: Bool) {
|
||||
var cellModels: [CellModel] = [
|
||||
.textWithImage(text: peerMeta?.name ?? Strings.unknownWebsite, imageURL: peerMeta?.iconURLString, image: nil),
|
||||
.textWithImage(text: account.croppedAddress, imageURL: nil, image: account.image),
|
||||
.textWithImage(text: chain.name, imageURL: nil, image: Images.network)
|
||||
.textWithImage(text: peerMeta?.name ?? Strings.unknownWebsite, extraText: nil, imageURL: peerMeta?.iconURLString, image: nil),
|
||||
.textWithImage(text: account.croppedAddress, extraText: balance, imageURL: nil, image: account.image),
|
||||
.textWithImage(text: chain.name, extraText: nil, imageURL: nil, image: Images.network)
|
||||
]
|
||||
|
||||
let price = priceService.forNetwork(chain)
|
||||
@ -173,9 +179,9 @@ extension ApproveTransactionViewController: UITableViewDataSource {
|
||||
let cell = tableView.dequeueReusableCellOfType(MultilineLabelTableViewCell.self, for: indexPath)
|
||||
cell.setup(text: text, largeFont: true, oneLine: oneLine)
|
||||
return cell
|
||||
case let .textWithImage(text: text, imageURL: imageURL, image: image):
|
||||
case let .textWithImage(text: text, extraText: extraText, imageURL: imageURL, image: image):
|
||||
let cell = tableView.dequeueReusableCellOfType(ImageWithLabelTableViewCell.self, for: indexPath)
|
||||
cell.setup(text: text, imageURL: imageURL, image: image)
|
||||
cell.setup(text: text, extraText: extraText, imageURL: imageURL, image: image)
|
||||
return cell
|
||||
case .gasPriceSlider:
|
||||
let cell = tableView.dequeueReusableCellOfType(GasPriceSliderTableViewCell.self, for: indexPath)
|
||||
|
@ -99,7 +99,7 @@ extension ApproveViewController: UITableViewDataSource {
|
||||
return cell
|
||||
case let .textWithImage(text: text, imageURL: imageURL, image: image):
|
||||
let cell = tableView.dequeueReusableCellOfType(ImageWithLabelTableViewCell.self, for: indexPath)
|
||||
cell.setup(text: text, imageURL: imageURL, image: image)
|
||||
cell.setup(text: text, extraText: nil, imageURL: imageURL, image: image)
|
||||
return cell
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,11 @@ class ImageWithLabelTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet weak var iconImageView: UIImageView!
|
||||
@IBOutlet weak var titleLabel: UILabel!
|
||||
@IBOutlet weak var extraTitleLabel: UILabel!
|
||||
|
||||
func setup(text: String, imageURL: String?, image: UIImage?) {
|
||||
func setup(text: String, extraText: String?, imageURL: String?, image: UIImage?) {
|
||||
titleLabel.text = text
|
||||
extraTitleLabel.text = extraText
|
||||
if let image = image {
|
||||
iconImageView.image = image
|
||||
iconImageView.layer.cornerRadius = 15
|
||||
|
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
@ -23,6 +24,12 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="370-qE-3uX">
|
||||
<rect key="frame" x="117.5" y="9.5" width="50" height="25.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="21"/>
|
||||
<color key="textColor" systemColor="tertiaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="circle.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="s2U-ez-xAZ">
|
||||
<rect key="frame" x="16" y="7.5" width="30" height="29"/>
|
||||
<color key="tintColor" systemColor="secondarySystemFillColor"/>
|
||||
@ -33,17 +40,21 @@
|
||||
</imageView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="370-qE-3uX" secondAttribute="trailing" constant="12" id="5jf-b4-aHe"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="Xtv-Wf-ono" secondAttribute="bottom" constant="12" id="7b6-zL-uFv"/>
|
||||
<constraint firstItem="s2U-ez-xAZ" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="KRd-w8-2MB"/>
|
||||
<constraint firstItem="Xtv-Wf-ono" firstAttribute="leading" secondItem="s2U-ez-xAZ" secondAttribute="trailing" constant="8" id="M1l-nB-oFH"/>
|
||||
<constraint firstItem="s2U-ez-xAZ" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="ZLm-uW-cps"/>
|
||||
<constraint firstItem="Xtv-Wf-ono" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="12" id="aro-oL-Eck"/>
|
||||
<constraint firstItem="370-qE-3uX" firstAttribute="leading" secondItem="Xtv-Wf-ono" secondAttribute="trailing" constant="12" id="h8A-9Y-XIV"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Xtv-Wf-ono" secondAttribute="trailing" constant="8" id="hxx-LP-Qrk"/>
|
||||
<constraint firstItem="370-qE-3uX" firstAttribute="centerY" secondItem="Xtv-Wf-ono" secondAttribute="centerY" id="kAI-RH-VZo"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
|
||||
<inset key="separatorInset" minX="16" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<connections>
|
||||
<outlet property="extraTitleLabel" destination="370-qE-3uX" id="zX1-dg-hak"/>
|
||||
<outlet property="iconImageView" destination="s2U-ez-xAZ" id="0eX-WD-IT0"/>
|
||||
<outlet property="titleLabel" destination="Xtv-Wf-ono" id="N8A-jp-bJP"/>
|
||||
</connections>
|
||||
@ -51,9 +62,12 @@
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="circle.fill" catalog="system" width="128" height="121"/>
|
||||
<image name="circle.fill" catalog="system" width="128" height="123"/>
|
||||
<systemColor name="secondarySystemFillColor">
|
||||
<color red="0.47058823529411764" green="0.47058823529411764" blue="0.50196078431372548" alpha="0.16" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="tertiaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.29803921568627451" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
Loading…
Reference in New Issue
Block a user