Skip to content

Commit

Permalink
get tx history from api
Browse files Browse the repository at this point in the history
  • Loading branch information
0xChqrles committed Jun 19, 2024
1 parent a9fe0e0 commit 8553775
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 147 deletions.
61 changes: 61 additions & 0 deletions app/App/Models/History.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// History.swift
// Vault
//
// Created by Charles Lanier on 19/06/2024.
//

import Foundation

class User {
let nickname: String
let avatarUrl: String? = nil
let address: String?

init(transactionUser: RawTransactionUser) {
self.nickname = transactionUser.nickname ?? transactionUser.phone_number ?? "UNKNOWN"
self.address = transactionUser.contract_address
}
}

class Transaction: Identifiable {
let from: User
let to: User
let amount: USDCAmount
let date: Date
let isSending: Bool

static let dateFormatter = {
let dateFormatter = DateFormatter()

dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

return dateFormatter
}()

init(address: String, transaction: RawTransaction) {
self.from = User(transactionUser: transaction.from)
self.to = User(transactionUser: transaction.to)
self.amount = USDCAmount(from: transaction.amount)!
self.date = Self.dateFormatter.date(from: transaction.transaction_timestamp)!
self.isSending = transaction.from.contract_address == address
}
}

class History {
let transactions: [Transaction]

var groupedTransactions: [Date: [Transaction]] {
get {
Dictionary(grouping: self.transactions) { (transaction) -> Date in
return Calendar.current.startOfDay(for: transaction.date)
}
}
}

init(address: String, transactions: [RawTransaction]) {
self.transactions = transactions.map { Transaction(address: address, transaction: $0) }
}
}
27 changes: 24 additions & 3 deletions app/App/Models/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ enum Status: Equatable {
class Model: ObservableObject {

@AppStorage("starknetMainAddress") private var address: String = ""
@AppStorage("isOnboarded") var isOnboarded: Bool = false

// API Data
@Published var balance: USDCAmount?
@Published var txHistory: History?

// App
@Published var isLoading = false
Expand Down Expand Up @@ -98,9 +100,8 @@ class Model: ObservableObject {
// Contacts
checkContactsAuthorizationStatus()

self.address = "0x039fd69d03e3735490a86925612072c5612cbf7a0223678619a1b7f30f4bdc8f"

self.getBalance()
self.getTxHistory()
}

deinit {
Expand Down Expand Up @@ -185,6 +186,21 @@ extension Model {
}
}
}

func getTxHistory() {
vaultService.send(GetTransactionsHistory(address: self.address, first: 10)) { result in
DispatchQueue.main.async {
switch result {
case .success(let response):
self.txHistory = History(address: self.address, transactions: response.transactions)

case .failure(let error):
// TODO: Handle error
print(error)
}
}
}
}
}

