Skip to content

Commit dbbcba7

Browse files
authored
feature: add ability to specify read-only rpc map (#185)
* feat: add readOnlyRpcMap option * update unit tests * Update README with read only rpc documentation
1 parent 4bdd6d9 commit dbbcba7

11 files changed

+181
-129
lines changed

Example/Tests/EthereumConnectTests.swift

+18-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class EthereumConnectTests: XCTestCase {
1414
var trackEventMock: ((Event, [String: Any]) -> Void)!
1515
var ethereum: Ethereum!
1616
var store: SecureStore!
17+
var mockNetwork: MockNetwork!
18+
var mockReadOnlyRPCProvider: MockReadOnlyRPCProvider!
1719

1820
override func setUp() {
1921
super.setUp()
@@ -23,10 +25,13 @@ class EthereumConnectTests: XCTestCase {
2325
trackEventMock = { _, _ in }
2426
EthereumWrapper.shared.ethereum = nil
2527
SDKWrapper.shared.sdk = nil
28+
mockNetwork = MockNetwork()
29+
mockReadOnlyRPCProvider = MockReadOnlyRPCProvider(infuraAPIKey: "12345", readonlyRPCMap: [:], network: mockNetwork)
2630
ethereum = Ethereum.shared(
2731
transport: .socket,
2832
store: store,
29-
commClientFactory: commClientFactory,
33+
commClientFactory: commClientFactory,
34+
readOnlyRPCProvider: mockReadOnlyRPCProvider,
3035
trackEvent: trackEventMock)
3136
}
3237

@@ -43,8 +48,18 @@ class EthereumConnectTests: XCTestCase {
4348

4449
// Test the singleton instance creation
4550
func testSingletonInstance() {
46-
let instance1 = Ethereum.shared(transport: .socket, store: store, commClientFactory: commClientFactory, trackEvent: trackEventMock)
47-
let instance2 = Ethereum.shared(transport: .socket, store: store, commClientFactory: commClientFactory, trackEvent: trackEventMock)
51+
let instance1 = Ethereum.shared(
52+
transport: .socket,
53+
store: store,
54+
commClientFactory: commClientFactory,
55+
readOnlyRPCProvider: mockReadOnlyRPCProvider,
56+
trackEvent: trackEventMock)
57+
let instance2 = Ethereum.shared(
58+
transport: .socket,
59+
store: store,
60+
commClientFactory: commClientFactory,
61+
readOnlyRPCProvider: mockReadOnlyRPCProvider,
62+
trackEvent: trackEventMock)
4863
XCTAssert(instance1 === instance2)
4964
}
5065

Example/Tests/EthereumConvenienceMethodsTests.swift

+24-19
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class EthereumConvenienceMethodsTests: XCTestCase {
1313
var mockEthereumDelegate: MockEthereumDelegate!
1414
var trackEventMock: ((Event, [String: Any]) -> Void)!
1515
var ethereum: Ethereum!
16-
var mockInfuraProvider: MockInfuraProvider!
16+
var mockReadOnlyRPCProvider: MockReadOnlyRPCProvider!
1717
let infuraApiKey = "testApiKey"
1818
var store: SecureStore!
1919
var trackedEvents: [(Event, [String: Any])] = []
@@ -27,15 +27,18 @@ class EthereumConvenienceMethodsTests: XCTestCase {
2727

2828
store = Keychain(service: "com.example.ethconvenience")
2929
mockNetwork = MockNetwork()
30-
mockInfuraProvider = MockInfuraProvider(infuraAPIKey: infuraApiKey, network: mockNetwork)
30+
mockReadOnlyRPCProvider = MockReadOnlyRPCProvider(
31+
infuraAPIKey: infuraApiKey,
32+
readonlyRPCMap: [:],
33+
network: mockNetwork)
3134
mockEthereumDelegate = MockEthereumDelegate()
3235
EthereumWrapper.shared.ethereum = nil
3336
SDKWrapper.shared.sdk = nil
3437
ethereum = Ethereum.shared(
3538
transport: .socket,
3639
store: store,
3740
commClientFactory: mockCommClientFactory,
38-
infuraProvider: mockInfuraProvider,
41+
readOnlyRPCProvider: mockReadOnlyRPCProvider,
3942
trackEvent: trackEventMock)
4043
ethereum.delegate = mockEthereumDelegate
4144
}
@@ -46,7 +49,7 @@ class EthereumConvenienceMethodsTests: XCTestCase {
4649
mockNetwork = nil
4750
store.deleteAll()
4851
mockEthereumDelegate = nil
49-
mockInfuraProvider = nil
52+
mockReadOnlyRPCProvider = nil
5053
mockCommClientFactory = nil
5154
EthereumWrapper.shared.ethereum = nil
5255
SDKWrapper.shared.sdk = nil
@@ -55,93 +58,93 @@ class EthereumConvenienceMethodsTests: XCTestCase {
5558

5659
func testGetChainId() async {
5760
ethereum.connected = true
58-
ethereum.infuraProvider = nil
5961
let chainId = "0x1"
6062

6163
let expectation = self.expectation(description: "Request should return chainId")
6264
performSuccessfulTask(
6365
ethereum.getChainId,
6466
expectedValue: chainId,
6567
expectation: expectation)
68+
mockReadOnlyRPCProvider.expectation = expectation
6669
sendResultAndAwait(chainId, method: .ethChainId)
6770
await fulfillment(of: [expectation], timeout: 2.0)
6871
}
6972

7073
func testGetEthAccounts() async {
7174
ethereum.connected = true
72-
ethereum.infuraProvider = nil
7375
let accounts = ["0x1234"]
7476

7577
let expectation = self.expectation(description: "Request should return accounts")
7678
performSuccessfulTaskCollectionResult(
7779
ethereum.getEthAccounts,
7880
expectedValue: accounts,
7981
expectation: expectation)
82+
mockReadOnlyRPCProvider.expectation = expectation
8083
sendResultAndAwait(accounts, method: .ethAccounts)
8184
await fulfillment(of: [expectation], timeout: 2.0)
8285
}
8386

8487
func testGetEthGasPrice() async {
8588
ethereum.connected = true
86-
ethereum.infuraProvider = nil
8789
let balance = "0x1000"
8890

8991
let expectation = self.expectation(description: "Request should return gas price")
9092
performSuccessfulTask(ethereum.getEthGasPrice,
9193
expectedValue: balance,
9294
expectation: expectation)
95+
mockReadOnlyRPCProvider.expectation = expectation
9396
sendResultAndAwait(balance, method: .ethGasPrice)
9497
await fulfillment(of: [expectation], timeout: 2.0)
9598
}
9699

97100
func testGetEthBalance() async {
98101
ethereum.connected = true
99-
ethereum.infuraProvider = nil
100102
let balance = "0x1000"
101103

102104
let expectation = self.expectation(description: "Request should return balance")
103105
performSuccessfulTask({
104106
await self.ethereum.getEthBalance(address: "0x1234", block: "latest")
105107
}, expectedValue: balance, expectation: expectation)
108+
mockReadOnlyRPCProvider.expectation = expectation
106109
sendResultAndAwait(balance, method: .ethGetBalance)
107110
await fulfillment(of: [expectation], timeout: 2.0)
108111
}
109112

110113
func testGetEthBlockNumber() async {
111114
ethereum.connected = true
112-
ethereum.infuraProvider = nil
113115
let blockNumber = "0x10"
114116

115117
let expectation = self.expectation(description: "Request should return block number")
116118
performSuccessfulTask({
117119
await self.ethereum.getEthBlockNumber()
118120
}, expectedValue: blockNumber, expectation: expectation)
121+
mockReadOnlyRPCProvider.expectation = expectation
119122
sendResultAndAwait(blockNumber, method: .ethBlockNumber)
120123
await fulfillment(of: [expectation], timeout: 2.0)
121124
}
122125

123126
func testGetEthEstimateGas() async {
124127
ethereum.connected = true
125-
ethereum.infuraProvider = nil
126128
let gasEstimate = "0x5208"
127129

128130
let expectation = self.expectation(description: "Request should return gas estimate")
129131
performSuccessfulTask({
130132
await self.ethereum.getEthEstimateGas()
131133
}, expectedValue: gasEstimate, expectation: expectation)
134+
mockReadOnlyRPCProvider.expectation = expectation
132135
sendResultAndAwait(gasEstimate, method: .ethEstimateGas)
133136
await fulfillment(of: [expectation], timeout: 2.0)
134137
}
135138

136139
func testGetWeb3ClientVersion() async {
137140
ethereum.connected = true
138-
ethereum.infuraProvider = nil
139141
let web3Version = "Geth/v1.8.23-stable"
140142

141143
let expectation = self.expectation(description: "Request should return web3 version")
142144
performSuccessfulTask({
143145
await self.ethereum.getWeb3ClientVersion()
144146
}, expectedValue: web3Version, expectation: expectation)
147+
mockReadOnlyRPCProvider.expectation = expectation
145148
sendResultAndAwait(web3Version, method: .web3ClientVersion)
146149
await fulfillment(of: [expectation], timeout: 2.0)
147150
}
@@ -184,52 +187,54 @@ class EthereumConvenienceMethodsTests: XCTestCase {
184187

185188
func testSendRawTransaction() async {
186189
ethereum.connected = true
187-
ethereum.infuraProvider = nil
188190
let transactionHash = "0x345678"
189191

190192
let expectation = self.expectation(description: "Request should return transaction hash result")
191193
performSuccessfulTask({
192194
await self.ethereum.sendRawTransaction(signedTransaction: "signedTx")
193195
}, expectedValue: transactionHash, expectation: expectation)
196+
mockReadOnlyRPCProvider.response = transactionHash
197+
mockReadOnlyRPCProvider.expectation = expectation
194198
sendResultAndAwait(transactionHash, method: .ethSendRawTransaction)
195199
await fulfillment(of: [expectation], timeout: 2.0)
196200
}
197201

198202
func testGetBlockTransactionCountByNumber() async {
199203
ethereum.connected = true
200-
ethereum.infuraProvider = nil
201204
let transactionCount = "0x20"
202205

203206
let expectation = self.expectation(description: "Request should return transaction count")
207+
mockReadOnlyRPCProvider.response = transactionCount
208+
204209
performSuccessfulTask({
205210
await self.ethereum.getBlockTransactionCountByNumber(blockNumber: "0x10")
206211
}, expectedValue: transactionCount, expectation: expectation)
212+
207213
sendResultAndAwait(transactionCount, method: .ethGetBlockTransactionCountByNumber)
208-
await fulfillment(of: [expectation], timeout: 2.0)
214+
await fulfillment(of: [expectation], timeout: 20.0)
209215
}
210216

211217
func testGetBlockTransactionCountByHash() async {
212218
ethereum.connected = true
213-
ethereum.infuraProvider = nil
214219
let transactionCount = "0x30"
215220

216221
let expectation = self.expectation(description: "Request should return transaction count")
217222
performSuccessfulTask({
218223
await self.ethereum.getBlockTransactionCountByHash(blockHash: "0xabcdef")
219224
}, expectedValue: transactionCount, expectation: expectation)
225+
mockReadOnlyRPCProvider.response = transactionCount
226+
mockReadOnlyRPCProvider.expectation = expectation
220227
sendResultAndAwait(transactionCount, method: .ethGetBlockTransactionCountByHash)
221228
await fulfillment(of: [expectation], timeout: 2.0)
222229
}
223230

224231
func testGetTransactionCount() async {
225232
ethereum.connected = true
226-
ethereum.infuraProvider = nil
227233
let transactionCount = "0x40"
228234

229235
let expectation = self.expectation(description: "Request should return transaction count")
230-
performSuccessfulTask({
231-
await self.ethereum.getTransactionCount(address: "0x1234", tagOrblockNumber: "latest")
232-
}, expectedValue: transactionCount, expectation: expectation)
236+
let result = await self.ethereum.getTransactionCount(address: "0x1234", tagOrblockNumber: "latest")
237+
mockReadOnlyRPCProvider.response = transactionCount
233238
sendResultAndAwait(transactionCount, method: .ethGetTransactionCount)
234239
await fulfillment(of: [expectation], timeout: 2.0)
235240
}

Example/Tests/EthereumTests.swift

+14-13
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class EthereumTests: XCTestCase {
1313
var mockEthereumDelegate: MockEthereumDelegate!
1414
var trackEventMock: ((Event, [String: Any]) -> Void)!
1515
var ethereum: Ethereum!
16-
var mockInfuraProvider: MockInfuraProvider!
16+
var mockReadOnlyRPCProvider: MockReadOnlyRPCProvider!
1717
let infuraApiKey = "testApiKey"
1818
var cancellables: Set<AnyCancellable>!
1919
var trackedEvents: [(Event, [String: Any])] = []
@@ -29,15 +29,18 @@ class EthereumTests: XCTestCase {
2929
}
3030

3131
mockNetwork = MockNetwork()
32-
mockInfuraProvider = MockInfuraProvider(infuraAPIKey: infuraApiKey, network: mockNetwork)
32+
mockReadOnlyRPCProvider = MockReadOnlyRPCProvider(
33+
infuraAPIKey: infuraApiKey,
34+
readonlyRPCMap: nil,
35+
network: mockNetwork)
3336
mockEthereumDelegate = MockEthereumDelegate()
3437
EthereumWrapper.shared.ethereum = nil
3538
SDKWrapper.shared.sdk = nil
3639
ethereum = Ethereum.shared(
3740
transport: .socket,
3841
store: store,
3942
commClientFactory: mockCommClientFactory,
40-
infuraProvider: mockInfuraProvider,
43+
readOnlyRPCProvider: mockReadOnlyRPCProvider,
4144
trackEvent: trackEventMock)
4245
ethereum.delegate = mockEthereumDelegate
4346
}
@@ -49,7 +52,7 @@ class EthereumTests: XCTestCase {
4952
ethereum = nil
5053
mockNetwork = nil
5154
mockEthereumDelegate = nil
52-
mockInfuraProvider = nil
55+
mockReadOnlyRPCProvider = nil
5356
mockCommClientFactory = nil
5457
EthereumWrapper.shared.ethereum = nil
5558
SDKWrapper.shared.sdk = nil
@@ -60,11 +63,11 @@ class EthereumTests: XCTestCase {
6063
let expectation = self.expectation(description: "Read only API call")
6164
let request = EthereumRequest(method: "eth_blockNumber")
6265
ethereum.chainId = "0x1"
63-
mockInfuraProvider.expectation = expectation
66+
mockReadOnlyRPCProvider.expectation = expectation
6467
ethereum.sendRequest(request)
6568

6669
waitForExpectations(timeout: 2.0) { _ in
67-
XCTAssertTrue(self.mockInfuraProvider.sendRequestCalled)
70+
XCTAssertTrue(self.mockReadOnlyRPCProvider.sendRequestCalled)
6871
}
6972
}
7073

@@ -150,15 +153,15 @@ class EthereumTests: XCTestCase {
150153
waitForExpectations(timeout: 2.0)
151154
}
152155

153-
func testSendRequestReadOnlyWithInfuraProvider() {
156+
func testSendRequestReadOnlyWithReadOnlyRPCProvider() {
154157
let expectation = self.expectation(description: "Read-only request with Infura provider")
155158
let request = EthereumRequest(method: "eth_blockNumber")
156-
mockInfuraProvider.expectation = expectation
159+
mockReadOnlyRPCProvider.expectation = expectation
157160

158161
ethereum.sendRequest(request)
159162

160163
waitForExpectations(timeout: 2.0) { _ in
161-
XCTAssertTrue(self.mockInfuraProvider.sendRequestCalled)
164+
XCTAssertTrue(self.mockReadOnlyRPCProvider.sendRequestCalled)
162165
}
163166
}
164167

@@ -741,9 +744,7 @@ class EthereumTests: XCTestCase {
741744
XCTAssertFalse(mockEthereumDelegate.accountChangedCalled)
742745
}
743746

744-
func testInfuraProvider() {
745-
XCTAssertTrue(ethereum.infuraProvider is MockInfuraProvider)
746-
ethereum.infuraProvider = nil
747-
XCTAssertNil(ethereum.infuraProvider)
747+
func testReadOnlyRPCProvider() {
748+
XCTAssertTrue(ethereum.readOnlyRPCProvider is MockReadOnlyRPCProvider)
748749
}
749750
}

0 commit comments

Comments
 (0)