Skip to content

Commit 08e2399

Browse files
Merge pull request #104 from matterinc/develop
recent changes
2 parents 556e8ba + 1d46759 commit 08e2399

File tree

755 files changed

+123630
-11822
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

755 files changed

+123630
-11822
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ fastlane/screenshots
6767
fastlane/test_output
6868
API_keys.plist
6969
web3swiftTests/key.json
70+
web3swiftTests/Resources/key.json
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,307 @@
11

2+
# web3swift 2.0 Migration Guide
3+
4+
web3swift 2.0 is the latest major release of web3swift by Matter, Swift implementation of web3.js functionality for iOS and macOS. Following Semantic Versioning conventions, 2.0 introduces major release API-breaking changes.
5+
6+
This guide is provided in order to ease the transition of existing applications using web3swift 1.x to the latest APIs, as well as explain the design and structure of new and updated functionality.
7+
8+
- [Requirements](#requirements)
9+
- [Benefits of Upgrading](#benefits-of-upgrading)
10+
- [Follow naming convention](#follow-naming-convention)
11+
- [New pods](#new-pods)
12+
- [Breaking API Changes](#breaking-api-changes)
13+
- [Setting Transaction Options](#setting-transaction-options)
14+
- [Preparing transaction](#preparing-transaction)
15+
- [For sending Ether](#for-sending-ether)
16+
- [For sending ERC20](#for-sending-erc20)
17+
- [For sending to contract](#for-sending-to-contract)
18+
- [Send transaction](#send-transaction)
19+
- [For sending ether or tokens to wallets and contracts](#for-sending-ether-or-tokens-to-wallets-and-contracts)
20+
- [For calling contract methods](#for-calling-contract-methods)
21+
- [Get balance](#get-balance)
22+
- [Get Ether balance](#get-ether-balance)
23+
- [Get ERC20 balance](#get-erc20-balance)
24+
- [Chain state](#chain-state)
25+
- [Get Block number](#get-block-number)
26+
27+
## Requirements
28+
29+
- iOS 9.0+, macOS 10.11.0+
30+
- Xcode 10.0+
31+
- Swift 4.0+
32+
33+
## Benefits of Upgrading
34+
35+
- **Complete Swift 4 Compatibility:** includes the full adoption of the new [API Design Guidelines](https://swift.org/documentation/api-design-guidelines/).
36+
- **Separate libraries: EthereumAddress, EthereumABI:** Since there are several Matter products uses this classes, we've decided make them separate and turn in Pods.
37+
- **New class: TransactionOptions:** "Web3Options" is no longer used, instead new class introduced: "TransactionOptions" used to specify gas price, limit, nonce policy, value.
38+
- **New classes: Write Transaction & Read Transaction:** "TransactionIntermediate" is no longer used, instead two new classes introduced: "ReadTransaction" and "WriteTransaction", that have a variable "transactionOptions" used to specify gas price, limit, nonce policy, value
39+
- **WKWebView with injected "web3" provider:** create a simple DApps' browser with "web3" provider onboard.
40+
- **Add or remove "middleware":** that intercepts, modifies and even cancel transaction workflow on stages "before assembly" (before obtaining nonce, gas price, etc), "after assembly" (when nonce and gas price is set for transaction) and "before submission" (right before transaction is either signed locally and is sent as raw, or just send to remote node).
41+
- **Hooks and event loops functionality:** easy monitor properties in web3.
42+
- **New errors handling:** more 'try-catch' less optionals for errors handling.
43+
- **Removed "Result" framework:** usage of "Result" framework was removed due to large amount if name conflicts, now functions throw instead of returning "Result" wrapper.
44+
45+
---
46+
47+
## Follow naming convention
48+
49+
Now you have to do "import Web3swift" (capitalization!) instead of "import web3swift" to follow naming convention.
50+
51+
## New pods
52+
53+
Now EthereumAddress and Ethereum ABI are separate projects. Use "import EthereumAddress" and "import Ethereum ABI" everywhere you use them.
54+
55+
## Breaking API Changes
56+
57+
web3swift 2.0 has fully adopted all the new Swift 4 changes and conventions, including the new [API Design Guidelines](https://swift.org/documentation/api-design-guidelines/). Because of this, almost every API in web3swift has been modified in some way. We can't possibly document every single change, so we're going to attempt to identify the most important API changes to help you through those sometimes less than helpful compiler errors.
58+
59+
### Setting Transaction Options
60+
61+
Since setting transaction options is the most important operation for building transaction in web3swift, here are some examples of web3swift 1.x building transaction options compared to their new equivalents in web3swift 2.0.
62+
63+
```swift
64+
// web3swift 1.0
65+
var options = Web3Options()
66+
options.gasLimit = BigUInt(0)
67+
options.gasPrice = BigUInt(0)
68+
options.value = BigUInt(0)
69+
options.to = EthereumAddress("<Reciever address>")!
70+
options.from = EthereumAddress("<Sender address>")!
71+
72+
// web3swift 2.0
73+
var options = TransactionOptions()
74+
options.callOnBlock = .pending // or .latest / or .exactBlockNumber(BigUInt)
75+
options.nonce = .pending // or .latest / or .manual(BigUInt)
76+
options.gasLimit = .automatic // or .manual(BigUInt) / or .limited(BigUInt) / or .withMargin(Double)
77+
options.gasPrice = .automatic // or .manual(BigUInt) / or .withMargin(Double)
78+
options.to = EthereumAddress("<Reciever address>")!
79+
options.from = EthereumAddress("<Sender address>")!
80+
```
81+
82+
### Preparing transaction
83+
84+
In web3swift 1.0 you specified transactions for Ether, ERC20 and to contract in different, inconvenient and unobvious ways. From 2.0 on it became more convenient and obvious.
85+
86+
#### For sending Ether
87+
88+
```swift
89+
// web3swift 1.0
90+
guard let destinationEthAddress = EthereumAddress(destinationAddressString) else {return}
91+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {return}
92+
guard let selectedKey = KeysService().selectedWallet()?.address else {return}
93+
let web3 = web3swift.web3(provider: InfuraProvider(Networks.Mainnet)!) //or any other network
94+
web3.addKeystoreManager(KeysService().keystoreManager())
95+
let ethAddressFrom = EthereumAddress(selectedKey)
96+
var options = Web3Options.defaultOptions()
97+
options.from = ethAddressFrom
98+
options.value = BigUInt(amount)
99+
guard let contract = web3.contract(Web3.Utils.coldWalletABI, at: destinationEthAddress) else {return}
100+
guard let estimatedGas = contract.method(options: options)?.estimateGas(options: nil).value else {return}
101+
options.gasLimit = estimatedGas
102+
guard let gasPrice = web3.eth.getGasPrice().value else {return}
103+
options.gasPrice = gasPrice
104+
guard let transaction = contract.method(options: options) else {return}
105+
return transaction
106+
107+
// web3swift 2.0
108+
guard let destinationEthAddress = EthereumAddress(destinationAddressString) else {return}
109+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {return}
110+
guard let selectedKey = KeysService().selectedWallet()?.address else {return}
111+
let web3 = Web3.InfuraMainnetWeb3() //or any other network
112+
web3.addKeystoreManager(KeysService().keystoreManager())
113+
guard let ethAddressFrom = EthereumAddress(selectedKey) else {return}
114+
guard let contract = web3.contract(Web3.Utils.coldWalletABI, at: destinationEthAddress, abiVersion: 2) else {return}
115+
guard let writeTX = contract.write("fallback") else {return}
116+
writeTX.transactionOptions.from = ethAddressFrom
117+
writeTX.transactionOptions.value = value
118+
return writeTX
119+
```
120+
121+
#### For sending ERC20
122+
123+
```swift
124+
// web3swift 1.0
125+
guard let destinationEthAddress = EthereumAddress(destinationAddressString) else {return}
126+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {return}
127+
let web3 = web3swift.web3(provider: InfuraProvider(Networks.Mainnet)!) //or any other network
128+
web3.addKeystoreManager(KeysService().keystoreManager())
129+
let contract = self.contract(for: token, web3: web3)
130+
var options = Web3Options.defaultOptions()
131+
guard let tokenAddress = EthereumAddress(token),
132+
let fromAddress = Web3SwiftService.currentAddress,
133+
let intermediate = web3.eth.sendERC20tokensWithNaturalUnits(tokenAddress: tokenAddress,
134+
from: fromAddress,
135+
to: destinationEthAddress,
136+
amount: amountString) else {return}
137+
//MARK: - Just to check that everything is all right
138+
guard let _ = contract?.method(options: options)?.estimateGas(options: options).value else {return}
139+
guard let gasPrice = web3.eth.getGasPrice().value else {return}
140+
options.from = Web3SwiftService.currentAddress
141+
options.gasPrice = gasPrice
142+
options.value = 0
143+
options.to = EthereumAddress(token)
144+
let parameters = [destinationEthAddress, amount] as [Any]
145+
guard let transaction = contract?.method("transfer",
146+
parameters: parameters as [AnyObject],
147+
options: options) else {return}
148+
return transaction
149+
150+
// web3swift 2.0
151+
guard let contractAddress = EthereumAddress(contractAddressString) else {return}
152+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {return}
153+
guard let selectedKey = KeysService().selectedWallet()?.address else {return}
154+
let web3 = Web3.InfuraMainnetWeb3() //or any other network
155+
web3.addKeystoreManager(KeysService().keystoreManager())
156+
guard let ethAddressFrom = EthereumAddress(selectedKey) else {return}
157+
guard let contract = web3.contract(Web3.Utils.erc20ABI, at: contractAddress, abiVersion: 2) else {return}
158+
guard let writeTX = contract.write("transfer") else {return}
159+
writeTX.transactionOptions.from = ethAddressFrom
160+
writeTX.transactionOptions.value = value
161+
return writeTX
162+
```
163+
164+
#### For sending to contract
165+
166+
```swift
167+
// web3swift 1.0
168+
let wallet = TransactionsService.keyservice.selectedWallet()
169+
guard let address = wallet?.address else {return}
170+
guard let ethAddressFrom = EthereumAddress(address) else {return}
171+
guard let ethContractAddress = EthereumAddress(contractAddress) else {return}
172+
let web3 = Web3.InfuraMainnetWeb3() //or any other web
173+
web3.addKeystoreManager(TransactionsService.keyservice.keystoreManager())
174+
var options = predefinedOptions ?? Web3Options.defaultOptions()
175+
options.from = ethAddressFrom
176+
options.to = ethContractAddress
177+
options.value = options.value ?? 0
178+
guard let contract = web3.contract(contractAbi,
179+
at: ethContractAddress,
180+
abiVersion: 2) else {return}
181+
guard let gasPrice = web3.eth.getGasPrice().value else {return}
182+
options.gasPrice = predefinedOptions?.gasPrice ?? gasPrice
183+
guard let transaction = contract.method(method,
184+
parameters: data,
185+
options: options) else {return}
186+
guard case .success(let estimate) = transaction.estimateGas(options: options) else {return}
187+
print("estimated cost: \(estimate)")
188+
return transaction
189+
190+
// web3swift 2.0
191+
guard let contractAddress = EthereumAddress(contractAddressString) else {return}
192+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {return}
193+
guard let selectedKey = KeysService().selectedWallet()?.address else {return}
194+
let web3 = Web3.InfuraMainnetWeb3() //or any other network
195+
web3.addKeystoreManager(KeysService().keystoreManager())
196+
guard let ethAddressFrom = EthereumAddress(selectedKey) else {return}
197+
guard let contract = web3.contract(contractAbi, at: contractAddress, abiVersion: 2) else {return}
198+
guard let writeTX = contract.write(method,
199+
parameters: parameters,
200+
extraData: data,
201+
transactionOptions: predefinedOptions) else {return}
202+
writeTX.transactionOptions.from = ethAddressFrom
203+
writeTX.transactionOptions.value = value
204+
return writeTX
205+
```
206+
207+
### Send transaction
208+
209+
In web3swift 1.0 you specified sending operations with only value and to contract in different, inconvenient and unobvious ways. From 2.0 on you can use two methods: Send to send ether or tokens and Call for calling contract methods.
210+
211+
#### For sending ether or tokens to wallets and contracts
212+
213+
```swift
214+
// web3swift 1.0
215+
let result = transaction.send(password: <your password>,
216+
options: options)
217+
if let error = result.error {return}
218+
guard let value = result.value else {return}
219+
return value
220+
221+
// web3swift 2.0
222+
let options = options ?? transaction.transactionOptions
223+
guard let result = password == nil ?
224+
try? transaction.send() :
225+
try? transaction.send(password: <your password>, transactionOptions: options) else {return}
226+
return result
227+
```
228+
229+
#### For calling contract methods
230+
231+
```swift
232+
// web3swift 1.0
233+
let result = transaction.send(password: <your password>,
234+
options: transaction.options)
235+
if let error = result.error {return}
236+
guard let value = result.value else {return}
237+
return value
238+
239+
// web3swift 2.0
240+
let options = options ?? transaction.transactionOptions
241+
guard let result = try? transaction.call(transactionOptions: options) else {return}
242+
return result
243+
```
244+
245+
### Get balance
246+
247+
### Get Ether balance
248+
249+
```swift
250+
// web3swift 1.0
251+
let address = EthereumAddress("<Address>")!
252+
let web3Main = Web3.InfuraMainnetWeb3()
253+
let balanceResult = web3Main.eth.getBalance(address)
254+
guard case .success(let balance) = balanceResult else {return}
255+
let balanceString = Web3.Utils.formatToEthereumUnits(balance, toUnits: .eth, decimals: 3)
256+
257+
// web3swift 2.0
258+
let address = EthereumAddress("<Address>")!
259+
let web3Main = Web3.InfuraMainnetWeb3()
260+
let balance = try web3.eth.getBalance(address: address)
261+
let balanceString = Web3.Utils.formatToEthereumUnits(balance, toUnits: .eth, decimals: 3)
262+
```
263+
264+
### Get ERC20 balance
265+
266+
```swift
267+
// web3swift 1.0
268+
let contractAddress = EthereumAddress("<Contract ddress>")! // w3s token on Ethereum mainnet
269+
let contract = web3.contract(Web3.Utils.erc20ABI, at: contractAddress, abiVersion: 2)! // utilize precompiled ERC20 ABI for your concenience
270+
guard let w3sBalanceResult = contract.method("balanceOf",
271+
parameters: [coldWalletAddress] as [AnyObject],
272+
options: options)?.call(options: nil) else {return} // encode parameters for transaction
273+
guard case .success(let w3sBalance) = w3sBalanceResult, let bal = w3sBalance["0"] as? BigUInt else {return} // w3sBalance is [String: Any], and parameters are enumerated as "0", "1", etc in order of being returned. If returned parameter has a name in ABI, it is also duplicated
274+
275+
// web3swift 2.0
276+
let contractAddress = EthereumAddress("<Contract address>")! // w3s token on Ethereum mainnet
277+
let contract = web3.contract(Web3.Utils.erc20ABI, at: contractAddress, abiVersion: 2) // utilize precompiled ERC20 ABI for your concenience
278+
let userAddress = EthereumAddress("<address>")!
279+
guard let readTX = contract?.read("balanceOf", parameters: [addressOfUser] as [AnyObject]) else {return}
280+
readTX.transactionOptions.from = EthereumAddress("<address>")!
281+
let tokenBalance = try readTX.callPromise().wait()
282+
guard let balance = tokenBalance["0"] as? BigUInt else {return}
283+
```
284+
285+
### Chain state
286+
287+
### Get Block number
288+
289+
```swift
290+
// web3swift 1.0
291+
let web3 = WalletWeb3Factory.web3()
292+
let res = web3.eth.getBlockNumber()
293+
switch res {
294+
case .failure(let error):
295+
return error
296+
case .success(let number):
297+
return number
298+
}
299+
300+
// web3swift 2.0
301+
do {
302+
let number = try web3.eth.getBlockNumber()
303+
return number
304+
} catch let error {
305+
return error
306+
}
307+
```

Example/web3swiftBrowser/Podfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
platform :ios, '12.0'
2+
3+
target 'web3swiftBrowser' do
4+
use_frameworks!
5+
pod 'web3swift', :path => '../../'
6+
pod "WKBridge"
7+
end

Example/web3swiftBrowser/Podfile.lock

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
PODS:
2+
- BigInt (3.1.0):
3+
- SipHash (~> 1.2)
4+
- CryptoSwift (0.13.0)
5+
- EthereumABI (1.1.1):
6+
- BigInt (~> 3.1)
7+
- CryptoSwift (~> 0.13)
8+
- EthereumAddress (~> 1.0.0)
9+
- EthereumAddress (1.0.0):
10+
- CryptoSwift (~> 0.13)
11+
- PromiseKit (6.5.2):
12+
- PromiseKit/CorePromise (= 6.5.2)
13+
- PromiseKit/Foundation (= 6.5.2)
14+
- PromiseKit/UIKit (= 6.5.2)
15+
- PromiseKit/CorePromise (6.5.2)
16+
- PromiseKit/Foundation (6.5.2):
17+
- PromiseKit/CorePromise
18+
- PromiseKit/UIKit (6.5.2):
19+
- PromiseKit/CorePromise
20+
- scrypt (2.0):
21+
- CryptoSwift (~> 0.11)
22+
- secp256k1_swift (1.0.3)
23+
- SipHash (1.2.2)
24+
- SwiftRLP (1.2):
25+
- BigInt (~> 3.1)
26+
- web3swift (2.0.1):
27+
- BigInt (~> 3.1)
28+
- CryptoSwift (~> 0.13)
29+
- EthereumABI (~> 1.1.1)
30+
- EthereumAddress (~> 1.0.0)
31+
- PromiseKit (~> 6.3)
32+
- scrypt (~> 2.0)
33+
- secp256k1_swift (~> 1.0.3)
34+
- SwiftRLP (~> 1.1)
35+
- WKBridge (0.2.4)
36+
37+
DEPENDENCIES:
38+
- web3swift (from `../../`)
39+
- WKBridge
40+
41+
SPEC REPOS:
42+
https://github.com/cocoapods/specs.git:
43+
- BigInt
44+
- CryptoSwift
45+
- EthereumABI
46+
- EthereumAddress
47+
- PromiseKit
48+
- scrypt
49+
- secp256k1_swift
50+
- SipHash
51+
- SwiftRLP
52+
- WKBridge
53+
54+
EXTERNAL SOURCES:
55+
web3swift:
56+
:path: "../../"
57+
58+
SPEC CHECKSUMS:
59+
BigInt: 76b5dfdfa3e2e478d4ffdf161aeede5502e2742f
60+
CryptoSwift: 16e78bebf567bad1c87b2d58f6547f25b74c31aa
61+
EthereumABI: f040f5429e5a4366d028c88b88d9441e137593af
62+
EthereumAddress: f476e1320dca3a0024431e713ede7a09c7eb7796
63+
PromiseKit: 27c1601bfb73405871b805bcb8cf7e55c4dad3db
64+
scrypt: 3fe5b1a3b0976f97cd87488673a8f7c65708cc84
65+
secp256k1_swift: 4fc5c4b2d2c6d21ee8ccb868cdc92da12f38bed9
66+
SipHash: fad90a4683e420c52ef28063063dbbce248ea6d4
67+
SwiftRLP: 98a02b2210128353ca02e4c2f4d83e2a9796db4f
68+
web3swift: aadc7a9b0c3b0384227eff181e39ba24ebfcd76c
69+
WKBridge: 677fc36b9a9e4a80b6f9c4e915480d8fd91f5ad5
70+
71+
PODFILE CHECKSUM: ed17f63e9fc4feec3b3d9d88971f86da22d55a1f
72+
73+
COCOAPODS: 1.6.0.beta.2

0 commit comments

Comments
 (0)