diff --git a/Sources/Core/Web3/Web3.swift b/Sources/Core/Web3/Web3.swift index eee01d56..02c83d87 100644 --- a/Sources/Core/Web3/Web3.swift +++ b/Sources/Core/Web3/Web3.swift @@ -460,6 +460,31 @@ public struct Web3 { properties.provider.send(request: req, response: response) } + public func getLogs( + addresses: [EthereumAddress]?, + topics: [[EthereumData]]?, + fromBlock: EthereumQuantityTag, + toBlock: EthereumQuantityTag, + response: @escaping Web3ResponseCompletion<[EthereumLogObject]> + ) { + struct LogsParam: Codable { + let address: [EthereumAddress]? + let topics: [[EthereumData]]? + + let fromBlock: EthereumQuantityTag + let toBlock: EthereumQuantityTag + } + + let req = RPCRequest<[LogsParam]>( + id: properties.rpcId, + jsonrpc: Web3.jsonrpc, + method: "eth_getLogs", + params: [LogsParam(address: addresses, topics: topics, fromBlock: fromBlock, toBlock: toBlock)] + ) + + properties.provider.send(request: req, response: response) + } + // MARK: - Events public func subscribeToNewHeads( diff --git a/Sources/PromiseKit/Web3+PromiseKit.swift b/Sources/PromiseKit/Web3+PromiseKit.swift index 6f1a5384..d91b2106 100644 --- a/Sources/PromiseKit/Web3+PromiseKit.swift +++ b/Sources/PromiseKit/Web3+PromiseKit.swift @@ -277,6 +277,19 @@ public extension Web3.Eth { } } } + + func getLogs( + addresses: [EthereumAddress]?, + topics: [[EthereumData]]?, + fromBlock: EthereumQuantityTag, + toBlock: EthereumQuantityTag + ) -> Promise<[EthereumLogObject]> { + return Promise { seal in + self.getLogs(addresses: addresses, topics: topics, fromBlock: fromBlock, toBlock: toBlock) { response in + response.sealPromise(seal: seal) + } + } + } } fileprivate extension Web3Response { diff --git a/Tests/Web3Tests/Web3Tests/Web3HttpTests.swift b/Tests/Web3Tests/Web3Tests/Web3HttpTests.swift index ed684db3..10e4e156 100644 --- a/Tests/Web3Tests/Web3Tests/Web3HttpTests.swift +++ b/Tests/Web3Tests/Web3Tests/Web3HttpTests.swift @@ -548,6 +548,64 @@ class Web3HttpTests: QuickSpec { } } } + + context("eth get logs") { + // HTTP + waitUntil(timeout: .seconds(2)) { done in + firstly { + try web3.eth.getLogs( + addresses: [EthereumAddress(hex: "0xdAC17F958D2ee523a2206206994597C13D831ec7", eip55: true)], + topics: [[EthereumData(ethereumValue: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")]], + fromBlock: .block(BigUInt(15884445)), + toBlock: .block(BigUInt(15884445)) + ) + }.done { logs in + for log in logs { + it("should only include logs with this topic") { + expect(log.topics[0].hex()) == "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + } + } + it("should be the expected number of logs") { + expect(logs.count) == 22 + } + done() + }.catch { error in + it("should not fail") { + expect(false) == true + } + done() + } + } + + // WebSocket + waitUntil(timeout: .seconds(2)) { done in + try! web3Ws.eth.getLogs( + addresses: [EthereumAddress(hex: "0xdAC17F958D2ee523a2206206994597C13D831ec7", eip55: true)], + topics: [[EthereumData(ethereumValue: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")]], + fromBlock: .block(BigUInt(15884445)), + toBlock: .block(BigUInt(15884445)) + ) { response in + it("should be status ok") { + expect(response.status.isSuccess) == true + } + it("should not be nil") { + expect(response.result).toNot(beNil()) + } + + for log in response.result ?? [] { + it("should only include logs with this topic") { + expect(log.topics[0].hex()) == "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + } + } + it("should be the expected number of logs") { + expect(response.result?.count) == 22 + } + + // Tests done + done() + } + } + } } } }