Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions Sources/SafariWalletCore/Client/Etherscan/EtherscanClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ extension EtherscanClient {
/// - address: in hex string.
/// - Returns: Returns contract details based on the contract request.
public func getContractDetails(forAddress address: String) async throws -> Etherscan.ContractResponse {
let endpoint = try makeEndpointFrom(address: address)
let endpoint = try makeContractDetailEndpointFrom(address: address)
return try await urlSession.load(endpoint)
}

private func makeEndpointFrom(
private func makeContractDetailEndpointFrom(
address: String
) throws -> Endpoint<Etherscan.ContractResponse> {
guard let url = URL(string: "https://api.etherscan.io/api/") else { throw InvalidRequestError() }
Expand All @@ -49,3 +49,44 @@ extension EtherscanClient {
)
}
}

extension EtherscanClient {

/// Returns an array transactions based on the address.
/// - SeeAlso: [Etherscan documentation](https://docs.etherscan.io/api-endpoints/accounts#get-a-list-of-normal-transactions-by-address)
/// - Parameters:
/// - address: in hex string.
/// - page: page number. optional
/// - offset: number of records to be displayed per page. optional
/// - Returns: Returns an array transactions based on the address.
public func getTransactions(address: String,
page: Int,
offset: Int) async throws -> Etherscan.TransactionsResponse {
let endpoint = try makeTransactionsEndpointFrom(address: address, page: page, offset: offset)
return try await urlSession.load(endpoint)
}

private func makeTransactionsEndpointFrom(
address: String,
page: Int,
offset: Int
) throws -> Endpoint<Etherscan.TransactionsResponse> {
guard let url = URL(string: "https://api.etherscan.io/api/") else { throw InvalidRequestError() }
let query = [
"apikey": apiKey,
"module": "account",
"action": "txlist",
"address": address,
"startblock": "0",
"endblock": "99999999",
"page": String(page),
"offset": String(offset),
"sort": "desc",
]
return Endpoint(
json: .get,
url: url,
query: query
)
}
}
36 changes: 36 additions & 0 deletions Sources/SafariWalletCore/Client/Etherscan/EtherscanModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ public enum Etherscan {
public let implementation: String
public let swarmSource: String
}

public struct TransactionsResponse: Codable {
public let status, message: String
public let result: [Transaction]
}

public struct Transaction {
public let blockNumber: String
public let timeStamp: String
public let hash: String
public let nonce: String
public let blockHash: String
public let transactionIndex: String
public let from: String
public let to: String
public let value: String
public let gas: String
public let gasPrice: String
public let isError: String
public let txreceiptStatus: String
public let input: String
public let contractAddress: String
public let cumulativeGasUsed: String
public let gasUsed: String
public let confirmations: String
}

}

extension Etherscan.ContractDetail: Codable {
Expand All @@ -50,3 +77,12 @@ extension Etherscan.ContractDetail: Codable {
case swarmSource = "SwarmSource"
}
}

extension Etherscan.Transaction: Codable {

enum CodingKeys: String, CodingKey {
case blockNumber, timeStamp, hash, nonce, blockHash, transactionIndex, from, to, value, gas, gasPrice, isError
case txreceiptStatus = "txreceipt_status"
case input, contractAddress, cumulativeGasUsed, gasUsed, confirmations
}
}