// MARK: - Country picker
Expand Down Expand Up @@ -248,7 +264,12 @@ extension Model {
guard let phoneNumberFelt = Felt.fromShortString(phoneNumber) else {
return nil
}
let phoneNumberHex = phoneNumberFelt.toHex().dropFirst(2)

// TODO: remove this extra step after nonce support
guard let phoneNumberHex = Felt.fromShortString(phoneNumberFelt.toHex())?.toHex().dropFirst(2) else {
return nil
}

guard let phoneNumberBytes = BigUInt(phoneNumberHex, radix: 16)?.serialize().bytes else {
return nil
}
Expand Down
4 changes: 1 addition & 3 deletions app/App/Navigation/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ struct ContentView: View {

@EnvironmentObject var model: Model

@AppStorage("isOnboarded") var isOnboarded: Bool = false

@State private var selectedTab: Tab = Tab.payments

init() {
Expand All @@ -36,7 +34,7 @@ struct ContentView: View {
var body: some View {
if !self.model.isProperlyConfigured {
ErrorView()
} else if self.isOnboarded {
} else if self.model.isOnboarded {
ZStack(alignment: .bottom) {
TabView(selection: $selectedTab) {
NavigationStack {
Expand Down
149 changes: 29 additions & 120 deletions app/App/Navigation/Core/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,108 +7,12 @@

import SwiftUI

class User {
let address: String
let username: String
let avatarUrl: String?

init(address: String, username: String, avatarUrl: String? = nil) {
self.address = address
self.username = username
self.avatarUrl = avatarUrl
}
}

class Transfer: Identifiable {
let from: User
let to: User
let amount: USDCAmount
let date: Date

init(from: User, to: User, amount: USDCAmount, timestamp: Double) {
self.from = from
self.to = to
self.amount = amount
self.date = Date(timeIntervalSince1970: timestamp)
}
}

class History {
let transfers: [Transfer]

var groupedTransfers: [Date: [Transfer]] {
get {
return Dictionary(grouping: self.transfers) { (transfer) -> Date in
Calendar.current.startOfDay(for: transfer.date)
}
}
}

init(transfers: [Transfer]) {
self.transfers = transfers
}
}

let users: [String: User] = [
"me": User(
address: "0xdead",
username: "Bobby"
),
"sbf": User(
address: "0x1",
username: "SBF",
avatarUrl: "https://fortune.com/img-assets/wp-content/uploads/2022/11/SBF-1.jpg"
),
"apple": User(
address: "0x2",
username: "Apple",
avatarUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIHoznvT47BiebsgSlaiey1FKjGR8xZru6gROHvntwI3QSA2I7T08Ys7g1by9_iBw-ekI&usqp=CAU"
),
"vitalik": User(
address: "0x3",
username: "Vitalik",
avatarUrl: "https://images.moneycontrol.com/static-mcnews/2021/05/vitalik-Buterin-ethereum.jpg?impolicy=website&width=1600&height=900"
),
"satoshi": User(address: "0x4", username: "Satoshi N"),
"alex": User(
address: "0x5",
username: "Alex",
avatarUrl: "https://www.cryptotimes.io/wp-content/uploads/2024/02/Matter_Labs_co-founder_and_CEO_Alex_Gluchowski_proposed_an_Ethereum_court_system.jpg.webp"
),
"abdel": User(
address: "0x6",
username: "Abdel.stark",
avatarUrl: "https://miro.medium.com/v2/resize:fit:1400/1*BTiOG6PF5d9ToTAZqlIjuw.jpeg"
),
]

struct HomeView: View {

@EnvironmentObject private var model: Model

@State private var showingAddFundsWebView = false

private var me: User {
get {
return users["me"]!
}
}

let history: History

init() {
self.history = History(transfers: [
Transfer(from: users["me"]!, to: users["sbf"]!, amount: USDCAmount(from: 1_604_568.230)!, timestamp: 1712199068),
Transfer(from: users["me"]!, to: users["apple"]!, amount: USDCAmount(from: 4_249.99)!, timestamp: 1711924459),
Transfer(from: users["vitalik"]!, to: users["me"]!, amount: USDCAmount(from: 70_000)!, timestamp: 1711878225),

Transfer(from: users["alex"]!, to: users["me"]!, amount: USDCAmount(from: 1_000_000)!, timestamp: 1711847328),
Transfer(from: users["me"]!, to: users["satoshi"]!, amount: USDCAmount(from: 32.57)!, timestamp: 1712000648),

Transfer(from: users["abdel"]!, to: users["me"]!, amount: USDCAmount(from: 0.01)!, timestamp: 1711828026),
])
}

var body: some View {
List {

Expand Down Expand Up @@ -174,33 +78,38 @@ struct HomeView: View {

// MARK: History

ForEach(self.history.groupedTransfers.keys.sorted(by: >), id: \.self) { day in
Section {
ForEach(0..<self.history.groupedTransfers[day]!.count, id: \.self) { index in
let transfer = self.history.groupedTransfers[day]![index]
let isFirst = index == 0;
let isLast = index == self.history.groupedTransfers[day]!.count - 1

TransferRow(transfer: transfer, me: self.me)
.padding(16)
.background(.background2)
.clipShape(
.rect(
topLeadingRadius: isFirst ? 16 : 0,
bottomLeadingRadius: isLast ? 16 : 0,
bottomTrailingRadius: isLast ? 16 : 0,
topTrailingRadius: isFirst ? 16 : 0
if let txHistory = self.model.txHistory {
ForEach(
txHistory.groupedTransactions.keys.sorted(by: >),
id: \.self
) { day in
Section {
ForEach(0..<txHistory.groupedTransactions[day]!.count, id: \.self) { index in
let transfer = txHistory.groupedTransactions[day]![index]
let isFirst = index == 0;
let isLast = index == txHistory.groupedTransactions[day]!.count - 1

TransferRow(transfer: transfer)
.padding(16)
.background(.background2)
.clipShape(
.rect(
topLeadingRadius: isFirst ? 16 : 0,
bottomLeadingRadius: isLast ? 16 : 0,
bottomTrailingRadius: isLast ? 16 : 0,
topTrailingRadius: isFirst ? 16 : 0
)
)
)
}
} header: {
Text(self.formatSectionHeader(for: day).uppercased())
.textTheme(.headlineSmall)
.listRowInsets(EdgeInsets(top: 32, leading: 8, bottom: 12, trailing: 0))
}
} header: {
Text(self.formatSectionHeader(for: day).uppercased())
.textTheme(.headlineSmall)
.listRowInsets(EdgeInsets(top: 32, leading: 8, bottom: 12, trailing: 0))
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.listRowSeparator(.hidden)
.listRowBackground(EmptyView())
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.listRowSeparator(.hidden)
.listRowBackground(EmptyView())
}
}
.onAppear {
Expand Down
27 changes: 9 additions & 18 deletions app/App/Navigation/Core/Home/TransferRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@
import SwiftUI

struct TransferRow: View {
@State private var transfer: Transfer
@State private var me: User
@State private var transfer: Transaction

init(transfer: Transfer, me: User) {
init(transfer: Transaction) {
self.transfer = transfer
self.me = me
}

var body: some View {
let isSpending = transfer.from.address == self.me.address
let displayedUser = isSpending ? transfer.to : transfer.from
let displayedUser = self.transfer.isSending ? transfer.to : transfer.from

let dateFormatter = DateFormatter()
let _ = dateFormatter.dateFormat = "HH:mm"
Expand All @@ -43,11 +40,11 @@ struct TransferRow: View {
)
.clipShape(Circle())
} else {
NoAvatar(name: displayedUser.username)
NoAvatar(name: displayedUser.address == nil ? "?" : displayedUser.nickname)
}

VStack(alignment: .leading) {
Text(displayedUser.username).textTheme(.bodyPrimary)
Text(displayedUser.nickname).textTheme(.bodyPrimary)

Spacer()

Expand All @@ -57,18 +54,12 @@ struct TransferRow: View {

Spacer()

Text("\(isSpending ? "-" : "")$\(transfer.amount.toFixed())")
.if(!isSpending) { view in
view
.fontWeight(.semibold)
}
Text("\(self.transfer.isSending ? "-" : "")$\(self.transfer.amount.toFixed())")
.fontWeight(self.transfer.isSending ? .regular : .semibold)
.textTheme(.bodySecondary)
.padding(EdgeInsets(top: 2, leading: 6, bottom: 2, trailing: 6))
.if(!isSpending) { view in
view
.background(.accent)
.clipShape(RoundedRectangle(cornerRadius: 4))
}
.background(self.transfer.isSending ? .transparent : .accent)
.clipShape(RoundedRectangle(cornerRadius: 4))
}.fixedSize(horizontal: false, vertical: true)
}
}
2 changes: 1 addition & 1 deletion app/App/Navigation/Core/Sending/ContactRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct ContactRow: View {

Spacer()

Text(/*self.contact.phone*/"+33612345678").textTheme(.subtitle)
Text(self.contact.phone).textTheme(.subtitle)
}
.padding(.vertical, 6)

Expand Down
4 changes: 2 additions & 2 deletions app/App/Navigation/Onboarding/CelebrationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ConfettiSwiftUI

struct CelebrationView: View {

@AppStorage("isOnboarded") var isOnboarded: Bool = false
@EnvironmentObject var model: Model

@State private var presentingNextView = false
@State private var confetti = 0
Expand Down Expand Up @@ -43,7 +43,7 @@ struct CelebrationView: View {
}

PrimaryButton("Start exploring") {
isOnboarded = true
self.model.isOnboarded = true
}
}
}
Expand Down
Loading

0 comments on commit 8553775

Please sign in to comment.