Skip to content

Commit 78fbd28

Browse files
Update Usage.md
1 parent bb1091a commit 78fbd28

File tree

1 file changed

+353
-0
lines changed

1 file changed

+353
-0
lines changed

Documentation/Usage.md

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,156 @@ print("w3s token balance = " + String(bal))
297297

298298
## Transactions Operations
299299

300+
#### Web3Options
301+
302+
```swift
303+
/// A web3 instance bound to provider. All further functionality is provided under web.*. namespaces.
304+
public class web3: Web3OptionsInheritable {
305+
public var provider : Web3Provider
306+
public var options : Web3Options = Web3Options.defaultOptions()
307+
public var defaultBlock = "latest"
308+
public var requestDispatcher: JSONRPCrequestDispatcher
309+
310+
/// Add a provider request to the dispatch queue.
311+
public func dispatch(_ request: JSONRPCrequest) -> Promise<JSONRPCresponse> {
312+
return self.requestDispatcher.addToQueue(request: request)
313+
}
314+
315+
/// Raw initializer using a Web3Provider protocol object, dispatch queue and request dispatcher.
316+
public init(provider prov: Web3Provider, queue: OperationQueue? = nil, requestDispatcher: JSONRPCrequestDispatcher? = nil) {
317+
provider = prov
318+
if requestDispatcher == nil {
319+
self.requestDispatcher = JSONRPCrequestDispatcher(provider: provider, queue: DispatchQueue.global(qos: .userInteractive), policy: .Batch(32))
320+
} else {
321+
self.requestDispatcher = requestDispatcher!
322+
}
323+
}
324+
325+
/// Keystore manager can be bound to Web3 instance. If some manager is bound all further account related functions, such
326+
/// as account listing, transaction signing, etc. are done locally using private keys and accounts found in a manager.
327+
public func addKeystoreManager(_ manager: KeystoreManager?) {
328+
self.provider.attachedKeystoreManager = manager
329+
}
330+
331+
var ethInstance: web3.Eth?
332+
333+
/// Public web3.eth.* namespace.
334+
public var eth: web3.Eth {
335+
if (self.ethInstance != nil) {
336+
return self.ethInstance!
337+
}
338+
self.ethInstance = web3.Eth(provider : self.provider, web3: self)
339+
return self.ethInstance!
340+
}
341+
342+
public class Eth:Web3OptionsInheritable {
343+
var provider:Web3Provider
344+
// weak var web3: web3?
345+
var web3: web3
346+
public var options: Web3Options {
347+
return self.web3.options
348+
}
349+
public init(provider prov: Web3Provider, web3 web3instance: web3) {
350+
provider = prov
351+
web3 = web3instance
352+
}
353+
}
354+
355+
var personalInstance: web3.Personal?
356+
357+
/// Public web3.personal.* namespace.
358+
public var personal: web3.Personal {
359+
if (self.personalInstance != nil) {
360+
return self.personalInstance!
361+
}
362+
self.personalInstance = web3.Personal(provider : self.provider, web3: self)
363+
return self.personalInstance!
364+
}
365+
366+
public class Personal:Web3OptionsInheritable {
367+
var provider:Web3Provider
368+
// weak var web3: web3?
369+
var web3: web3
370+
public var options: Web3Options {
371+
return self.web3.options
372+
}
373+
public init(provider prov: Web3Provider, web3 web3instance: web3) {
374+
provider = prov
375+
web3 = web3instance
376+
}
377+
}
378+
379+
var walletInstance: web3.Web3Wallet?
380+
381+
/// Public web3.wallet.* namespace.
382+
public var wallet: web3.Web3Wallet {
383+
if (self.walletInstance != nil) {
384+
return self.walletInstance!
385+
}
386+
self.walletInstance = web3.Web3Wallet(provider : self.provider, web3: self)
387+
return self.walletInstance!
388+
}
389+
390+
public class Web3Wallet {
391+
var provider:Web3Provider
392+
// weak var web3: web3?
393+
var web3: web3
394+
public init(provider prov: Web3Provider, web3 web3instance: web3) {
395+
provider = prov
396+
web3 = web3instance
397+
}
398+
}
399+
400+
var browserFunctionsInstance: web3.BrowserFunctions?
401+
402+
/// Public web3.browserFunctions.* namespace.
403+
public var browserFunctions: web3.BrowserFunctions {
404+
if (self.browserFunctionsInstance != nil) {
405+
return self.browserFunctionsInstance!
406+
}
407+
self.browserFunctionsInstance = web3.BrowserFunctions(provider : self.provider, web3: self)
408+
return self.browserFunctionsInstance!
409+
}
410+
411+
public class BrowserFunctions:Web3OptionsInheritable {
412+
var provider:Web3Provider
413+
// weak var web3: web3?
414+
var web3: web3
415+
public var options: Web3Options {
416+
return self.web3.options
417+
}
418+
public init(provider prov: Web3Provider, web3 web3instance: web3) {
419+
provider = prov
420+
web3 = web3instance
421+
}
422+
}
423+
424+
var erc721Instance: web3.ERC721?
425+
426+
/// Public web3.browserFunctions.* namespace.
427+
public var erc721: web3.ERC721 {
428+
if (self.erc721Instance != nil) {
429+
return self.erc721Instance!
430+
}
431+
self.erc721Instance = web3.ERC721(provider : self.provider, web3: self)
432+
return self.erc721Instance!
433+
}
434+
435+
public class ERC721: Web3OptionsInheritable {
436+
var provider:Web3Provider
437+
// weak var web3: web3?
438+
var web3: web3
439+
public var options: Web3Options {
440+
return self.web3.options
441+
}
442+
public init(provider prov: Web3Provider, web3 web3instance: web3) {
443+
provider = prov
444+
web3 = web3instance
445+
}
446+
}
447+
}
448+
```
449+
300450
### Prepare Transaction
301451

