Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Fix #5723: Solana transaction support in Transaction Parser (#5737)
Browse files Browse the repository at this point in the history
* Support Solana transaction types in `TransactionParser`.

* Add Solana transaction unit tests

* Add `fromFiat` & `minBuyAmountFiat` to `EthSwapDetails`.

* Add gasFee computed property on `ParsedTransaction`. Fix `AssetDetailStore` swap transactions by fetching user visible assets and all tokens.
  • Loading branch information
StephenHeaps committed Jul 26, 2022
1 parent d1556c9 commit 526cfcf
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 68 deletions.
13 changes: 11 additions & 2 deletions BraveWallet/Crypto/Stores/AccountActivityStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AccountActivityStore: ObservableObject {
private let assetRatioService: BraveWalletAssetRatioService
private let txService: BraveWalletTxService
private let blockchainRegistry: BraveWalletBlockchainRegistry
private let solTxManagerProxy: BraveWalletSolanaTxManagerProxy

init(
account: BraveWallet.AccountInfo,
Expand All @@ -34,7 +35,8 @@ class AccountActivityStore: ObservableObject {
rpcService: BraveWalletJsonRpcService,
assetRatioService: BraveWalletAssetRatioService,
txService: BraveWalletTxService,
blockchainRegistry: BraveWalletBlockchainRegistry
blockchainRegistry: BraveWalletBlockchainRegistry,
solTxManagerProxy: BraveWalletSolanaTxManagerProxy
) {
self.account = account
self.keyringService = keyringService
Expand All @@ -43,6 +45,7 @@ class AccountActivityStore: ObservableObject {
self.assetRatioService = assetRatioService
self.txService = txService
self.blockchainRegistry = blockchainRegistry
self.solTxManagerProxy = solTxManagerProxy

self.keyringService.add(self)
self.rpcService.add(self)
Expand Down Expand Up @@ -124,7 +127,12 @@ class AccountActivityStore: ObservableObject {
allTokens: [BraveWallet.BlockchainToken],
assetRatios: [String: Double]
) async -> [TransactionSummary] {
await txService.allTransactionInfo(.eth, from: account.address)
let transactions = await txService.allTransactionInfo(account.coin, from: account.address)
var solEstimatedTxFees: [String: UInt64] = [:]
if account.coin == .sol {
solEstimatedTxFees = await solTxManagerProxy.estimatedTxFees(for: transactions.map(\.id))
}
return transactions
.sorted(by: { $0.createdTime > $1.createdTime })
.map { transaction in
TransactionParser.transactionSummary(
Expand All @@ -134,6 +142,7 @@ class AccountActivityStore: ObservableObject {
visibleTokens: userVisibleTokens,
allTokens: allTokens,
assetRatios: assetRatios,
solEstimatedTxFee: solEstimatedTxFees[transaction.id],
currencyFormatter: currencyFormatter
)
}
Expand Down
34 changes: 28 additions & 6 deletions BraveWallet/Crypto/Stores/AssetDetailStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class AssetDetailStore: ObservableObject {
private let rpcService: BraveWalletJsonRpcService
private let txService: BraveWalletTxService
private let blockchainRegistry: BraveWalletBlockchainRegistry
private let solTxManagerProxy: BraveWalletSolanaTxManagerProxy

let token: BraveWallet.BlockchainToken

Expand All @@ -65,6 +66,7 @@ class AssetDetailStore: ObservableObject {
walletService: BraveWalletBraveWalletService,
txService: BraveWalletTxService,
blockchainRegistry: BraveWalletBlockchainRegistry,
solTxManagerProxy: BraveWalletSolanaTxManagerProxy,
token: BraveWallet.BlockchainToken
) {
self.assetRatioService = assetRatioService
Expand All @@ -73,6 +75,7 @@ class AssetDetailStore: ObservableObject {
self.walletService = walletService
self.txService = txService
self.blockchainRegistry = blockchainRegistry
self.solTxManagerProxy = solTxManagerProxy
self.token = token

self.keyringService.add(self)
Expand Down Expand Up @@ -164,25 +167,43 @@ class AssetDetailStore: ObservableObject {
keyring: BraveWallet.KeyringInfo,
assetRatios: [String: Double]
) async -> [TransactionSummary] {
let network = await rpcService.network(.eth)
let coin = token.coin
let network = await rpcService.network(coin)
let userVisibleAssets = await walletService.userAssets(network.chainId, coin: coin)
let allTokens = await blockchainRegistry.allTokens(network.chainId, coin: coin)
let allTransactions = await withTaskGroup(of: [BraveWallet.TransactionInfo].self) { group -> [BraveWallet.TransactionInfo] in
for account in keyring.accountInfos {
group.addTask {
await self.txService.allTransactionInfo(.eth, from: account.address)
await self.txService.allTransactionInfo(coin, from: account.address)
}
}
return await group.reduce([BraveWallet.TransactionInfo](), { partialResult, prior in
return partialResult + prior
})
}
var solEstimatedTxFees: [String: UInt64] = [:]
if token.coin == .sol {
solEstimatedTxFees = await solTxManagerProxy.estimatedTxFees(for: allTransactions.map(\.id))
}
return allTransactions
.filter { tx in
switch tx.txType {
case .erc20Approve, .erc20Transfer:
let toAddress = tx.txDataUnion.ethTxData1559?.baseData.to
return toAddress == self.token.contractAddress
guard let tokenContractAddress = tx.txDataUnion.ethTxData1559?.baseData.to else {
return false
}
return tokenContractAddress.caseInsensitiveCompare(self.token.contractAddress) == .orderedSame
case .ethSend, .ethSwap, .other, .erc721TransferFrom, .erc721SafeTransferFrom:
return network.symbol.caseInsensitiveCompare(self.token.symbol) == .orderedSame
case .solanaSystemTransfer:
return network.symbol.caseInsensitiveCompare(self.token.symbol) == .orderedSame
case .solanaSplTokenTransfer, .solanaSplTokenTransferWithAssociatedTokenAccountCreation:
guard let tokenContractAddress = tx.txDataUnion.solanaTxData?.splTokenMintAddress else {
return false
}
return tokenContractAddress.caseInsensitiveCompare(self.token.contractAddress) == .orderedSame
case .erc1155SafeTransferFrom, .solanaDappSignTransaction, .solanaDappSignAndSendTransaction:
return false
@unknown default:
return false
}
Expand All @@ -193,9 +214,10 @@ class AssetDetailStore: ObservableObject {
from: transaction,
network: network,
accountInfos: keyring.accountInfos,
visibleTokens: [token],
allTokens: [],
visibleTokens: userVisibleAssets,
allTokens: allTokens,
assetRatios: assetRatios,
solEstimatedTxFee: solEstimatedTxFees[transaction.id],
currencyFormatter: self.currencyFormatter
)
}
Expand Down
4 changes: 3 additions & 1 deletion BraveWallet/Crypto/Stores/CryptoStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public class CryptoStore: ObservableObject {
walletService: walletService,
txService: txService,
blockchainRegistry: blockchainRegistry,
solTxManagerProxy: solTxManagerProxy,
token: token
)
assetDetailStore = store
Expand All @@ -196,7 +197,8 @@ public class CryptoStore: ObservableObject {
rpcService: rpcService,
assetRatioService: assetRatioService,
txService: txService,
blockchainRegistry: blockchainRegistry
blockchainRegistry: blockchainRegistry,
solTxManagerProxy: solTxManagerProxy
)
accountActivityStore = store
return store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extension TransactionParser {
visibleTokens: [BraveWallet.BlockchainToken],
allTokens: [BraveWallet.BlockchainToken],
assetRatios: [String: Double],
solEstimatedTxFee: UInt64?,
currencyFormatter: NumberFormatter
) -> TransactionSummary {
guard let parsedTransaction = parseTransaction(
Expand All @@ -53,6 +54,7 @@ extension TransactionParser {
visibleTokens: visibleTokens,
allTokens: allTokens,
assetRatios: assetRatios,
solEstimatedTxFee: solEstimatedTxFee,
currencyFormatter: currencyFormatter,
decimalFormatStyle: .balance // use 4 digit precision for summary
) else {
Expand All @@ -72,17 +74,17 @@ extension TransactionParser {
}
switch parsedTransaction.details {
case let .ethSend(details):
let title = String.localizedStringWithFormat(Strings.Wallet.transactionSendTitle, details.fromAmount, details.fromTokenSymbol, details.fromFiat ?? "")
let title = String.localizedStringWithFormat(Strings.Wallet.transactionSendTitle, details.fromAmount, details.fromToken.symbol, details.fromFiat ?? "")
return .init(
txInfo: transaction,
namedFromAddress: parsedTransaction.namedFromAddress,
namedToAddress: parsedTransaction.namedToAddress,
title: title,
gasFee: details.gasFee,
networkSymbol: details.fromTokenSymbol
networkSymbol: parsedTransaction.networkSymbol
)
case let .erc20Transfer(details):
let title = String.localizedStringWithFormat(Strings.Wallet.transactionSendTitle, details.fromAmount, details.fromTokenSymbol, details.fromFiat ?? "")
let title = String.localizedStringWithFormat(Strings.Wallet.transactionSendTitle, details.fromAmount, details.fromToken.symbol, details.fromFiat ?? "")
return .init(
txInfo: transaction,
namedFromAddress: parsedTransaction.namedFromAddress,
Expand Down Expand Up @@ -135,6 +137,16 @@ extension TransactionParser {
gasFee: nil,
networkSymbol: parsedTransaction.networkSymbol
)
case let .solSystemTransfer(details), let .solSplTokenTransfer(details):
let title = String.localizedStringWithFormat(Strings.Wallet.transactionSendTitle, details.fromAmount, details.fromToken.symbol, details.fromFiat ?? "")
return .init(
txInfo: transaction,
namedFromAddress: parsedTransaction.namedFromAddress,
namedToAddress: parsedTransaction.namedToAddress,
title: title,
gasFee: details.gasFee,
networkSymbol: parsedTransaction.networkSymbol
)
}
}
}
Loading

0 comments on commit 526cfcf

Please sign in to comment.