diff --git a/Sources/SafariWalletCore/Client/Etherscan/EtherscanClient.swift b/Sources/SafariWalletCore/Client/Etherscan/EtherscanClient.swift index 55622fb..720e151 100644 --- a/Sources/SafariWalletCore/Client/Etherscan/EtherscanClient.swift +++ b/Sources/SafariWalletCore/Client/Etherscan/EtherscanClient.swift @@ -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 { guard let url = URL(string: "https://api.etherscan.io/api/") else { throw InvalidRequestError() } @@ -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 { + 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 + ) + } +} diff --git a/Sources/SafariWalletCore/Client/Etherscan/EtherscanModels.swift b/Sources/SafariWalletCore/Client/Etherscan/EtherscanModels.swift index 07f593d..9806a19 100644 --- a/Sources/SafariWalletCore/Client/Etherscan/EtherscanModels.swift +++ b/Sources/SafariWalletCore/Client/Etherscan/EtherscanModels.swift @@ -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 { @@ -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 + } +}