diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..7f22cabd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.build/ +.vscode/launch.json diff --git a/CHedera.xcframework/ios-arm64/libhedera.a b/CHedera.xcframework/ios-arm64/libhedera.a index 642cf523..53c5137b 100644 Binary files a/CHedera.xcframework/ios-arm64/libhedera.a and b/CHedera.xcframework/ios-arm64/libhedera.a differ diff --git a/CHedera.xcframework/ios-x86_64-simulator/libhedera.a b/CHedera.xcframework/ios-x86_64-simulator/libhedera.a index 326e46de..7cdf8581 100644 Binary files a/CHedera.xcframework/ios-x86_64-simulator/libhedera.a and b/CHedera.xcframework/ios-x86_64-simulator/libhedera.a differ diff --git a/CHedera.xcframework/macos-arm64/libhedera.a b/CHedera.xcframework/macos-arm64/libhedera.a index 22df19ac..985b8874 100644 Binary files a/CHedera.xcframework/macos-arm64/libhedera.a and b/CHedera.xcframework/macos-arm64/libhedera.a differ diff --git a/CHedera.xcframework/macos-x86_64/libhedera.a b/CHedera.xcframework/macos-x86_64/libhedera.a index 72158a01..a66f39f9 100644 Binary files a/CHedera.xcframework/macos-x86_64/libhedera.a and b/CHedera.xcframework/macos-x86_64/libhedera.a differ diff --git a/Examples/DeleteAccount/main.swift b/Examples/DeleteAccount/main.swift index c9f36c51..f9d2a911 100644 --- a/Examples/DeleteAccount/main.swift +++ b/Examples/DeleteAccount/main.swift @@ -31,7 +31,7 @@ public enum Program { let response = try await AccountDeleteTransaction() .transferAccountId("0.0.6189") - .deleteAccountId("0.0.34952813") + .accountId("0.0.34952813") .execute(client) _ = try await response.getReceipt(client) diff --git a/Package.swift b/Package.swift index 00e575f9..88cd92e6 100644 --- a/Package.swift +++ b/Package.swift @@ -1,3 +1,5 @@ +// swift-tools-version:5.5 + /* * ‌ * Hedera Swift SDK @@ -18,7 +20,6 @@ * ‍ */ -// swift-tools-version:5.5 import PackageDescription // collect example targets diff --git a/README.md b/README.md index ad924225..2d4e16d1 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ Maintained with ❤️ by LaunchBadge, Swirlds Labs, and the Hedera community -## SDK IS NOT READY FOR PRODUCTION USE. IT IS CURRENTLY STILL UNDER DEVELOPEMENT. - ## Requirements - Swift v5.3+ @@ -55,19 +53,14 @@ community Discord: -## Contributing - -Contributions are welcome. Please see the -[contributing guide](https://github.com/hashgraph/.github/blob/main/CONTRIBUTING.md) -to see how you can get involved. - -## Code of Conduct +## License -This project is governed by the -[Contributor Covenant Code of Conduct](https://github.com/hashgraph/.github/blob/main/CODE_OF_CONDUCT.md). By -participating, you are expected to uphold this code of conduct. Please report unacceptable behavior -to [oss@hedera.com](mailto:oss@hedera.com). +Licensed under Apache License, +Version 2.0 – see [LICENSE](LICENSE) +or [apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0). -## License +## Contribution -[Apache License 2.0](LICENSE) +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +licensed as above, without any additional terms or conditions. diff --git a/Sources/Hedera/AccountAllowanceApproveTransaction.swift b/Sources/Hedera/AccountAllowanceApproveTransaction.swift index da5860c4..7b9f8f08 100644 --- a/Sources/Hedera/AccountAllowanceApproveTransaction.swift +++ b/Sources/Hedera/AccountAllowanceApproveTransaction.swift @@ -41,7 +41,7 @@ public final class AccountAllowanceApproveTransaction: Transaction { public func approveHbarAllowance( _ ownerAccountId: AccountId, _ spenderAccountId: AccountId, - _ amount: UInt64 + _ amount: Hbar ) -> Self { hbarAllowances.append( HbarAllowance( @@ -138,7 +138,7 @@ public final class AccountAllowanceApproveTransaction: Transaction { private struct HbarAllowance: Codable { let ownerAccountId: AccountId let spenderAccountId: AccountId - let amount: UInt64 + let amount: Hbar } private struct TokenAllowance: Codable { diff --git a/Sources/Hedera/AccountBalance.swift b/Sources/Hedera/AccountBalance.swift index 95980fcb..b9cdde33 100644 --- a/Sources/Hedera/AccountBalance.swift +++ b/Sources/Hedera/AccountBalance.swift @@ -24,6 +24,5 @@ public final class AccountBalanceResponse: Codable { public let accountId: AccountId /// Current balance of the referenced account. - // TODO: use Hbar type - public let hbars: UInt64 + public let hbars: Hbar } diff --git a/Sources/Hedera/AccountBalanceQuery.swift b/Sources/Hedera/AccountBalanceQuery.swift index fbb5d920..1f80e8ce 100644 --- a/Sources/Hedera/AccountBalanceQuery.swift +++ b/Sources/Hedera/AccountBalanceQuery.swift @@ -28,7 +28,7 @@ public final class AccountBalanceQuery: Query { /// Create a new `AccountBalanceQuery`. public init( accountId: AccountId? = nil, - contractId: AccountId? = nil + contractId: ContractId? = nil ) { self.accountId = accountId self.contractId = contractId @@ -50,16 +50,14 @@ public final class AccountBalanceQuery: Query { } /// The contract ID for which information is requested. - // TODO: Use ContractIdOrEvmAddress - public var contractId: AccountId? + public var contractId: ContractId? /// Sets the contract ID for which information is requested. /// /// This is mutually exclusive with `accountId`. /// - // TODO: Use ContractIdOrEvmAddress @discardableResult - public func contractId(_ contractId: AccountId) -> Self { + public func contractId(_ contractId: ContractId) -> Self { self.contractId = contractId accountId = nil diff --git a/Sources/Hedera/AccountCreateTransaction.swift b/Sources/Hedera/AccountCreateTransaction.swift index 740e0af8..76d8abcf 100644 --- a/Sources/Hedera/AccountCreateTransaction.swift +++ b/Sources/Hedera/AccountCreateTransaction.swift @@ -25,7 +25,7 @@ public final class AccountCreateTransaction: Transaction { /// Create a new `AccountCreateTransaction` ready for configuration. public init( key: Key? = nil, - initialBalance: UInt64 = 0, + initialBalance: Hbar = 0, receiverSignatureRequired: Bool = false, autoRenewPeriod: TimeInterval? = nil, accountMemo: String = "", @@ -56,13 +56,12 @@ public final class AccountCreateTransaction: Transaction { return self } - // TODO: Hbar /// The initial number of Hbar to put into the account. - public var initialBalance: UInt64 + public var initialBalance: Hbar /// Sets the initial number of Hbar to put into the account. @discardableResult - public func initialBalance(_ initialBalance: UInt64) -> Self { + public func initialBalance(_ initialBalance: Hbar) -> Self { self.initialBalance = initialBalance return self diff --git a/Sources/Hedera/AccountDeleteTransaction.swift b/Sources/Hedera/AccountDeleteTransaction.swift index 88ae7d02..4314ad13 100644 --- a/Sources/Hedera/AccountDeleteTransaction.swift +++ b/Sources/Hedera/AccountDeleteTransaction.swift @@ -41,26 +41,26 @@ public final class AccountDeleteTransaction: Transaction { } /// The account ID which should be deleted. - public var deleteAccountId: AccountId? + public var accountId: AccountId? /// Sets the account ID which should be deleted. @discardableResult - public func deleteAccountId(_ deleteAccountId: AccountId) -> Self { - self.deleteAccountId = deleteAccountId + public func accountId(_ accountId: AccountId) -> Self { + self.accountId = accountId return self } private enum CodingKeys: String, CodingKey { case transferAccountId - case deleteAccountId + case accountId } public override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(transferAccountId, forKey: .transferAccountId) - try container.encodeIfPresent(deleteAccountId, forKey: .deleteAccountId) + try container.encodeIfPresent(accountId, forKey: .accountId) try super.encode(to: encoder) } diff --git a/Sources/Hedera/AccountInfo.swift b/Sources/Hedera/AccountInfo.swift index e2960657..6c165111 100644 --- a/Sources/Hedera/AccountInfo.swift +++ b/Sources/Hedera/AccountInfo.swift @@ -20,7 +20,6 @@ import Foundation -// TODO: stakingInfo /// Response from `AccountInfoQuery`. public final class AccountInfo: Codable { /// The account that is being referenced. @@ -35,16 +34,14 @@ public final class AccountInfo: Codable { public let isDeleted: Bool /// The total number of HBARs proxy staked to this account. - // TODO: use Hbar type - public let proxyReceived: UInt64 + public let proxyReceived: Hbar /// The key for the account, which must sign in order to transfer out, or to modify the /// account in any way other than extending its expiration date. public let key: Key /// Current balance of the referenced account. - // TODO: use Hbar type - public let balance: UInt64 + public let balance: Hbar /// If true, no transaction can transfer to this account unless signed by /// this account's key. @@ -65,9 +62,15 @@ public final class AccountInfo: Codable { /// The maximum number of tokens that an Account can be implicitly associated with. public let maxAutomaticTokenAssociations: UInt32 - /// The alias of this account. - public let alias: PublicKey? + /// The public key which aliases to this account. + public let aliasKey: PublicKey? /// The ethereum transaction nonce associated with this account. public let ethereumNonce: UInt64 + + /// The ledger ID the response was returned from. + public let ledgerId: LedgerId + + /// Staking metadata for this account. + public let staking: StakingInfo? } diff --git a/Sources/Hedera/AccountUpdateTransaction.swift b/Sources/Hedera/AccountUpdateTransaction.swift index 4a8454ad..007998cc 100644 --- a/Sources/Hedera/AccountUpdateTransaction.swift +++ b/Sources/Hedera/AccountUpdateTransaction.swift @@ -76,12 +76,12 @@ public final class AccountUpdateTransaction: Transaction { } /// The new expiration time to extend to (ignored if equal to or before the current one). - public var expiresAt: Date? + public var expirationTime: Date? /// Sets the new expiration time to extend to (ignored if equal to or before the current one). @discardableResult - public func expiresAt(_ expiresAt: Date) -> Self { - self.expiresAt = expiresAt + public func expirationTime(_ expirationTime: Date) -> Self { + self.expirationTime = expirationTime return self } @@ -150,7 +150,7 @@ public final class AccountUpdateTransaction: Transaction { case key case accountMemo case autoRenewPeriod - case expiresAt + case expirationTime case maxAutomaticTokenAssociations case stakedAccountId case stakedNodeId @@ -163,7 +163,7 @@ public final class AccountUpdateTransaction: Transaction { try container.encodeIfPresent(key, forKey: .key) try container.encodeIfPresent(accountMemo, forKey: .accountMemo) try container.encodeIfPresent(autoRenewPeriod?.wholeSeconds, forKey: .autoRenewPeriod) - try container.encodeIfPresent(expiresAt?.unixTimestampNanos, forKey: .expiresAt) + try container.encodeIfPresent(expirationTime?.unixTimestampNanos, forKey: .expirationTime) try container.encodeIfPresent(maxAutomaticTokenAssociations, forKey: .maxAutomaticTokenAssociations) try container.encodeIfPresent(stakedAccountId, forKey: .stakedAccountId) try container.encodeIfPresent(stakedNodeId, forKey: .stakedNodeId) diff --git a/Sources/Hedera/ContractCreateTransaction.swift b/Sources/Hedera/ContractCreateTransaction.swift index d4c20ded..3a63518d 100644 --- a/Sources/Hedera/ContractCreateTransaction.swift +++ b/Sources/Hedera/ContractCreateTransaction.swift @@ -28,7 +28,7 @@ public final class ContractCreateTransaction: Transaction { bytecodeFileId: FileId? = nil, adminKey: Key? = nil, gas: UInt64 = 0, - initialBalance: UInt64 = 0, + initialBalance: Hbar = 0, autoRenewPeriod: TimeInterval? = nil, constructorParameters: Data? = nil, contractMemo: String = "", @@ -99,12 +99,12 @@ public final class ContractCreateTransaction: Transaction { /// The initial balance to put into the cryptocurrency account associated with the new /// smart contract. - public var initialBalance: UInt64 + public var initialBalance: Hbar /// Sets the initial balance to put into the cryptocurrency account associated with the new /// smart contract. @discardableResult - public func initialBalance(_ initialBalance: UInt64) -> Self { + public func initialBalance(_ initialBalance: Hbar) -> Self { self.initialBalance = initialBalance return self diff --git a/Sources/Hedera/ContractExecuteTransaction.swift b/Sources/Hedera/ContractExecuteTransaction.swift index 2895a14f..bb53ea00 100644 --- a/Sources/Hedera/ContractExecuteTransaction.swift +++ b/Sources/Hedera/ContractExecuteTransaction.swift @@ -35,7 +35,7 @@ public final class ContractExecuteTransaction: Transaction { public init( contractId: ContractId? = nil, gas: UInt64 = 0, - payableAmount: UInt64 = 0, + payableAmount: Hbar = 0, functionParameters: Data? = nil ) { self.contractId = contractId @@ -67,11 +67,11 @@ public final class ContractExecuteTransaction: Transaction { } /// The number of hbars sent with this function call. - public var payableAmount: UInt64 + public var payableAmount: Hbar /// Set the number of hbars sent with this function call. @discardableResult - public func payableAmount(_ payableAmount: UInt64) -> Self { + public func payableAmount(_ payableAmount: Hbar) -> Self { self.payableAmount = payableAmount return self diff --git a/Sources/Hedera/ContractFunctionResult.swift b/Sources/Hedera/ContractFunctionResult.swift index a5007c0c..b0110e54 100644 --- a/Sources/Hedera/ContractFunctionResult.swift +++ b/Sources/Hedera/ContractFunctionResult.swift @@ -44,8 +44,7 @@ public struct ContractFunctionResult: Codable { public let gas: UInt64 /// Number of HBAR sent (the function must be payable if this is nonzero). - // TODO: Use Hbar type - public let hbarAmount: UInt64 + public let hbarAmount: Hbar /// The parameters passed into the contract call. public let contractFunctionParametersBytes: Data @@ -64,7 +63,7 @@ public struct ContractFunctionResult: Codable { bloom = Data(base64Encoded: try container.decode(String.self, forKey: .bloom))! gasUsed = try container.decode(UInt64.self, forKey: .gasUsed) gas = try container.decode(UInt64.self, forKey: .gas) - hbarAmount = try container.decode(UInt64.self, forKey: .hbarAmount) + hbarAmount = try container.decode(Hbar.self, forKey: .hbarAmount) contractFunctionParametersBytes = Data(base64Encoded: try container.decode(String.self, forKey: .contractFunctionParametersBytes))! bytes = Data(base64Encoded: try container.decode(String.self, forKey: .bytes))! senderAccountId = try container.decodeIfPresent(AccountId.self, forKey: .senderAccountId) diff --git a/Sources/Hedera/ContractInfo.swift b/Sources/Hedera/ContractInfo.swift index 17617280..5af484ad 100644 --- a/Sources/Hedera/ContractInfo.swift +++ b/Sources/Hedera/ContractInfo.swift @@ -47,9 +47,8 @@ public final class ContractInfo: Codable { /// The memo associated with the contract. public let contractMemo: String - // TODO: Use Hbar type /// The current balance, in tinybars. - public let balance: UInt64 + public let balance: Hbar /// Whether the contract has been deleted. public let isDeleted: Bool diff --git a/Sources/Hedera/EthereumTransaction.swift b/Sources/Hedera/EthereumTransaction.swift new file mode 100644 index 00000000..545ada4d --- /dev/null +++ b/Sources/Hedera/EthereumTransaction.swift @@ -0,0 +1,98 @@ +/* + * ‌ + * Hedera Swift SDK + * ​ + * Copyright (C) 2022 - 2023 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ + +import Foundation + +/// Submit an Ethereum transaction. +public final class EthereumTransaction: Transaction { + public init( + ethereumData: Data? = nil, + callDataFileId: FileId? = nil, + maxGasAllowanceHbar: UInt64 = 0 + ) { + self.ethereumData = ethereumData + self.callDataFileId = callDataFileId + self.maxGasAllowanceHbar = maxGasAllowanceHbar + } + + /// The raw Ethereum transaction (RLP encoded type 0, 1, and 2). + public var ethereumData: Data? + + /// Sets the raw Ethereum transaction (RLP encoded type 0, 1, and 2). + @discardableResult + public func ethereumData(_ ethereumData: Data) -> Self { + self.ethereumData = ethereumData + + return self + } + + /// For large transactions (for example contract create) this should be used to + /// set the FileId of an HFS file containing the callData + /// of the ethereumData. The data in the ethereumData will be re-written with + /// the callData element as a zero length string with the original contents in + /// the referenced file at time of execution. The ethereumData will need to be + /// "rehydrated" with the callData for signature validation to pass. + public var callDataFileId: FileId? + + /// Sets a file ID to find the raw Ethereum transaction (RLP encoded type 0, 1, and 2). + /// + /// For large transactions (for example contract create) this should be used to + /// set the FileId of an HFS file containing the callData + /// of the ethereumData. The data in the ethereumData will be re-written with + /// the callData element as a zero length string with the original contents in + /// the referenced file at time of execution. The ethereumData will need to be + /// "rehydrated" with the callData for signature validation to pass. + /// + @discardableResult + public func callDataFileId(_ callDataFileId: FileId) -> Self { + self.callDataFileId = callDataFileId + + return self + } + + /// The maximum amount that the payer of the hedera transaction + /// is willing to pay to complete the transaction. + public var maxGasAllowanceHbar: UInt64 + + /// Sets the maximum amount that the payer of the hedera transaction + /// is willing to pay to complete the transaction. + @discardableResult + public func maxGasAllowanceHbar(_ maxGasAllowanceHbar: UInt64) -> Self { + self.maxGasAllowanceHbar = maxGasAllowanceHbar + + return self + } + + private enum CodingKeys: String, CodingKey { + case ethereumData + case callDataFileId + case maxGasAllowanceHbar + } + + public override func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encodeIfPresent(ethereumData?.base64EncodedString(), forKey: .ethereumData) + try container.encodeIfPresent(callDataFileId, forKey: .callDataFileId) + try container.encodeIfPresent(maxGasAllowanceHbar, forKey: .maxGasAllowanceHbar) + + try super.encode(to: encoder) + } +} diff --git a/Sources/Hedera/Hbar.swift b/Sources/Hedera/Hbar.swift new file mode 100644 index 00000000..ae89e399 --- /dev/null +++ b/Sources/Hedera/Hbar.swift @@ -0,0 +1,122 @@ +/* + * ‌ + * Hedera Swift SDK + * ​ + * Copyright (C) 2022 - 2023 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ + +import Foundation + +/// Common units of hbar. +/// For the most part they follow SI prefix conventions. +public enum HbarUnit: UInt64 { + case tinybar = 1 + case microbar = 100 + case millibar = 100_000 + case hbar = 100_000_000 + case kilobar = 100_000_000_000 + case megabar = 100_000_000_000_000 + case gigabar = 100_000_000_000_000_000 +} + +public struct Hbar: LosslessStringConvertible, Codable, ExpressibleByIntegerLiteral, ExpressibleByStringLiteral, ExpressibleByFloatLiteral { + /// A constant value of zero hbars. + public static let zero: Hbar = 0 + + /// A constant value of the maximum number of hbars. + public static let max: Hbar = 50000000000 + + /// A constant value of the minimum number of hbars. + public static let min: Hbar = -50000000000 + + public static func fromTinybars(_ amount: Int64) -> Self { + Self(tinybars: amount) + } + + public init(stringLiteral value: StringLiteralType) { + self.init(value)! + } + + public init(integerLiteral value: IntegerLiteralType) { + self.init(tinybars: Int64(value)) + } + + public init(floatLiteral value: FloatLiteralType) { + try! self.init(Decimal(value)) + } + + public init?(_ description: String) { + let amount = NSDecimalNumber(string: description).decimalValue + + if (amount.isNaN) { + return nil + } + + let hbar = try? Self(amount) + + if (hbar == nil) { + return nil + } + + self = hbar! + } + + public init(from decoder: Decoder) throws { + self.init(tinybars: try decoder.singleValueContainer().decode(Int64.self)) + } + + private init(tinybars: Int64) { + self.tinybars = tinybars + } + + /// Create a new Hbar of the specified, possibly fractional value. + public init(_ amount: Decimal) throws { + self = try Self(amount, HbarUnit.hbar) + } + + /// Create a new Hbar of the specified, possibly fractional value. + public init(_ amount: Decimal, _ unit: HbarUnit) throws { + let tinybars = amount * Decimal(unit.rawValue); + + if (!(tinybars.isZero || (tinybars.isNormal && tinybars.exponent >= 0))) { + throw NSError(domain: "Amount and Unit combination results in a fractional value for tinybar. Ensure tinybar value is a whole number.", code: 0) + } + + self.tinybars = NSDecimalNumber(decimal: tinybars).int64Value + } + + private let tinybars: Int64 + + /// Convert this hbar value to a different unit. + public func to(_ unit: HbarUnit) -> Decimal { + Decimal(tinybars) / Decimal(unit.rawValue) + } + + /// Convert this hbar value to Tinybars. + public func toTinybars() -> Int64 { + tinybars + } + + public var description: String { + to(.hbar).description + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + + try container.encode(toTinybars()) + } +} diff --git a/Sources/Hedera/LedgerId.swift b/Sources/Hedera/LedgerId.swift new file mode 100644 index 00000000..948b03f8 --- /dev/null +++ b/Sources/Hedera/LedgerId.swift @@ -0,0 +1,76 @@ +/* + * ‌ + * Hedera Swift SDK + * ​ + * Copyright (C) 2022 - 2023 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ + +import Foundation + +public struct LedgerId: Equatable, Codable, CustomStringConvertible { + public static let mainnet = LedgerId(Data([0])) + + public static let testnet = LedgerId(Data([1])) + + public static let previewnet = LedgerId(Data([2])) + + public init(_ bytes: Data) { + self.bytes = bytes + } + + public init(from decoder: Decoder) throws { + self.init(try decoder.singleValueContainer().decode(String.self))! + } + + public init?(_ description: String) { + let bytes = Data(base64Encoded: description) + + if (bytes == nil) { + return nil + } + + self.bytes = bytes! + } + + private let bytes: Data + + public func isMainnet() -> Bool { + self == Self.mainnet + } + + public func isTestnet() -> Bool { + self == Self.testnet + } + + public func isPreviewnet() -> Bool { + self == Self.previewnet + } + + public static func ==(lhs: Self, rhs: Self) -> Bool { + lhs.bytes == rhs.bytes + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + + try container.encode(String(describing: self)) + } + + public var description: String { + bytes.base64EncodedString() + } + +} diff --git a/Sources/Hedera/PaymentTransaction.swift b/Sources/Hedera/PaymentTransaction.swift index 884edb8f..ccc64461 100644 --- a/Sources/Hedera/PaymentTransaction.swift +++ b/Sources/Hedera/PaymentTransaction.swift @@ -22,9 +22,9 @@ import Foundation internal final class PaymentTransaction: Codable { internal var nodeAccountIds: [AccountId]? - internal var amount: UInt64? - internal var maxAmount: UInt64? - internal var maxTransactionFee: UInt64? + internal var amount: Hbar? + internal var maxAmount: Hbar? + internal var maxTransactionFee: Hbar? internal var transactionMemo: String? internal var payerAccountId: AccountId? internal var transactionId: String? diff --git a/Sources/Hedera/Query.swift b/Sources/Hedera/Query.swift index 3e99234f..de34d8c2 100644 --- a/Sources/Hedera/Query.swift +++ b/Sources/Hedera/Query.swift @@ -45,8 +45,7 @@ public class Query: Request { /// The client will submit exactly this amount for the payment of this query. Hedera /// will not return any remainder (over the actual cost for this query). /// - // TODO: Use Hbar - public func paymentAmount(_ amount: UInt64) -> Self { + public func paymentAmount(_ amount: Hbar) -> Self { self.payment.amount = amount return self @@ -65,8 +64,7 @@ public class Query: Request { /// /// Set to `None` to allow unlimited payment amounts. /// - // TODO: Use Hbar - public func maxPaymentAmount(_ maxAmount: UInt64?) -> Self { + public func maxPaymentAmount(_ maxAmount: Hbar?) -> Self { self.payment.maxAmount = maxAmount return self @@ -87,8 +85,7 @@ public class Query: Request { /// /// Defaults to 1 hbar. /// - // TODO: Use Hbar - public func maxPaymentTransactionFee(_ maxPaymentTransactionFee: UInt64) -> Self { + public func maxPaymentTransactionFee(_ maxPaymentTransactionFee: Hbar) -> Self { self.payment.maxTransactionFee = maxPaymentTransactionFee return self diff --git a/Sources/Hedera/StakingInfo.swift b/Sources/Hedera/StakingInfo.swift new file mode 100644 index 00000000..6860edf2 --- /dev/null +++ b/Sources/Hedera/StakingInfo.swift @@ -0,0 +1,62 @@ +/* + * ‌ + * Hedera Swift SDK + * ​ + * Copyright (C) 2022 - 2023 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ + +import Foundation + +public struct StakingInfo: Codable { + /// If true, the contract declines receiving a staking reward. The default value is false. + public let declineStakingReward: Bool + + /// The staking period during which either the staking settings for this account or contract changed (such as starting + /// staking or changing staked_node_id) or the most recent reward was earned, whichever is later. If this account or contract + /// is not currently staked to a node, then this field is not set. + public let stakePeriodStart: Date? + + /// The amount in Hbar that will be received in the next reward situation. + public let pendingReward: Hbar + + /// The total of balance of all accounts staked to this account or contract. + public let stakedToMe: Hbar + + /// The account to which this account or contract is staking. + public let stakedAccountId: AccountId? + + /// The ID of the node this account or contract is staked to. + public let stakedNodeId: UInt64? + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + declineStakingReward = try container.decode(Bool.self, forKey: .declineStakingReward) + + let stakePeriodStartNanos = try container.decodeIfPresent(UInt64.self, forKey: .stakePeriodStart) + + if (stakePeriodStartNanos != nil) { + stakePeriodStart = Date(unixTimestampNanos: stakePeriodStartNanos!) + } else { + stakePeriodStart = nil + } + + pendingReward = try container.decode(Hbar.self, forKey: .pendingReward) + stakedToMe = try container.decode(Hbar.self, forKey: .stakedToMe) + stakedAccountId = try container.decodeIfPresent(AccountId.self, forKey: .stakedAccountId) + stakedNodeId = try container.decodeIfPresent(UInt64.self, forKey: .stakedNodeId) + } +} diff --git a/Sources/Hedera/TransactionRecord.swift b/Sources/Hedera/TransactionRecord.swift index efc255b5..855a7306 100644 --- a/Sources/Hedera/TransactionRecord.swift +++ b/Sources/Hedera/TransactionRecord.swift @@ -43,7 +43,7 @@ public struct TransactionRecord: Codable { public let transactionMemo: String /// The actual transaction fee charged. - public let transactionFee: UInt64 + public let transactionFee: Hbar /// Reference to the scheduled transaction ID that this transaction record represents. public let scheduleRef: ScheduleId? @@ -79,7 +79,7 @@ public struct TransactionRecord: Codable { consensusTimestamp = Date(unixTimestampNanos: try container.decode(UInt64.self, forKey: .consensusTimestamp)) transactionId = try container.decode(String.self, forKey: .transactionId) transactionMemo = try container.decode(String.self, forKey: .transactionMemo) - transactionFee = try container.decode(UInt64.self, forKey: .transactionFee) + transactionFee = try container.decode(Hbar.self, forKey: .transactionFee) scheduleRef = try container.decodeIfPresent(ScheduleId.self, forKey: .scheduleRef) automaticTokenAssociations = try container.decode([TokenAssociation].self, forKey: .automaticTokenAssociations)