Skip to content
Merged
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
32 changes: 28 additions & 4 deletions Documentation/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
- *[Infura Websocket Provider](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#infura-websocket-provider)*
- [Connect to Infura endpoint](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#connect-to-infura-endpoint)
- [Connect to custom endpoint with API similar to Infura WSS endpoint](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#connect-to-custom-endpoint-with-api-similar-to-infura-wss-endpoint)
- [Create a filter in the node to notify when something happened](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#create-a-filter-in-the-node-to-notify-when-something-happened)
- [Set a filter in the node to notify when something happened](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#set-a-filter-in-the-node-to-notify-when-something-happened)
- [Get new pending transactions](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#get-new-pending-transactions)
- [Create a new subscription over particular events](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#create-a-new-subscription-over-particular-events)
- [Subscribe on new pending transactions](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-new-pending-transactions)
- [Subscribe on logs](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-logs)
- [Subscribe on new heads](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-new-heads)
- **[ENS](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#ens)**
- [Registry](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#registry)
- [Resolver](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#resolver)
Expand Down Expand Up @@ -410,18 +412,28 @@ socketProvider = InfuraWebsocketProvider.connectToInfuraSocket(.Mainnet, delegat
socketProvider = InfuraWebsocketProvider.connectToSocket("ws://your.endpoint", delegate: delegate)
```

#### Create a filter in the node to notify when something happened
#### Set a filter in the node to notify when something happened

To study possible filters read [Infura WSS filters documentation](https://infura.io/docs/ethereum/wss/introduction)

```swift
try! socketProvider.filter(method: <InfuraWebsocketMethod>, params: <[Encodable]?>)
// Getting logs
try! socketProvider.setFilterAndGetLogs(method: <InfuraWebsocketMethod>, params: <[Encodable]?>)
// Getting changes
try! socketProvider.setFilterAndGetChanges(method: <InfuraWebsocketMethod>, params: <[Encodable]?>)
```
Or you can provide parameters in more convenient way:
```swift
// Getting logs
try! socketProvider.setFilterAndGetLogs(method: <InfuraWebsocketMethod>, address: <EthereumAddress?>, fromBlock: <BlockNumber?>, toBlock: <BlockNumber?>, topics: <[String]?>)
// Getting changes
try! socketProvider.setFilterAndGetChanges(method: <InfuraWebsocketMethod>, address: <EthereumAddress?>, fromBlock: <BlockNumber?>, toBlock: <BlockNumber?>, topics: <[String]?>)
```

#### Get new pending transactions

```swift
try! socketProvider.filter(method: .newPendingTransactionFilter)
try! socketProvider.setFilterAndGetLogs(method: .newPendingTransactionFilter)
```

#### Create a new subscription over particular events
Expand All @@ -438,6 +450,18 @@ try! socketProvider.subscribe(params: <[Encodable]>)
try! socketProvider.subscribeOnNewPendingTransactions()
```

#### Subscribe on logs

```swift
try! socketProvider.subscribeOnLogs(addresses: <[EthereumAddress]?>, topics: <[String]?>)
```

#### Subscribe on new heads

```swift
try! socketProvider.subscribeOnNewHeads()
```

## ENS

You need ENS instance for future actions:
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@
- *[Infura Websocket Provider](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#infura-websocket-provider)*
- [Connect to Infura endpoint](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#connect-to-infura-endpoint)
- [Connect to custom endpoint with API similar to Infura WSS endpoint](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#connect-to-custom-endpoint-with-api-similar-to-infura-wss-endpoint)
- [Create a filter in the node to notify when something happened](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#create-a-filter-in-the-node-to-notify-when-something-happened)
- [Set a filter in the node to notify when something happened](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#set-a-filter-in-the-node-to-notify-when-something-happened)
- [Get new pending transactions](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#get-new-pending-transactions)
- [Create a new subscription over particular events](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#create-a-new-subscription-over-particular-events)
- [Subscribe on new pending transactions](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-new-pending-transactions)
- [Subscribe on logs](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-logs)
- [Subscribe on new heads](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#subscribe-on-new-heads)
- **[ENS](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#ens)**
- [Registry](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#registry)
- [Resolver](https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#resolver)
Expand Down
146 changes: 146 additions & 0 deletions Sources/web3swift/Convenience/Decodable+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//
// DecodingContainer+AnyCollection.swift
// AnyDecodable
//
// Created by levantAJ on 1/18/19.
// Copyright © 2019 levantAJ. All rights reserved.
//
import Foundation

struct AnyCodingKey: CodingKey {
var stringValue: String
var intValue: Int?

init?(stringValue: String) {
self.stringValue = stringValue
}

init?(intValue: Int) {
self.intValue = intValue
self.stringValue = String(intValue)
}
}

extension KeyedDecodingContainer {
/// Decodes a value of the given type for the given key.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated with.
/// - returns: A value of the requested type, if present for the given key
/// and convertible to the requested type.
/// - throws: `DecodingError.typeMismatch` if the encountered encoded value
/// is not convertible to the requested type.
/// - throws: `DecodingError.keyNotFound` if `self` does not have an entry
/// for the given key.
/// - throws: `DecodingError.valueNotFound` if `self` has a null entry for
/// the given key.
public func decode(_ type: [Any].Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [Any] {
var values = try nestedUnkeyedContainer(forKey: key)
return try values.decode(type)
}

/// Decodes a value of the given type for the given key.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated with.
/// - returns: A value of the requested type, if present for the given key
/// and convertible to the requested type.
/// - throws: `DecodingError.typeMismatch` if the encountered encoded value
/// is not convertible to the requested type.
/// - throws: `DecodingError.keyNotFound` if `self` does not have an entry
/// for the given key.
/// - throws: `DecodingError.valueNotFound` if `self` has a null entry for
/// the given key.
public func decode(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [String: Any] {
let values = try nestedContainer(keyedBy: AnyCodingKey.self, forKey: key)
return try values.decode(type)
}

/// Decodes a value of the given type for the given key, if present.
///
/// This method returns `nil` if the container does not have a value
/// associated with `key`, or if the value is null. The difference between
/// these states can be distinguished with a `contains(_:)` call.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated with.
/// - returns: A decoded value of the requested type, or `nil` if the
/// `Decoder` does not have an entry associated with the given key, or if
/// the value is a null value.
/// - throws: `DecodingError.typeMismatch` if the encountered encoded value
/// is not convertible to the requested type.
public func decodeIfPresent(_ type: [Any].Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [Any]? {
guard contains(key),
try decodeNil(forKey: key) == false else { return nil }
return try decode(type, forKey: key)
}

/// Decodes a value of the given type for the given key, if present.
///
/// This method returns `nil` if the container does not have a value
/// associated with `key`, or if the value is null. The difference between
/// these states can be distinguished with a `contains(_:)` call.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated with.
/// - returns: A decoded value of the requested type, or `nil` if the
/// `Decoder` does not have an entry associated with the given key, or if
/// the value is a null value.
/// - throws: `DecodingError.typeMismatch` if the encountered encoded value
/// is not convertible to the requested type.
public func decodeIfPresent(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [String: Any]? {
guard contains(key),
try decodeNil(forKey: key) == false else { return nil }
return try decode(type, forKey: key)
}
}

private extension KeyedDecodingContainer {
func decode(_ type: [String: Any].Type) throws -> [String: Any] {
var dictionary: [String: Any] = [:]
for key in allKeys {
if try decodeNil(forKey: key) {
dictionary[key.stringValue] = NSNull()
} else if let bool = try? decode(Bool.self, forKey: key) {
dictionary[key.stringValue] = bool
} else if let string = try? decode(String.self, forKey: key) {
dictionary[key.stringValue] = string
} else if let int = try? decode(Int.self, forKey: key) {
dictionary[key.stringValue] = int
} else if let double = try? decode(Double.self, forKey: key) {
dictionary[key.stringValue] = double
} else if let dict = try? decode([String: Any].self, forKey: key) {
dictionary[key.stringValue] = dict
} else if let array = try? decode([Any].self, forKey: key) {
dictionary[key.stringValue] = array
}
}
return dictionary
}
}

private extension UnkeyedDecodingContainer {
mutating func decode(_ type: [Any].Type) throws -> [Any] {
var elements: [Any] = []
while !isAtEnd {
if try decodeNil() {
elements.append(NSNull())
} else if let int = try? decode(Int.self) {
elements.append(int)
} else if let bool = try? decode(Bool.self) {
elements.append(bool)
} else if let double = try? decode(Double.self) {
elements.append(double)
} else if let string = try? decode(String.self) {
elements.append(string)
} else if let values = try? nestedContainer(keyedBy: AnyCodingKey.self),
let element = try? values.decode([String: Any].self) {
elements.append(element)
} else if var values = try? nestedUnkeyedContainer(),
let element = try? values.decode([Any].self) {
elements.append(element)
}
}
return elements
}
}
130 changes: 130 additions & 0 deletions Sources/web3swift/Convenience/Encodable+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//
// EncodingContainer+AnyCollection.swift
// AnyDecodable
//
// Created by ShopBack on 1/19/19.
// Copyright © 2019 levantAJ. All rights reserved.
//
import Foundation

extension KeyedEncodingContainer {
/// Encodes the given value for the given key.
///
/// - parameter value: The value to encode.
/// - parameter key: The key to associate the value with.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
public mutating func encode(_ value: [String: Any], forKey key: KeyedEncodingContainer<K>.Key) throws {
var container = nestedContainer(keyedBy: AnyCodingKey.self, forKey: key)
try container.encode(value)
}

/// Encodes the given value for the given key.
///
/// - parameter value: The value to encode.
/// - parameter key: The key to associate the value with.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
public mutating func encode(_ value: [Any], forKey key: KeyedEncodingContainer<K>.Key) throws {
var container = nestedUnkeyedContainer(forKey: key)
try container.encode(value)
}

/// Encodes the given value for the given key if it is not `nil`.
///
/// - parameter value: The value to encode.
/// - parameter key: The key to associate the value with.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
public mutating func encodeIfPresent(_ value: [String: Any]?, forKey key: KeyedEncodingContainer<K>.Key) throws {
if let value = value {
var container = nestedContainer(keyedBy: AnyCodingKey.self, forKey: key)
try container.encode(value)
} else {
try encodeNil(forKey: key)
}
}

/// Encodes the given value for the given key if it is not `nil`.
///
/// - parameter value: The value to encode.
/// - parameter key: The key to associate the value with.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
public mutating func encodeIfPresent(_ value: [Any]?, forKey key: KeyedEncodingContainer<K>.Key) throws {
if let value = value {
var container = nestedUnkeyedContainer(forKey: key)
try container.encode(value)
} else {
try encodeNil(forKey: key)
}
}
}

private extension KeyedEncodingContainer where K == AnyCodingKey {
mutating func encode(_ value: [String: Any]) throws {
for (k, v) in value {
let key = AnyCodingKey(stringValue: k)!
switch v {
case is NSNull:
try encodeNil(forKey: key)
case let string as String:
try encode(string, forKey: key)
case let int as Int:
try encode(int, forKey: key)
case let bool as Bool:
try encode(bool, forKey: key)
case let double as Double:
try encode(double, forKey: key)
case let dict as [String: Any]:
try encode(dict, forKey: key)
case let array as [Any]:
try encode(array, forKey: key)
default:
debugPrint("⚠️ Unsuported type!", v)
continue
}
}
}
}

private extension UnkeyedEncodingContainer {
/// Encodes the given value.
///
/// - parameter value: The value to encode.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
mutating func encode(_ value: [Any]) throws {
for v in value {
switch v {
case is NSNull:
try encodeNil()
case let string as String:
try encode(string)
case let int as Int:
try encode(int)
case let bool as Bool:
try encode(bool)
case let double as Double:
try encode(double)
case let dict as [String: Any]:
try encode(dict)
case let array as [Any]:
var values = nestedUnkeyedContainer()
try values.encode(array)
default:
debugPrint("⚠️ Unsuported type!", v)
}
}
}

/// Encodes the given value.
///
/// - parameter value: The value to encode.
/// - throws: `EncodingError.invalidValue` if the given value is invalid in
/// the current context for this format.
mutating func encode(_ value: [String: Any]) throws {
var container = self.nestedContainer(keyedBy: AnyCodingKey.self)
try container.encode(value)
}
}
2 changes: 1 addition & 1 deletion Sources/web3swift/Web3/Web3+Eth+Websocket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension web3.Eth {

public func getLatestPendingTransactions(forDelegate delegate: Web3SocketDelegate) throws {
let provider = try getWebsocketProvider(forDelegate: delegate)
try provider.filter(method: .newPendingTransactionFilter)
try provider.setFilterAndGetChanges(method: .newPendingTransactionFilter)
}

public func subscribeOnPendingTransactions(forDelegate delegate: Web3SocketDelegate) throws {
Expand Down
Loading