Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ extension TransactionParticipantViewModel {

let address = transactionViewModel.participant
let chain = transactionViewModel.transaction.transaction.assetId.chain
let addressName = transactionViewModel.getAddressName(address: address)
let account = SimpleAccount(
name: transactionViewModel.getAddressName(address: address),
name: addressName?.name,
chain: chain,
address: address,
assetImage: nil
assetImage: nil,
addressType: addressName?.type
)

return .participant(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Components
import Localization
import Primitives
import PrimitivesComponents
import Style

struct ConfirmRecipientViewModel {
private let model: TransferDataViewModel
Expand All @@ -29,7 +30,8 @@ extension ConfirmRecipientViewModel: ItemModelProvidable {
name: addressName?.name ?? model.recipient.name,
chain: model.chain,
address: model.recipient.address,
assetImage: .none
assetImage: addressNameImage,
addressType: addressName?.type
),
mode: .nameOrAddress,
addressLink: addressLink
Expand All @@ -41,6 +43,13 @@ extension ConfirmRecipientViewModel: ItemModelProvidable {
// MARK: - Private

extension ConfirmRecipientViewModel {
private var addressNameImage: AssetImage? {
switch addressName?.type {
case .contact: .image(Images.System.person)
case .address, .contract, .validator, .none: nil
}
}

private var recipientTitle: String {
switch model.type {
case .swap: Localized.Common.provider
Expand Down
2 changes: 1 addition & 1 deletion Packages/ChainServices/StakeService/StakeService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ extension StakeService {
}
try store.updateValidators(updateValidators)

let addressNames = updateValidators.map { AddressName(chain: $0.chain, address: $0.id, name: $0.name)}
let addressNames = updateValidators.map { AddressName(chain: $0.chain, address: $0.id, name: $0.name, type: .validator) }
try addressStore.addAddressNames(addressNames)
}

Expand Down
2 changes: 1 addition & 1 deletion Packages/Components/Sources/AssetImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public struct AssetImage: Sendable, Equatable {
public let chainPlaceholder: Image?

public init(
type: String? = .none,
type: String? = .none,
imageURL: URL? = .none,
placeholder: Image? = .none,
chainPlaceholder: Image? = .none
Expand Down
27 changes: 24 additions & 3 deletions Packages/Components/Sources/AssetImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ public struct AssetImageView: View {
}
private let assetImage: AssetImage
private let overlayPadding: CGFloat = 2
private let cornerRadius: CGFloat
private var cornerRadius: CGFloat { style?.cornerRadius ?? size / 2 }
private let style: Style?

public init(
assetImage: AssetImage,
size: CGFloat = .image.asset,
cornerRadius: CGFloat? = nil
style: Style? = nil
) {
self.assetImage = assetImage
self.size = max(1, size)
self.cornerRadius = cornerRadius ?? size / 2
self.style = style
}

private var overlayOffset: CGFloat { (size / 2) - (overlaySize / 2) }
Expand All @@ -42,6 +43,9 @@ public struct AssetImageView: View {
)
.frame(width: size, height: size)
.cornerRadius(cornerRadius)
.ifLet(style?.foregroundColor) { view, color in
view.foregroundStyle(color)
}
.overlay(overlayBadge)
}

Expand Down Expand Up @@ -100,6 +104,23 @@ public struct AssetImageView: View {
}
}

// MARK: - Style

extension AssetImageView {
public struct Style: Sendable, Equatable {
public let foregroundColor: Color?
public let cornerRadius: CGFloat?

public init(
foregroundColor: Color? = nil,
cornerRadius: CGFloat? = nil
) {
self.foregroundColor = foregroundColor
self.cornerRadius = cornerRadius
}
}
}

#Preview {
Group {
AssetImageView(
Expand Down
7 changes: 5 additions & 2 deletions Packages/Components/Sources/Lists/ListItemImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ public struct ListItemImageView: View {
public let subtitle: String?
public let subtitleStyle: TextStyle
public let assetImage: AssetImage?
public let assetImageStyle: AssetImageView.Style?
public let imageSize: CGFloat
public let infoAction: (() -> Void)?

public init(
title: String?,
subtitle: String?,
subtitleStyle: TextStyle = .calloutSecondary,
assetImage: AssetImage? = nil,
assetImageStyle: AssetImageView.Style? = nil,
imageSize: CGFloat = .list.image,
infoAction: (() -> Void)? = nil
) {
self.title = title
self.subtitle = subtitle
self.subtitleStyle = subtitleStyle
self.assetImage = assetImage
self.assetImageStyle = assetImageStyle
self.imageSize = imageSize
self.infoAction = infoAction
}
Expand All @@ -48,7 +51,7 @@ public struct ListItemImageView: View {
infoAction: infoAction
)
if let assetImage {
AssetImageView(assetImage: assetImage, size: imageSize)
AssetImageView(assetImage: assetImage, size: imageSize, style: assetImageStyle)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Packages/Components/Sources/Lists/ListItemToggleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public struct ListItemToggleView: View {
AssetImageView(
assetImage: imageStyle.assetImage,
size: imageStyle.imageSize,
cornerRadius: imageStyle.cornerRadius
style: .init(cornerRadius: imageStyle.cornerRadius)
)
}
Text(title.text)
Expand Down
2 changes: 1 addition & 1 deletion Packages/Components/Sources/Lists/ListItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public struct ListItemView: View {
AssetImageView(
assetImage: imageStyle.assetImage,
size: imageStyle.imageSize,
cornerRadius: imageStyle.cornerRadius
style: .init(cornerRadius: imageStyle.cornerRadius)
)
}
HStack {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public struct ContactService: Sendable {
extension ContactService {
private func syncAddressNames(contact: Contact, addresses: [ContactAddress]) throws {
let addressNames = addresses.map {
AddressName(chain: $0.chain, address: $0.address, name: contact.name)
AddressName(chain: $0.chain, address: $0.address, name: contact.name, type: .contact)
}
try addressStore.addAddressNames(addressNames)
}
Expand Down
4 changes: 3 additions & 1 deletion Packages/Primitives/Sources/AddressName.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ public struct AddressName: Codable, Equatable, Hashable, Sendable {
public let chain: Chain
public let address: String
public let name: String
public let type: AddressType?

public init(chain: Chain, address: String, name: String) {
public init(chain: Chain, address: String, name: String, type: AddressType?) {
self.chain = chain
self.address = address
self.name = name
self.type = type
}
}
1 change: 1 addition & 0 deletions Packages/Primitives/Sources/Scan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum AddressType: String, Codable, Equatable, Sendable {
case address
case contract
case validator
case contact
}

public struct ScanAddress: Codable, Equatable, Sendable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ public extension AddressName {
static func mock(
chain: Chain = .arbitrum,
address: String = "0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7",
name: String = "Hyperliquid"
name: String = "Hyperliquid",
type: AddressType? = nil
) -> AddressName {
AddressName(
chain: chain,
address: address,
name: name
name: name,
type: type
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public struct AddressListItemView: View {
ListItemImageView(
title: model.title,
subtitle: model.subtitle,
assetImage: model.assetImage
assetImage: model.assetImage,
assetImageStyle: model.assetImageStyle,
imageSize: model.assetImageSize
)
.contextMenu(
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ private struct ExplorerMock: ExplorerLinkFetchable {
feePrice: nil,
assets: [],
prices: [],
fromAddress: AddressName(chain: .smartChain, address: "0x92abCE21234D71EC443E679f3a1feAFD3Fc830fB", name: "test1"),
toAddress: AddressName(chain: .smartChain, address: "0x8d7460E51bCf4eD26877cb77E56f3ce7E9f5EB8F", name: "test2")
fromAddress: AddressName(chain: .smartChain, address: "0x92abCE21234D71EC443E679f3a1feAFD3Fc830fB", name: "test1", type: nil),
toAddress: AddressName(chain: .smartChain, address: "0x8d7460E51bCf4eD26877cb77E56f3ce7E9f5EB8F", name: "test2", type: nil)
)

let transactionVMMock = TransactionViewModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ public struct SimpleAccount {
public let chain: Chain
public let address: String
public let assetImage: AssetImage?
public let addressType: AddressType?

public init(name: String?, chain: Chain, address: String, assetImage: AssetImage?) {
public init(name: String?, chain: Chain, address: String, assetImage: AssetImage?, addressType: AddressType? = nil) {
self.name = name
self.chain = chain
self.address = address
self.assetImage = assetImage
self.addressType = addressType
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Formatters
import Style

public struct AddressListItemViewModel {

public enum Mode {
case auto(addressStyle: AddressFormatter.Style)
case address(addressStyle: AddressFormatter.Style)
Expand Down Expand Up @@ -44,6 +44,20 @@ public struct AddressListItemViewModel {
account.assetImage
}

public var assetImageStyle: AssetImageView.Style? {
switch account.addressType {
case .contact: AssetImageView.Style(foregroundColor: Colors.secondaryText, cornerRadius: 0)
case .address, .contract, .validator, .none: nil
}
}

public var assetImageSize: CGFloat {
switch account.addressType {
case .contact: .list.accessory
case .address, .contract, .validator, .none: .list.image
}
}

public var addressExplorerText: String {
Localized.Transaction.viewOn(addressLink.name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,13 @@ public struct TransactionViewModel: Sendable {
private var addressLink: BlockExplorerLink { explorerService.addressUrl(chain: assetId.chain, address: participant) }
private var assetId: AssetId { transaction.transaction.assetId }

public func getAddressName(address: String) -> String? {
public func getAddressName(address: String) -> AddressName? {
if address == transaction.transaction.from {
return transaction.fromAddress?.name
return transaction.fromAddress
}

if address == transaction.transaction.to {
return transaction.toAddress?.name
return transaction.toAddress
}

return .none
Expand All @@ -351,7 +351,7 @@ public struct TransactionViewModel: Sendable {
// MARK: - Private methods

private func getDisplayName(address: String, chain: Chain) -> String {
if let name = getAddressName(address: address) {
if let name = getAddressName(address: address)?.name {
return name
}
return AddressFormatter(address: address, chain: chain).value()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extension AddressListItemViewModel {
title: String = "Recipient",
account: SimpleAccount = SimpleAccount(name: "Alice", chain: .ethereum, address: "0x123456789101112", assetImage: nil),
mode: Mode = .auto(addressStyle: .short),
addressLink: BlockExplorerLink = BlockExplorerLink(name: "Mock", link: "https://mock.com")
addressLink: BlockExplorerLink = .init(name: "Mock", link: "https://mock.com")
) -> AddressListItemViewModel {
AddressListItemViewModel(
title: title,
Expand Down
6 changes: 6 additions & 0 deletions Packages/Store/Sources/Migrations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,12 @@ struct Migrations {
try? ContactAddressRecord.create(db: db)
}

migrator.registerMigration("Add type to \(AddressRecord.databaseTableName)") { db in
try? db.alter(table: AddressRecord.databaseTableName) {
$0.add(column: AddressRecord.Columns.type.name, .text)
}
}

try migrator.migrate(dbQueue)
}
}
16 changes: 11 additions & 5 deletions Packages/Store/Sources/Models/AddressRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,29 @@ import Primitives

struct AddressRecord: Codable, FetchableRecord, PersistableRecord, Sendable {
static let databaseTableName = "addresses"

enum Columns {
static let chain = Column("chain")
static let address = Column("address")
static let name = Column("name")
static let type = Column("type")
}

let chain: Chain
let address: String
let name: String

let type: AddressType?

init(
chain: Chain,
address: String,
name: String
name: String,
type: AddressType?
) {
self.chain = chain
self.address = address
self.name = name
self.type = type
}
}

Expand All @@ -38,6 +42,7 @@ extension AddressRecord: CreateTable {
.notNull()
$0.column(Columns.name.name, .text)
.notNull()
$0.column(Columns.type.name, .text)
$0.primaryKey([Columns.chain.name, Columns.address.name])
}
}
Expand All @@ -48,7 +53,8 @@ extension AddressRecord {
AddressName(
chain: chain,
address: address,
name: name
name: name,
type: type
)
}
}
3 changes: 2 additions & 1 deletion Packages/Store/Sources/Stores/AddressStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public struct AddressStore: Sendable {
try AddressRecord(
chain: addressName.chain,
address: addressName.address,
name: addressName.name
name: addressName.name,
type: addressName.type
).save(db, onConflict: .replace)
}
}
Expand Down
Loading