302452
#### Setting Transaction Options
@@ -313,6 +463,209 @@ options.gasLimit = gasLimit
313463
options.from = EthereumAddress("0xE6877A4d8806e9A9F12eB2e8561EA6c1db19978d")
314464
```
315465

466+
#### Preparing Transaction For Sending Ether
467+
468+
```swift
469+
public func prepareTransactionForSendingEther(destinationAddressString: String,
470+
amountString: String,
471+
gasLimit: BigUInt,
472+
completion: @escaping (Result<TransactionIntermediate>) -> Void) {
473+
DispatchQueue.global(qos: .userInitiated).async {
474+
guard let destinationEthAddress = EthereumAddress(destinationAddressString) else {
475+
DispatchQueue.main.async {
476+
completion(Result.Error(SendErrors.invalidDestinationAddress))
477+
}
478+
return
479+
}
480+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {
481+
DispatchQueue.main.async {
482+
completion(Result.Error(SendErrors.invalidAmountFormat))
483+
}
484+
return
485+
}
486+
guard let selectedKey = KeysService().selectedWallet()?.address else {
487+
DispatchQueue.main.async {
488+
completion(Result.Error(SendErrors.noAvailableKeys))
489+
}
490+
return
491+
}
492+
493+
494+
let web3 = web3swift.web3(provider: InfuraProvider(CurrentNetwork.currentNetwork ?? Networks.Mainnet)!)
495+
web3.addKeystoreManager(KeysService().keystoreManager())
496+
497+
let ethAddressFrom = EthereumAddress(selectedKey)
498+
var options = Web3Options.defaultOptions()
499+
options.from = ethAddressFrom
500+
options.value = BigUInt(amount)
501+
502+
guard let contract = web3.contract(Web3.Utils.coldWalletABI, at: destinationEthAddress) else {
503+
DispatchQueue.main.async {
504+
completion(Result.Error(SendErrors.contractLoadingError))
505+
}
506+
return
507+
}
508+
509+
guard let estimatedGas = contract.method(options: options)?.estimateGas(options: nil).value else {
510+
DispatchQueue.main.async {
511+
completion(Result.Error(SendErrors.retrievingEstimatedGasError))
512+
}
513+
return
514+
}
515+
options.gasLimit = estimatedGas
516+
517+
guard let gasPrice = web3.eth.getGasPrice().value else {
518+
DispatchQueue.main.async {
519+
completion(Result.Error(SendErrors.retrievingGasPriceError))
520+
}
521+
return
522+
}
523+
options.gasPrice = gasPrice
524+
525+
guard let transaction = contract.method(options: options) else {
526+
DispatchQueue.main.async {
527+
completion(Result.Error(SendErrors.createTransactionIssue))
528+
}
529+
return
530+
}
531+
532+
DispatchQueue.main.async {
533+
completion(Result.Success(transaction))
534+
}
535+
536+
}
537+
}
538+
```
539+
540+
#### Preparing Transaction For Sending ERC-20 tokens
541+
542+
```swift
543+
public func prepareTransactionForSendingERC(destinationAddressString: String,
544+
amountString: String,
545+
gasLimit: BigUInt,
546+
tokenAddress token: String,
547+
completion: @escaping (Result<TransactionIntermediate>) -> Void) {
548+
DispatchQueue.global(qos: .userInitiated).async {
549+
guard let destinationEthAddress = EthereumAddress(destinationAddressString) else {
550+
DispatchQueue.main.async {
551+
completion(Result.Error(SendErrors.invalidDestinationAddress))
552+
}
553+
return
554+
}
555+
guard let amount = Web3.Utils.parseToBigUInt(amountString, units: .eth) else {
556+
DispatchQueue.main.async {
557+
completion(Result.Error(SendErrors.invalidAmountFormat))
558+
}
559+
return
560+
}
561+
562+
let web3 = web3swift.web3(provider: InfuraProvider(CurrentNetwork.currentNetwork ?? Networks.Mainnet)!)
563+
web3.addKeystoreManager(KeysService().keystoreManager())
564+
565+
let contract = self.contract(for: token, web3: web3)
566+
var options = Web3Options.defaultOptions()
567+
568+
guard let tokenAddress = EthereumAddress(token),
569+
let fromAddress = Web3SwiftService.currentAddress,
570+
let intermediate = web3.eth.sendERC20tokensWithNaturalUnits(
571+
tokenAddress: tokenAddress,
572+
from: fromAddress,
573+
to: destinationEthAddress,
574+
amount: amountString) else {
575+
DispatchQueue.main.async {
576+
completion(Result.Error(SendErrors.createTransactionIssue))
577+
}
578+
return
579+
}
580+
DispatchQueue.main.async {
581+
completion(Result.Success(intermediate))
582+
}
583+
584+
//MARK: - Just to check that everything is all right
585+
guard let _ = contract?.method(options: options)?.estimateGas(options: options).value else {
586+
DispatchQueue.main.async {
587+
completion(Result.Error(SendErrors.retrievingEstimatedGasError))
588+
}
589+
return
590+
}
591+
guard let gasPrice = web3.eth.getGasPrice().value else {
592+
DispatchQueue.main.async {
593+
completion(Result.Error(SendErrors.retrievingGasPriceError))
594+
}
595+
return
596+
}
597+
598+
options.from = Web3SwiftService.currentAddress
599+
options.gasPrice = gasPrice
600+
//options.gasLimit = estimatedGas
601+
options.value = 0
602+
options.to = EthereumAddress(token)
603+
let parameters = [destinationEthAddress,
604+
amount] as [Any]
605+
guard let transaction = contract?.method("transfer",
606+
parameters: parameters as [AnyObject],
607+
options: options) else {
608+
DispatchQueue.main.async {
609+
completion(Result.Error(SendErrors.createTransactionIssue))
610+
}
611+
612+
return
613+
}
614+
DispatchQueue.main.async {
615+
completion(Result.Success(transaction))
616+
}
617+
618+
return
619+
}
620+
}
621+
```
622+
623+
#### Preparing Transaction For Sending To Some Contract
624+
625+
```swift
626+
public func prepareTransactionToContract(data: [AnyObject],
627+
contractAbi: String,
628+
contractAddress: String,
629+
method: String,
630+
predefinedOptions: Web3Options? = nil,
631+
completion: @escaping (Result<TransactionIntermediate>) -> Void) {
632+
let wallet = TransactionsService.keyservice.selectedWallet()
633+
guard let address = wallet?.address else { return }
634+
let ethAddressFrom = EthereumAddress(address)
635+
let ethContractAddress = EthereumAddress(contractAddress)!
636+
637+
let web3 = CurrentWeb.currentWeb ?? Web3.InfuraMainnetWeb3()
638+
web3.addKeystoreManager(TransactionsService.keyservice.keystoreManager())
639+
var options = predefinedOptions ?? Web3Options.defaultOptions()
640+
options.from = ethAddressFrom
641+
options.to = ethContractAddress
642+
options.value = options.value ?? 0
643+
guard let contract = web3.contract(contractAbi,
644+
at: ethContractAddress,
645+
abiVersion: 2) else {
646+
return
647+
DispatchQueue.main.async {
648+
completion(Result.Error(TransactionErrors.init(rawValue: "Can not create a contract with given abi and address.")!))
649+
}
650+
}
651+
guard let gasPrice = web3.eth.getGasPrice().value else { return }
652+
options.gasPrice = predefinedOptions?.gasPrice ?? gasPrice
653+
guard let transaction = contract.method(method,
654+
parameters: data,
655+
options: options) else { return }
656+
guard case .success(let estimate) = transaction.estimateGas(options: options) else {
657+
DispatchQueue.main.async {
658+
completion(Result.Error(TransactionErrors.PreparingError))
659+
}
660+
return
661+
}
662+
print("estimated cost: \(estimate)")
663+
DispatchQueue.main.async {
664+
completion(Result.Success(transaction))
665+
}
666+
}
667+
```
668+
316669
### Send Transaction
317670

318671
#### Sending ETH

0 commit comments

Comments
 (0)