Skip to content
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,14 @@ protocol IERC1376: IERC20 {

// FIXME: Rewrite this to CodableTransaction
public class ERC1376: IERC1376, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1376ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -92,6 +83,9 @@ public class ERC1376: IERC1376, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,14 @@ protocol IERC1400: IERC20 {
// can be imperatively read and saved
// FIXME: Rewrite this to CodableTransaction
public class ERC1400: IERC1400, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1400ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -89,6 +80,9 @@ public class ERC1400: IERC1400, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
17 changes: 5 additions & 12 deletions Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,14 @@ protocol IERC1410: IERC20 {

// FIXME: Rewrite this to CodableTransaction
public class ERC1410: IERC1410, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
private var _totalSupply: BigUInt?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1410ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -68,6 +58,9 @@ public class ERC1410: IERC1410, ERC20BaseProperties {
self.abi = abi
self.transaction = transaction
self.transaction.to = address
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,14 @@ protocol IERC1594: IERC20 {

// FIXME: Rewrite this to CodableTransaction
public class ERC1594: IERC1594, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1594ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -57,6 +48,9 @@ public class ERC1594: IERC1594, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,14 @@ protocol IERC1633: IERC20, IERC165 {
}

public class ERC1633: IERC1633, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1633ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -44,6 +35,9 @@ public class ERC1633: IERC1633, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,14 @@ protocol IERC1643: IERC20 {

// FIXME: Rewrite this to CodableTransaction
public class ERC1643: IERC1643, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1643ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -47,6 +38,9 @@ public class ERC1643: IERC1643, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
16 changes: 5 additions & 11 deletions Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,14 @@ protocol IERC1644: IERC20 {

// FIXME: Rewrite this to CodableTransaction
public class ERC1644: IERC1644, ERC20BaseProperties {

internal var _name: String?
internal var _symbol: String?
internal var _decimals: UInt8?
internal var _hasReadProperties: Bool = false

public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
public var transaction: CodableTransaction
public var web3: Web3
public var provider: Web3Provider
public var address: EthereumAddress
public var abi: String

lazy var contract: Web3.Contract = {
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
precondition(contract != nil)
return contract!
}()
public let contract: Web3.Contract

public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1644ABI, transaction: CodableTransaction = .emptyTransaction) {
self.web3 = web3
Expand All @@ -46,6 +37,9 @@ public class ERC1644: IERC1644, ERC20BaseProperties {
self.transaction = transaction
self.transaction.to = address
self.abi = abi
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
contract = web3.contract(abi, at: address)!
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
}

public func getBalance(account: EthereumAddress) async throws -> BigUInt {
Expand Down
41 changes: 41 additions & 0 deletions Sources/web3swift/Tokens/ERC20/ERC20BaseProperties.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// ERC20BaseProperties.swift
//
//
// Created by Jann Driessen on 21.11.22.
//

import Foundation

/// Declares common properties of an [ERC-20](https://eips.ethereum.org/EIPS/eip-20) complient smart contract.
/// Default implementation of access to these properties is declared in the extension of this protocol.
public protocol ERC20BaseProperties: AnyObject {
var basePropertiesProvider: ERC20BasePropertiesProvider { get }
var contract: Web3.Contract { get }
var name: String? { get }
var symbol: String? { get }
var decimals: UInt8? { get }
}

public extension ERC20BaseProperties {
var name: String? {
basePropertiesProvider.name
}

var symbol: String? {
basePropertiesProvider.symbol
}

var decimals: UInt8? {
basePropertiesProvider.decimals
}

var hasReadProperties: Bool {
basePropertiesProvider.hasReadProperties
}

func readProperties() async throws {
if basePropertiesProvider.hasReadProperties { return }
try await basePropertiesProvider.readProperties()
}
}
40 changes: 40 additions & 0 deletions Sources/web3swift/Tokens/ERC20/ERC20BasePropertiesProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// ERC20BasePropertiesProvider.swift
//
//
// Created by Jann Driessen on 21.11.22.
//

import BigInt
import Foundation

/// The default implementation of access of common [ERC-20](https://eips.ethereum.org/EIPS/eip-20#methods) properties `name`, `symbol` and `decimals`.
public final class ERC20BasePropertiesProvider {
var name: String?
var symbol: String?
var decimals: UInt8?

private let contract: Web3.Contract
private (set) var hasReadProperties: Bool = false
init(contract: Web3.Contract) {
self.contract = contract
}

public func readProperties() async throws {
guard !hasReadProperties else { return }
guard contract.contract.address != nil else {return}
name = try await contract
.createReadOperation("name")?
.callContractMethod()["0"] as? String

symbol = try await contract
.createReadOperation("symbol")?
.callContractMethod()["0"] as? String

let decimals = try await contract
.createReadOperation("decimals")?
.callContractMethod()["0"] as? BigUInt
self.decimals = decimals != nil ? UInt8(decimals!) : nil
hasReadProperties = true
}
}
Loading