diff --git a/Examples/ModifyTokenKeys/main.swift b/Examples/ModifyTokenKeys/main.swift new file mode 100644 index 00000000..1802466c --- /dev/null +++ b/Examples/ModifyTokenKeys/main.swift @@ -0,0 +1,166 @@ +/* + * ‌ + * Hedera Swift SDK + * + * Copyright (C) 2022 - 2024 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 +import Hedera +import SwiftDotenv + +@main +internal enum Program { + internal static func main() async throws { + let env = try Dotenv.load() + let client = try Client.forName(env.networkName) + + // Defaults the operator account ID and key such that all generated transactions will be paid for + // by this account and be signed by this key + client.setOperator(env.operatorAccountId, env.operatorKey) + + // Generate a higher-privileged key. + let adminKey = PrivateKey.generateEd25519() + + // Generate the lower-privileged keys that will be modified. + // Note: Lower-privileged keys are Wipe, Supply, and updated Supply key.. + let supplyKey = PrivateKey.generateEd25519() + let wipeKey = PrivateKey.generateEd25519() + let newSupplyKey = PrivateKey.generateEd25519() + + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Create an NFT token with admin, wipe, and supply key. + let tokenId = try await TokenCreateTransaction() + .name("Example NFT") + .symbol("ENFT") + .tokenType(TokenType.nonFungibleUnique) + .treasuryAccountId(env.operatorAccountId) + .adminKey(.single(adminKey.publicKey)) + .wipeKey(.single(wipeKey.publicKey)) + .supplyKey(.single(supplyKey.publicKey)) + .expirationTime(Timestamp.now + .minutes(5)) + .freezeWith(client) + .sign(adminKey) + .execute(client) + .getReceipt(client) + .tokenId! + + let tokenInfo = try await TokenInfoQuery() + .tokenId(tokenId) + .execute(client) + + print("Admin Key: \(tokenInfo.adminKey!)") + print("Wipe Key: \(tokenInfo.wipeKey!)") + print("Supply Key: \(tokenInfo.supplyKey!)") + + print("------------------------------------") + print("Removing Wipe Key...") + + // Remove the wipe key with empty Keylist, signing with the admin key. + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.keyList([])) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(client) + .sign(adminKey) + .execute(client) + .getReceipt(client) + + let tokenInfoAfterWipeKeyUpdate = try await TokenInfoQuery() + .tokenId(tokenId) + .execute(client) + + print("Wipe Key (after removal): \(String(describing: tokenInfoAfterWipeKeyUpdate.wipeKey))") + print("------------------------------------") + print("Removing Admin Key...") + + // Remove the admin key with empty Keylist, signing with the admin key. + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.keyList([])) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(client) + .sign(adminKey) + .execute(client) + .getReceipt(client) + + let tokenInfoAfterAdminKeyUpdate = try await TokenInfoQuery() + .tokenId(tokenId) + .execute(client) + + print("Admin Key (after removal): \(String(describing:tokenInfoAfterAdminKeyUpdate.adminKey))") + + print("------------------------------------") + print("Update Supply Key...") + + // Update the supply key with a new key, signing with the old supply key and the new supply key. + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(newSupplyKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(client) + .sign(supplyKey) + .sign(newSupplyKey) + .execute(client) + .getReceipt(client) + + let tokenInfoAfterSupplyKeyUpdate = try await TokenInfoQuery() + .tokenId(tokenId) + .execute(client) + + print("Supply Key (after update): \(String(describing: tokenInfoAfterSupplyKeyUpdate.supplyKey))") + + print("------------------------------------") + print("Removing Supply Key...") + + // Remove the supply key with unusable key, signing with the new supply key. + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(client) + .sign(newSupplyKey) + .execute(client) + .getReceipt(client) + + let tokenInfoAfterSupplyKeyRemoval = try await TokenInfoQuery() + .tokenId(tokenId) + .execute(client) + + print("Supply Key (after removal): \(String(describing: tokenInfoAfterSupplyKeyRemoval.supplyKey))") + } +} + +extension Environment { + /// Account ID for the operator to use in this example. + internal var operatorAccountId: AccountId { + AccountId(self["OPERATOR_ID"]!.stringValue)! + } + + /// Private key for the operator to use in this example. + internal var operatorKey: PrivateKey { + PrivateKey(self["OPERATOR_KEY"]!.stringValue)! + } + + /// The name of the hedera network this example should be ran against. + /// + /// Testnet by default. + internal var networkName: String { + self["HEDERA_NETWORK"]?.stringValue ?? "testnet" + } +} diff --git a/Package.swift b/Package.swift index ed658597..4e5ccdfd 100644 --- a/Package.swift +++ b/Package.swift @@ -44,6 +44,7 @@ let exampleTargets = [ "GetAddressBook", "GetExchangeRates", "GetFileContents", + "ModifyTokenKeys", "MultiAppTransfer", "MultiSigOffline", "Prng", @@ -130,7 +131,7 @@ let package = Package( // .unsafeFlags(["-Xfrontend", "-warn-concurrency", "-Xfrontend", "-enable-actor-data-race-checks"]) // ] ), - .target( + .executableTarget( name: "HederaTCK", dependencies: [ "Hedera", diff --git a/README.md b/README.md index 47fef15c..f5aea348 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,14 @@ protoc protoc-gen-swift (from https://github.com/apple/swift-protobuf) protoc-gen-grpc-swift (from https://github.com/grpc/grpc-swift) +### Fetch Submodule (Hedera-Protobufs) +Update [\protobuf](https://github.com/hashgraph/hedera-protobufs) submodule to latest changes. +```bash +git submodule update --recursive --remote +``` + ### Generate services + ```bash # cwd: `$REPO` protoc --swift_opt=Visibility=Public --swift_opt=FileNaming=PathToUnderscores --swift_out=./Sources/HederaProtobufs/Services --proto_path=./protobufs/services protobufs/services/**.proto diff --git a/Sources/Hedera/AnyTransaction.swift b/Sources/Hedera/AnyTransaction.swift index a271e822..f14d80b8 100644 --- a/Sources/Hedera/AnyTransaction.swift +++ b/Sources/Hedera/AnyTransaction.swift @@ -295,11 +295,13 @@ extension ServicesTransactionDataList: TryFromProtobuf { case .scheduleSign(let data): value = .scheduleSign([data]) case .utilPrng(let data): value = .prng([data]) case .tokenUpdateNfts(let data): value = .tokenUpdateNfts([data]) - case .cryptoAddLiveHash: throw HError.fromProtobuf("Unsupported transaction `AddLiveHashTransaction`") case .cryptoDeleteLiveHash: throw HError.fromProtobuf("Unsupported transaction `DeleteLiveHashTransaction`") case .uncheckedSubmit: throw HError.fromProtobuf("Unsupported transaction `UncheckedSubmitTransaction`") case .nodeStakeUpdate: throw HError.fromProtobuf("Unsupported transaction `NodeStakeUpdateTransaction`") + case .nodeDelete: throw HError.fromProtobuf("Unsupported transaction `NodeDeleteTransaction`") + case .nodeCreate: throw HError.fromProtobuf("Unsupported transaction `NodeCreateTransaction`") + case .nodeUpdate: throw HError.fromProtobuf("Unsupported transaction `NodeUpdateTransaction`") } for transaction in iter { diff --git a/Sources/Hedera/FeeSchedule/FeeDataType.swift b/Sources/Hedera/FeeSchedule/FeeDataType.swift index cbb24906..716e2ede 100644 --- a/Sources/Hedera/FeeSchedule/FeeDataType.swift +++ b/Sources/Hedera/FeeSchedule/FeeDataType.swift @@ -54,7 +54,7 @@ extension FeeDataType: TryProtobufCodable { case .tokenFungibleCommonWithCustomFees: self = .tokenFungibleCommonWithCustomFees case .tokenNonFungibleUniqueWithCustomFees: self = .tokenNonFungibleUniqueWithCustomFees case .scheduleCreateContractCall: self = .scheduleCreateContractCall - case .unrecognized(let code): + case .UNRECOGNIZED(let code): throw HError.fromProtobuf("unrecognized FeeDataType `\(code)`") } } diff --git a/Sources/Hedera/FeeSchedule/RequestType.swift b/Sources/Hedera/FeeSchedule/RequestType.swift index f8f823b2..57cbf914 100644 --- a/Sources/Hedera/FeeSchedule/RequestType.swift +++ b/Sources/Hedera/FeeSchedule/RequestType.swift @@ -247,6 +247,18 @@ public enum RequestType { /// Update a Non-Fungible token. case tokenUpdateNfts + /// Create a node + case nodeCreate + + /// Update a node + case nodeUpdate + + /// Delete a node + case nodeDelete + + /// Get the info for a node + case nodeGetInfo + // this literally can't be smaller. // swiftlint:disable:next function_body_length internal init?(protobuf proto: Proto_HederaFunctionality) throws { @@ -324,10 +336,14 @@ public enum RequestType { case .ethereumTransaction: self = .ethereumTransaction case .nodeStakeUpdate: self = .nodeStakeUpdate case .utilPrng: self = .utilPrng - case .transactionGetFastRecord: self = .tokenUpdateNfts - + case .transactionGetFastRecord: self = .transactionGetFastRecord case .tokenUpdateNfts: self = .tokenUpdateNfts - case .unrecognized(let code): + case .nodeCreate: self = .nodeCreate + case .nodeDelete: self = .nodeDelete + case .nodeUpdate: self = .nodeUpdate + case .nodeGetInfo: self = .nodeGetInfo + + case .UNRECOGNIZED(let code): throw HError.fromProtobuf("unrecognized RequestType: `\(code)`") } } @@ -408,6 +424,10 @@ public enum RequestType { case .utilPrng: return .utilPrng case .transactionGetFastRecord: return .transactionGetFastRecord case .tokenUpdateNfts: return .tokenUpdateNfts + case .nodeCreate: return .nodeCreate + case .nodeUpdate: return .nodeUpdate + case .nodeDelete: return .nodeDelete + case .nodeGetInfo: return .nodeGetInfo } } } diff --git a/Sources/Hedera/FreezeType.swift b/Sources/Hedera/FreezeType.swift index 9386ee9a..3cabaccd 100644 --- a/Sources/Hedera/FreezeType.swift +++ b/Sources/Hedera/FreezeType.swift @@ -61,7 +61,7 @@ extension FreezeType: TryProtobufCodable { case .freezeUpgrade: self = .freezeUpgrade case .freezeAbort: self = .freezeAbort case .telemetryUpgrade: self = .telemetryUpgrade - case .unrecognized(let value): throw HError.fromProtobuf("unrecognized FreezeType: `\(value)`") + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("unrecognized FreezeType: `\(value)`") } } diff --git a/Sources/Hedera/Schedule/ScheduleInfo.swift b/Sources/Hedera/Schedule/ScheduleInfo.swift index b2c129ce..ba995c2a 100644 --- a/Sources/Hedera/Schedule/ScheduleInfo.swift +++ b/Sources/Hedera/Schedule/ScheduleInfo.swift @@ -112,6 +112,9 @@ public struct ScheduleInfo: Sendable { case .scheduleDelete(let data): proto.data = .scheduleDelete(data) case .utilPrng(let data): proto.data = .utilPrng(data) case .tokenUpdateNfts(let data): proto.data = .tokenUpdateNfts(data) + case .nodeCreate(let data): proto.data = .nodeCreate(data) + case .nodeUpdate(let data): proto.data = .nodeUpdate(data) + case .nodeDelete(let data): proto.data = .nodeDelete(data) case nil: break } diff --git a/Sources/Hedera/Token/TokenInfo.swift b/Sources/Hedera/Token/TokenInfo.swift index 41a29ebd..d9efb7d0 100644 --- a/Sources/Hedera/Token/TokenInfo.swift +++ b/Sources/Hedera/Token/TokenInfo.swift @@ -145,7 +145,7 @@ extension TokenInfo: TryProtobufCodable { defaultFreezeStatus = true case .unfrozen: defaultFreezeStatus = false - case .unrecognized(let value): + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("Unrecognized defaultFreezeStatus: `\(value)`") } @@ -157,7 +157,7 @@ extension TokenInfo: TryProtobufCodable { defaultKycStatus = true case .revoked: defaultKycStatus = false - case .unrecognized(let value): + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("Unrecognized defaultKycStatus: `\(value)`") } @@ -175,7 +175,7 @@ extension TokenInfo: TryProtobufCodable { pauseStatus = true case .unpaused: pauseStatus = false - case .unrecognized(let value): + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("Unrecognized pauseStatus: `\(value)`") } diff --git a/Sources/Hedera/Token/TokenKeyValidation.swift b/Sources/Hedera/Token/TokenKeyValidation.swift new file mode 100644 index 00000000..efb6d4a2 --- /dev/null +++ b/Sources/Hedera/Token/TokenKeyValidation.swift @@ -0,0 +1,54 @@ +/* + * ‌ + * Hedera Swift SDK + * ​ + * Copyright (C) 2022 - 2024 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 +import HederaProtobufs + +public enum TokenKeyValidation { + /// Currently the default behaviour. It will perform all token key validations. + case fullValidation + /// Perform no validations at all for all passed token keys. + case noValidation + /// The passed token key is not recognized. + case unrecognized(Int) +} + +extension TokenKeyValidation: TryFromProtobuf { + internal typealias Protobuf = Proto_TokenKeyValidation + + internal init(protobuf proto: Protobuf) throws { + switch proto { + case .fullValidation: self = .fullValidation + case .noValidation: self = .noValidation + case .UNRECOGNIZED(let value): self = .unrecognized(value) + } + } + + func toProtobuf() -> Protobuf { + switch self { + case .fullValidation: + return .fullValidation + case .noValidation: + return .noValidation + case .unrecognized(let value): + return .UNRECOGNIZED(value) + } + } +} diff --git a/Sources/Hedera/Token/TokenSupplyType.swift b/Sources/Hedera/Token/TokenSupplyType.swift index 825ebed5..2b006d0b 100644 --- a/Sources/Hedera/Token/TokenSupplyType.swift +++ b/Sources/Hedera/Token/TokenSupplyType.swift @@ -41,7 +41,7 @@ extension TokenSupplyType: TryProtobufCodable { self = .infinite case .finite: self = .finite - case .unrecognized(let value): + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("unrecognized TokenSupplyType: `\(value)`") } } diff --git a/Sources/Hedera/Token/TokenType.swift b/Sources/Hedera/Token/TokenType.swift index ccbcbda6..bb69947c 100644 --- a/Sources/Hedera/Token/TokenType.swift +++ b/Sources/Hedera/Token/TokenType.swift @@ -49,7 +49,7 @@ extension TokenType: TryProtobufCodable { switch proto { case .fungibleCommon: self = .fungibleCommon case .nonFungibleUnique: self = .nonFungibleUnique - case .unrecognized(let value): + case .UNRECOGNIZED(let value): throw HError.fromProtobuf("unrecognized token type \(value)") } } diff --git a/Sources/Hedera/Token/TokenUpdateTransaction.swift b/Sources/Hedera/Token/TokenUpdateTransaction.swift index 19ebecf8..af37d546 100644 --- a/Sources/Hedera/Token/TokenUpdateTransaction.swift +++ b/Sources/Hedera/Token/TokenUpdateTransaction.swift @@ -42,8 +42,9 @@ public final class TokenUpdateTransaction: Transaction { tokenMemo: String? = nil, feeScheduleKey: Key? = nil, pauseKey: Key? = nil, - metadata: Data = .init(), - metadataKey: Key? = nil + metadata: Data? = nil, + metadataKey: Key? = nil, + keyVerificationMode: TokenKeyValidation = .fullValidation ) { self.tokenId = tokenId self.tokenName = tokenName @@ -62,6 +63,7 @@ public final class TokenUpdateTransaction: Transaction { self.pauseKey = pauseKey self.metadata = metadata self.metadataKey = metadataKey + self.keyVerificationMode = keyVerificationMode super.init() } @@ -84,6 +86,7 @@ public final class TokenUpdateTransaction: Transaction { self.pauseKey = data.hasPauseKey ? try .fromProtobuf(data.pauseKey) : nil self.metadata = data.hasMetadata ? data.metadata.value : nil ?? Data.init() self.metadataKey = data.hasMetadataKey ? try .fromProtobuf(data.metadataKey) : nil + self.keyVerificationMode = try .fromProtobuf(data.keyVerificationMode) try super.init(protobuf: proto) } @@ -323,7 +326,7 @@ public final class TokenUpdateTransaction: Transaction { } /// Returns the new metadata of the created token definition. - public var metadata: Data { + public var metadata: Data? { willSet { ensureNotFrozen() } @@ -352,6 +355,21 @@ public final class TokenUpdateTransaction: Transaction { return self } + /// Returns the new key which can change the metadata of a token. + public var keyVerificationMode: TokenKeyValidation { + willSet { + ensureNotFrozen() + } + } + + /// Sets the new key which can change the metadata of a token. + @discardableResult + public func keyVerificationMode(_ keyVerificationMode: TokenKeyValidation) -> Self { + self.keyVerificationMode = keyVerificationMode + + return self + } + internal override func validateChecksums(on ledgerId: LedgerId) throws { try tokenId?.validateChecksums(on: ledgerId) try treasuryAccountId?.validateChecksums(on: ledgerId) @@ -391,11 +409,15 @@ extension TokenUpdateTransaction: ToProtobuf { expirationTime?.toProtobufInto(&proto.expiry) feeScheduleKey?.toProtobufInto(&proto.feeScheduleKey) pauseKey?.toProtobufInto(&proto.pauseKey) - proto.metadata = Google_Protobuf_BytesValue(metadata) metadataKey?.toProtobufInto(&proto.metadataKey) + proto.keyVerificationMode = keyVerificationMode.toProtobuf() if let tokenMemo = tokenMemo { proto.memo = .init(tokenMemo) } + if let metadata = metadata { + proto.metadata = Google_Protobuf_BytesValue(metadata) + } + } } } diff --git a/Sources/HederaProtobufs/Services/address_book_service.pb.swift b/Sources/HederaProtobufs/Services/address_book_service.pb.swift new file mode 100644 index 00000000..428f34f5 --- /dev/null +++ b/Sources/HederaProtobufs/Services/address_book_service.pb.swift @@ -0,0 +1,21 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: address_book_service.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} diff --git a/Sources/HederaProtobufs/Services/basic_types.pb.swift b/Sources/HederaProtobufs/Services/basic_types.pb.swift index 987e61a3..ae694152 100644 --- a/Sources/HederaProtobufs/Services/basic_types.pb.swift +++ b/Sources/HederaProtobufs/Services/basic_types.pb.swift @@ -39,7 +39,7 @@ public enum Proto_TokenType: SwiftProtobuf.Enum { /// Unique, not interchangeable with other tokens of the same type as they typically have /// different values. Individually traced and can carry unique properties (e.g. serial number). case nonFungibleUnique // = 1 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .fungibleCommon @@ -49,7 +49,7 @@ public enum Proto_TokenType: SwiftProtobuf.Enum { switch rawValue { case 0: self = .fungibleCommon case 1: self = .nonFungibleUnique - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -57,7 +57,7 @@ public enum Proto_TokenType: SwiftProtobuf.Enum { switch self { case .fungibleCommon: return 0 case .nonFungibleUnique: return 1 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -66,7 +66,7 @@ public enum Proto_TokenType: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_TokenType: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_TokenType] = [ .fungibleCommon, .nonFungibleUnique, @@ -113,7 +113,7 @@ public enum Proto_SubType: SwiftProtobuf.Enum { ///* /// The resource prices are scoped to a ScheduleCreate containing a ContractCall. case scheduleCreateContractCall // = 5 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .default @@ -127,7 +127,7 @@ public enum Proto_SubType: SwiftProtobuf.Enum { case 3: self = .tokenFungibleCommonWithCustomFees case 4: self = .tokenNonFungibleUniqueWithCustomFees case 5: self = .scheduleCreateContractCall - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -139,7 +139,7 @@ public enum Proto_SubType: SwiftProtobuf.Enum { case .tokenFungibleCommonWithCustomFees: return 3 case .tokenNonFungibleUniqueWithCustomFees: return 4 case .scheduleCreateContractCall: return 5 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -148,7 +148,7 @@ public enum Proto_SubType: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_SubType: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_SubType] = [ .default, .tokenFungibleCommon, @@ -175,7 +175,7 @@ public enum Proto_TokenSupplyType: SwiftProtobuf.Enum { /// Indicates that tokens of that type have an upper bound of maxSupply, /// provided on token creation. case finite // = 1 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .infinite @@ -185,7 +185,7 @@ public enum Proto_TokenSupplyType: SwiftProtobuf.Enum { switch rawValue { case 0: self = .infinite case 1: self = .finite - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -193,7 +193,7 @@ public enum Proto_TokenSupplyType: SwiftProtobuf.Enum { switch self { case .infinite: return 0 case .finite: return 1 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -202,7 +202,7 @@ public enum Proto_TokenSupplyType: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_TokenSupplyType: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_TokenSupplyType] = [ .infinite, .finite, @@ -211,6 +211,54 @@ extension Proto_TokenSupplyType: CaseIterable { #endif // swift(>=4.2) +///* +/// Types of validation strategies for token keys. +public enum Proto_TokenKeyValidation: SwiftProtobuf.Enum { + public typealias RawValue = Int + + ///* + /// Currently the default behaviour. It will perform all token key validations. + case fullValidation // = 0 + + ///* + /// Perform no validations at all for all passed token keys. + case noValidation // = 1 + case UNRECOGNIZED(Int) + + public init() { + self = .fullValidation + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .fullValidation + case 1: self = .noValidation + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .fullValidation: return 0 + case .noValidation: return 1 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Proto_TokenKeyValidation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Proto_TokenKeyValidation] = [ + .fullValidation, + .noValidation, + ] +} + +#endif // swift(>=4.2) + ///* /// Possible Freeze statuses returned on TokenGetInfoQuery or CryptoGetInfoResponse in /// TokenRelationship @@ -228,7 +276,7 @@ public enum Proto_TokenFreezeStatus: SwiftProtobuf.Enum { ///* /// UNDOCUMENTED case unfrozen // = 2 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .freezeNotApplicable @@ -239,7 +287,7 @@ public enum Proto_TokenFreezeStatus: SwiftProtobuf.Enum { case 0: self = .freezeNotApplicable case 1: self = .frozen case 2: self = .unfrozen - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -248,7 +296,7 @@ public enum Proto_TokenFreezeStatus: SwiftProtobuf.Enum { case .freezeNotApplicable: return 0 case .frozen: return 1 case .unfrozen: return 2 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -257,7 +305,7 @@ public enum Proto_TokenFreezeStatus: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_TokenFreezeStatus: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_TokenFreezeStatus] = [ .freezeNotApplicable, .frozen, @@ -283,7 +331,7 @@ public enum Proto_TokenKycStatus: SwiftProtobuf.Enum { ///* /// UNDOCUMENTED case revoked // = 2 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .kycNotApplicable @@ -294,7 +342,7 @@ public enum Proto_TokenKycStatus: SwiftProtobuf.Enum { case 0: self = .kycNotApplicable case 1: self = .granted case 2: self = .revoked - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -303,7 +351,7 @@ public enum Proto_TokenKycStatus: SwiftProtobuf.Enum { case .kycNotApplicable: return 0 case .granted: return 1 case .revoked: return 2 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -312,7 +360,7 @@ public enum Proto_TokenKycStatus: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_TokenKycStatus: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_TokenKycStatus] = [ .kycNotApplicable, .granted, @@ -338,7 +386,7 @@ public enum Proto_TokenPauseStatus: SwiftProtobuf.Enum { ///* /// Indicates that a Token is Unpaused. case unpaused // = 2 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .pauseNotApplicable @@ -349,7 +397,7 @@ public enum Proto_TokenPauseStatus: SwiftProtobuf.Enum { case 0: self = .pauseNotApplicable case 1: self = .paused case 2: self = .unpaused - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -358,7 +406,7 @@ public enum Proto_TokenPauseStatus: SwiftProtobuf.Enum { case .pauseNotApplicable: return 0 case .paused: return 1 case .unpaused: return 2 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -367,7 +415,7 @@ public enum Proto_TokenPauseStatus: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_TokenPauseStatus: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_TokenPauseStatus] = [ .pauseNotApplicable, .paused, @@ -680,7 +728,23 @@ public enum Proto_HederaFunctionality: SwiftProtobuf.Enum { ///* /// Update the metadata of one or more NFT's of a specific token type. case tokenUpdateNfts // = 88 - case unrecognized(Int) + + ///* + /// Create a node + case nodeCreate // = 89 + + ///* + /// Update a node + case nodeUpdate // = 90 + + ///* + /// Delete a node + case nodeDelete // = 91 + + ///* + /// Get Node information + case nodeGetInfo // = 92 + case UNRECOGNIZED(Int) public init() { self = .none @@ -763,7 +827,11 @@ public enum Proto_HederaFunctionality: SwiftProtobuf.Enum { case 86: self = .utilPrng case 87: self = .transactionGetFastRecord case 88: self = .tokenUpdateNfts - default: self = .unrecognized(rawValue) + case 89: self = .nodeCreate + case 90: self = .nodeUpdate + case 91: self = .nodeDelete + case 92: self = .nodeGetInfo + default: self = .UNRECOGNIZED(rawValue) } } @@ -844,7 +912,11 @@ public enum Proto_HederaFunctionality: SwiftProtobuf.Enum { case .utilPrng: return 86 case .transactionGetFastRecord: return 87 case .tokenUpdateNfts: return 88 - case .unrecognized(let i): return i + case .nodeCreate: return 89 + case .nodeUpdate: return 90 + case .nodeDelete: return 91 + case .nodeGetInfo: return 92 + case .UNRECOGNIZED(let i): return i } } @@ -853,7 +925,7 @@ public enum Proto_HederaFunctionality: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_HederaFunctionality: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_HederaFunctionality] = [ .none, .cryptoTransfer, @@ -930,6 +1002,10 @@ extension Proto_HederaFunctionality: CaseIterable { .utilPrng, .transactionGetFastRecord, .tokenUpdateNfts, + .nodeCreate, + .nodeUpdate, + .nodeDelete, + .nodeGetInfo, ] } @@ -2379,6 +2455,12 @@ public struct Proto_ServiceEndpoint { /// The port of the node public var port: Int32 = 0 + ///* + /// A node domain name + /// This MUST be the fully qualified domain name of the node. + /// This value MUST NOT be more than 253 characters. + public var domainName: String = String() + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -2797,6 +2879,7 @@ public struct Proto_StakingInfo { extension Proto_TokenType: @unchecked Sendable {} extension Proto_SubType: @unchecked Sendable {} extension Proto_TokenSupplyType: @unchecked Sendable {} +extension Proto_TokenKeyValidation: @unchecked Sendable {} extension Proto_TokenFreezeStatus: @unchecked Sendable {} extension Proto_TokenKycStatus: @unchecked Sendable {} extension Proto_TokenPauseStatus: @unchecked Sendable {} @@ -2877,6 +2960,13 @@ extension Proto_TokenSupplyType: SwiftProtobuf._ProtoNameProviding { ] } +extension Proto_TokenKeyValidation: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "FULL_VALIDATION"), + 1: .same(proto: "NO_VALIDATION"), + ] +} + extension Proto_TokenFreezeStatus: SwiftProtobuf._ProtoNameProviding { public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "FreezeNotApplicable"), @@ -2978,6 +3068,10 @@ extension Proto_HederaFunctionality: SwiftProtobuf._ProtoNameProviding { 86: .same(proto: "UtilPrng"), 87: .same(proto: "TransactionGetFastRecord"), 88: .same(proto: "TokenUpdateNfts"), + 89: .same(proto: "NodeCreate"), + 90: .same(proto: "NodeUpdate"), + 91: .same(proto: "NodeDelete"), + 92: .same(proto: "NodeGetInfo"), ] } @@ -4407,7 +4501,15 @@ extension Proto_FeeData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa var _servicedata: Proto_FeeComponents? = nil var _subType: Proto_SubType = .default - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} @@ -4573,6 +4675,7 @@ extension Proto_ServiceEndpoint: SwiftProtobuf.Message, SwiftProtobuf._MessageIm public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "ipAddressV4"), 2: .same(proto: "port"), + 3: .standard(proto: "domain_name"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -4583,6 +4686,7 @@ extension Proto_ServiceEndpoint: SwiftProtobuf.Message, SwiftProtobuf._MessageIm switch fieldNumber { case 1: try { try decoder.decodeSingularBytesField(value: &self.ipAddressV4) }() case 2: try { try decoder.decodeSingularInt32Field(value: &self.port) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.domainName) }() default: break } } @@ -4595,12 +4699,16 @@ extension Proto_ServiceEndpoint: SwiftProtobuf.Message, SwiftProtobuf._MessageIm if self.port != 0 { try visitor.visitSingularInt32Field(value: self.port, fieldNumber: 2) } + if !self.domainName.isEmpty { + try visitor.visitSingularStringField(value: self.domainName, fieldNumber: 3) + } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Proto_ServiceEndpoint, rhs: Proto_ServiceEndpoint) -> Bool { if lhs.ipAddressV4 != rhs.ipAddressV4 {return false} if lhs.port != rhs.port {return false} + if lhs.domainName != rhs.domainName {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Sources/HederaProtobufs/Services/consensus_get_topic_info.pb.swift b/Sources/HederaProtobufs/Services/consensus_get_topic_info.pb.swift index b70b8a98..a8b9f907 100644 --- a/Sources/HederaProtobufs/Services/consensus_get_topic_info.pb.swift +++ b/Sources/HederaProtobufs/Services/consensus_get_topic_info.pb.swift @@ -169,7 +169,15 @@ extension Proto_ConsensusGetTopicInfoResponse: SwiftProtobuf.Message, SwiftProto var _topicID: Proto_TopicID? = nil var _topicInfo: Proto_ConsensusTopicInfo? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/contract_call_local.pb.swift b/Sources/HederaProtobufs/Services/contract_call_local.pb.swift index de574c0d..a4ead51e 100644 --- a/Sources/HederaProtobufs/Services/contract_call_local.pb.swift +++ b/Sources/HederaProtobufs/Services/contract_call_local.pb.swift @@ -435,7 +435,15 @@ extension Proto_ContractFunctionResult: SwiftProtobuf.Message, SwiftProtobuf._Me var _contractNonces: [Proto_ContractNonceInfo] = [] var _signerNonce: SwiftProtobuf.Google_Protobuf_Int64Value? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/contract_create.pb.swift b/Sources/HederaProtobufs/Services/contract_create.pb.swift index 85661955..341d8b12 100644 --- a/Sources/HederaProtobufs/Services/contract_create.pb.swift +++ b/Sources/HederaProtobufs/Services/contract_create.pb.swift @@ -389,7 +389,15 @@ extension Proto_ContractCreateTransactionBody: SwiftProtobuf.Message, SwiftProto var _stakedID: Proto_ContractCreateTransactionBody.OneOf_StakedID? var _declineReward: Bool = false - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/contract_get_info.pb.swift b/Sources/HederaProtobufs/Services/contract_get_info.pb.swift index 819c1fc3..2def1dc8 100644 --- a/Sources/HederaProtobufs/Services/contract_get_info.pb.swift +++ b/Sources/HederaProtobufs/Services/contract_get_info.pb.swift @@ -387,7 +387,15 @@ extension Proto_ContractGetInfoResponse.ContractInfo: SwiftProtobuf.Message, Swi var _maxAutomaticTokenAssociations: Int32 = 0 var _stakingInfo: Proto_StakingInfo? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/contract_update.pb.swift b/Sources/HederaProtobufs/Services/contract_update.pb.swift index 690cce3f..c38c34b2 100644 --- a/Sources/HederaProtobufs/Services/contract_update.pb.swift +++ b/Sources/HederaProtobufs/Services/contract_update.pb.swift @@ -313,7 +313,15 @@ extension Proto_ContractUpdateTransactionBody: SwiftProtobuf.Message, SwiftProto var _stakedID: Proto_ContractUpdateTransactionBody.OneOf_StakedID? var _declineReward: SwiftProtobuf.Google_Protobuf_BoolValue? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/crypto_create.pb.swift b/Sources/HederaProtobufs/Services/crypto_create.pb.swift index a0418d25..a4f00b8f 100644 --- a/Sources/HederaProtobufs/Services/crypto_create.pb.swift +++ b/Sources/HederaProtobufs/Services/crypto_create.pb.swift @@ -311,7 +311,15 @@ extension Proto_CryptoCreateTransactionBody: SwiftProtobuf.Message, SwiftProtobu var _declineReward: Bool = false var _alias: Data = Data() - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/crypto_get_info.pb.swift b/Sources/HederaProtobufs/Services/crypto_get_info.pb.swift index 8c1fc90b..d9f75f80 100644 --- a/Sources/HederaProtobufs/Services/crypto_get_info.pb.swift +++ b/Sources/HederaProtobufs/Services/crypto_get_info.pb.swift @@ -438,7 +438,15 @@ extension Proto_CryptoGetInfoResponse.AccountInfo: SwiftProtobuf.Message, SwiftP var _ethereumNonce: Int64 = 0 var _stakingInfo: Proto_StakingInfo? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/crypto_update.pb.swift b/Sources/HederaProtobufs/Services/crypto_update.pb.swift index 07aa6a5c..11f663ac 100644 --- a/Sources/HederaProtobufs/Services/crypto_update.pb.swift +++ b/Sources/HederaProtobufs/Services/crypto_update.pb.swift @@ -426,7 +426,15 @@ extension Proto_CryptoUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobu var _stakedID: Proto_CryptoUpdateTransactionBody.OneOf_StakedID? var _declineReward: SwiftProtobuf.Google_Protobuf_BoolValue? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/freeze_type.pb.swift b/Sources/HederaProtobufs/Services/freeze_type.pb.swift index f8a969bd..21ec2f2b 100644 --- a/Sources/HederaProtobufs/Services/freeze_type.pb.swift +++ b/Sources/HederaProtobufs/Services/freeze_type.pb.swift @@ -57,7 +57,7 @@ public enum Proto_FreezeType: SwiftProtobuf.Enum { /// Performs an immediate upgrade on auxilary services and containers providing /// telemetry/metrics. Does not impact network operations. case telemetryUpgrade // = 5 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .unknownFreezeType @@ -71,7 +71,7 @@ public enum Proto_FreezeType: SwiftProtobuf.Enum { case 3: self = .freezeUpgrade case 4: self = .freezeAbort case 5: self = .telemetryUpgrade - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -83,7 +83,7 @@ public enum Proto_FreezeType: SwiftProtobuf.Enum { case .freezeUpgrade: return 3 case .freezeAbort: return 4 case .telemetryUpgrade: return 5 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -92,7 +92,7 @@ public enum Proto_FreezeType: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_FreezeType: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_FreezeType] = [ .unknownFreezeType, .freezeOnly, diff --git a/Sources/HederaProtobufs/Services/get_account_details.pb.swift b/Sources/HederaProtobufs/Services/get_account_details.pb.swift index 60d1e50b..59aca7c9 100644 --- a/Sources/HederaProtobufs/Services/get_account_details.pb.swift +++ b/Sources/HederaProtobufs/Services/get_account_details.pb.swift @@ -520,7 +520,15 @@ extension Proto_GetAccountDetailsResponse.AccountDetails: SwiftProtobuf.Message, var _grantedNftAllowances: [Proto_GrantedNftAllowance] = [] var _grantedTokenAllowances: [Proto_GrantedTokenAllowance] = [] - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/node_create.pb.swift b/Sources/HederaProtobufs/Services/node_create.pb.swift new file mode 100644 index 00000000..3e764d1f --- /dev/null +++ b/Sources/HederaProtobufs/Services/node_create.pb.swift @@ -0,0 +1,165 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: node_create.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +///* +/// A transaction body to add a new node to the network. +/// After the node is created, the node_id for it is in the receipt. +/// +/// This transaction body SHALL be considered a "privileged transaction". +/// +/// This message supports a transaction to create a new node in the network. +/// The transaction, once complete, enables a new consensus node +/// to join the network, and requires governing council authorization. +/// +/// A `NodeCreateTransactionBody` MUST be signed by the governing council.
+/// The newly created node information will be used to generate config.txt and +/// a-pulbic-NodeAlias.pem file per each node during phase 2,
+/// not active until next freeze upgrade. +public struct Proto_NodeCreateTransactionBody { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// Node account id, mandatory field, ALIAS is not allowed, only ACCOUNT_NUM. + /// If account_id does not exist, it will reject the transaction. + /// Multiple nodes can have the same account_id. + public var accountID: Proto_AccountID { + get {return _accountID ?? Proto_AccountID()} + set {_accountID = newValue} + } + /// Returns true if `accountID` has been explicitly set. + public var hasAccountID: Bool {return self._accountID != nil} + /// Clears the value of `accountID`. Subsequent reads from it will return its default value. + public mutating func clearAccountID() {self._accountID = nil} + + ///* + /// Description of the node with UTF-8 encoding up to 100 bytes, optional field. + public var description_p: String = String() + + ///* + /// Ip address and port, mandatory field. Fully qualified domain name is + /// not allowed here. Maximum number of these endpoints is 10. + /// The first in the list is used as the Internal IP address in config.txt, + /// the second in the list is used as the External IP address in config.txt, + /// the rest of IP addresses are ignored for DAB phase 2. + public var gossipEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// A node's grpc service IP addresses and ports, IP:Port is mandatory, + /// fully qualified domain name is optional. Maximum number of these endpoints is 8. + public var serviceEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// The node's X509 certificate used to sign stream files (e.g., record stream + /// files). Precisely, this field is the DER encoding of gossip X509 certificate. + /// This is a mandatory field. + public var gossipCaCertificate: Data = Data() + + ///* + /// Hash of the node's TLS certificate. Precisely, this field is a string of + /// hexadecimal characters which translated to binary, are the SHA-384 hash of + /// the UTF-8 NFKD encoding of the node's TLS cert in PEM format. + /// Its value can be used to verify the node's certificate it presents + /// during TLS negotiations.node x509 certificate hash, optional field. + public var grpcCertificateHash: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _accountID: Proto_AccountID? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Proto_NodeCreateTransactionBody: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "proto" + +extension Proto_NodeCreateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeCreateTransactionBody" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "account_id"), + 2: .same(proto: "description"), + 3: .standard(proto: "gossip_endpoint"), + 4: .standard(proto: "service_endpoint"), + 5: .standard(proto: "gossip_ca_certificate"), + 6: .standard(proto: "grpc_certificate_hash"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._accountID) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.description_p) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.gossipEndpoint) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.serviceEndpoint) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.gossipCaCertificate) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.grpcCertificateHash) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._accountID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + if !self.description_p.isEmpty { + try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 2) + } + if !self.gossipEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.gossipEndpoint, fieldNumber: 3) + } + if !self.serviceEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.serviceEndpoint, fieldNumber: 4) + } + if !self.gossipCaCertificate.isEmpty { + try visitor.visitSingularBytesField(value: self.gossipCaCertificate, fieldNumber: 5) + } + if !self.grpcCertificateHash.isEmpty { + try visitor.visitSingularBytesField(value: self.grpcCertificateHash, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeCreateTransactionBody, rhs: Proto_NodeCreateTransactionBody) -> Bool { + if lhs._accountID != rhs._accountID {return false} + if lhs.description_p != rhs.description_p {return false} + if lhs.gossipEndpoint != rhs.gossipEndpoint {return false} + if lhs.serviceEndpoint != rhs.serviceEndpoint {return false} + if lhs.gossipCaCertificate != rhs.gossipCaCertificate {return false} + if lhs.grpcCertificateHash != rhs.grpcCertificateHash {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/HederaProtobufs/Services/node_delete.pb.swift b/Sources/HederaProtobufs/Services/node_delete.pb.swift new file mode 100644 index 00000000..0c70245b --- /dev/null +++ b/Sources/HederaProtobufs/Services/node_delete.pb.swift @@ -0,0 +1,84 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: node_delete.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +///* +/// Delete the given node. After deletion, it will be marked as deleted. +/// But information about it will continue to exist for a year. +/// For phase 2, this marks the node to be deleted in the merkle tree and will be used to write config.txt and +/// a-pulbic-NodeAlias.pem file per each node during prepare freeze. +/// The deleted node will not be deleted until the network is upgraded. +/// Such a deleted node can never be reused. +/// The council has to sign this transaction. This is a privileged transaction. +public struct Proto_NodeDeleteTransactionBody { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// The unique id of the node to be deleted. If invalid node is specified, transaction will + /// result in INVALID_NODE_ID. + public var nodeID: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Proto_NodeDeleteTransactionBody: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "proto" + +extension Proto_NodeDeleteTransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeDeleteTransactionBody" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "node_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.nodeID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.nodeID != 0 { + try visitor.visitSingularUInt64Field(value: self.nodeID, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeDeleteTransactionBody, rhs: Proto_NodeDeleteTransactionBody) -> Bool { + if lhs.nodeID != rhs.nodeID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/HederaProtobufs/Services/node_get_info.pb.swift b/Sources/HederaProtobufs/Services/node_get_info.pb.swift new file mode 100644 index 00000000..768f2ea0 --- /dev/null +++ b/Sources/HederaProtobufs/Services/node_get_info.pb.swift @@ -0,0 +1,347 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: node_get_info.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +///* +/// Gets information about Node instance. This needs super use privileges to succeed or should be a node operator. +public struct Proto_NodeGetInfoQuery { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// Standard information sent with every query operation.
+ /// This includes the signed payment and what kind of response is requested + /// (cost, state proof, both, or neither). + public var header: Proto_QueryHeader { + get {return _header ?? Proto_QueryHeader()} + set {_header = newValue} + } + /// Returns true if `header` has been explicitly set. + public var hasHeader: Bool {return self._header != nil} + /// Clears the value of `header`. Subsequent reads from it will return its default value. + public mutating func clearHeader() {self._header = nil} + + ///* + /// A node identifier for which information is requested.
+ /// If the identified node is not valid, this request SHALL fail with + /// a response code `INVALID_NODE_ID`. + public var nodeID: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _header: Proto_QueryHeader? = nil +} + +///* +/// A query response describing the current state of a node +public struct Proto_NodeInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// A numeric node identifier.
+ /// This value identifies this node within the network address book. + public var nodeID: UInt64 = 0 + + ///* + /// The account is charged for transactions submitted by the node that fail due diligence + public var accountID: Proto_AccountID { + get {return _accountID ?? Proto_AccountID()} + set {_accountID = newValue} + } + /// Returns true if `accountID` has been explicitly set. + public var hasAccountID: Bool {return self._accountID != nil} + /// Clears the value of `accountID`. Subsequent reads from it will return its default value. + public mutating func clearAccountID() {self._accountID = nil} + + ///* + /// A description of the node with UTF-8 encoding up to 100 bytes + public var description_p: String = String() + + ///* + /// A node's Gossip Endpoints, ip address and port + public var gossipEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// A node's service Endpoints, ip address or FQDN and port + public var serviceEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// The node's X509 certificate used to sign stream files (e.g., record stream + /// files). Precisely, this field is the DER encoding of gossip X509 certificate. + /// files). + public var gossipCaCertificate: Data = Data() + + ///* + /// node x509 certificate hash. Hash of the node's TLS certificate. Precisely, this field is a string of + /// hexadecimal characters which, translated to binary, are the SHA-384 hash of + /// the UTF-8 NFKD encoding of the node's TLS cert in PEM format. Its value can be + /// used to verify the node's certificate it presents during TLS negotiations. + public var grpcCertificateHash: Data = Data() + + ///* + /// The consensus weight of this node in the network. + public var weight: UInt64 = 0 + + ///* + /// Whether the node has been deleted + public var deleted: Bool = false + + ///* + /// A ledger ID.
+ /// This identifies the network that responded to this query. + /// The specific values are documented in [HIP-198] + /// (https://hips.hedera.com/hip/hip-198). + public var ledgerID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _accountID: Proto_AccountID? = nil +} + +///* +/// Response when the client sends the node NodeGetInfoQuery +public struct Proto_NodeGetInfoResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// The standard response information for queries.
+ /// This includes the values requested in the `QueryHeader`; + /// cost, state proof, both, or neither. + public var header: Proto_ResponseHeader { + get {return _header ?? Proto_ResponseHeader()} + set {_header = newValue} + } + /// Returns true if `header` has been explicitly set. + public var hasHeader: Bool {return self._header != nil} + /// Clears the value of `header`. Subsequent reads from it will return its default value. + public mutating func clearHeader() {self._header = nil} + + ///* + /// The information requested about this node instance + public var nodeInfo: Proto_NodeInfo { + get {return _nodeInfo ?? Proto_NodeInfo()} + set {_nodeInfo = newValue} + } + /// Returns true if `nodeInfo` has been explicitly set. + public var hasNodeInfo: Bool {return self._nodeInfo != nil} + /// Clears the value of `nodeInfo`. Subsequent reads from it will return its default value. + public mutating func clearNodeInfo() {self._nodeInfo = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _header: Proto_ResponseHeader? = nil + fileprivate var _nodeInfo: Proto_NodeInfo? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Proto_NodeGetInfoQuery: @unchecked Sendable {} +extension Proto_NodeInfo: @unchecked Sendable {} +extension Proto_NodeGetInfoResponse: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "proto" + +extension Proto_NodeGetInfoQuery: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeGetInfoQuery" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "header"), + 2: .standard(proto: "node_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._header) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.nodeID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._header { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + if self.nodeID != 0 { + try visitor.visitSingularUInt64Field(value: self.nodeID, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeGetInfoQuery, rhs: Proto_NodeGetInfoQuery) -> Bool { + if lhs._header != rhs._header {return false} + if lhs.nodeID != rhs.nodeID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Proto_NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeInfo" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "node_id"), + 2: .standard(proto: "account_id"), + 3: .same(proto: "description"), + 4: .standard(proto: "gossip_endpoint"), + 5: .standard(proto: "service_endpoint"), + 6: .standard(proto: "gossip_ca_certificate"), + 7: .standard(proto: "grpc_certificate_hash"), + 8: .same(proto: "weight"), + 10: .same(proto: "deleted"), + 9: .standard(proto: "ledger_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.nodeID) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._accountID) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.description_p) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.gossipEndpoint) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.serviceEndpoint) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.gossipCaCertificate) }() + case 7: try { try decoder.decodeSingularBytesField(value: &self.grpcCertificateHash) }() + case 8: try { try decoder.decodeSingularUInt64Field(value: &self.weight) }() + case 9: try { try decoder.decodeSingularBytesField(value: &self.ledgerID) }() + case 10: try { try decoder.decodeSingularBoolField(value: &self.deleted) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.nodeID != 0 { + try visitor.visitSingularUInt64Field(value: self.nodeID, fieldNumber: 1) + } + try { if let v = self._accountID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + if !self.description_p.isEmpty { + try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 3) + } + if !self.gossipEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.gossipEndpoint, fieldNumber: 4) + } + if !self.serviceEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.serviceEndpoint, fieldNumber: 5) + } + if !self.gossipCaCertificate.isEmpty { + try visitor.visitSingularBytesField(value: self.gossipCaCertificate, fieldNumber: 6) + } + if !self.grpcCertificateHash.isEmpty { + try visitor.visitSingularBytesField(value: self.grpcCertificateHash, fieldNumber: 7) + } + if self.weight != 0 { + try visitor.visitSingularUInt64Field(value: self.weight, fieldNumber: 8) + } + if !self.ledgerID.isEmpty { + try visitor.visitSingularBytesField(value: self.ledgerID, fieldNumber: 9) + } + if self.deleted != false { + try visitor.visitSingularBoolField(value: self.deleted, fieldNumber: 10) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeInfo, rhs: Proto_NodeInfo) -> Bool { + if lhs.nodeID != rhs.nodeID {return false} + if lhs._accountID != rhs._accountID {return false} + if lhs.description_p != rhs.description_p {return false} + if lhs.gossipEndpoint != rhs.gossipEndpoint {return false} + if lhs.serviceEndpoint != rhs.serviceEndpoint {return false} + if lhs.gossipCaCertificate != rhs.gossipCaCertificate {return false} + if lhs.grpcCertificateHash != rhs.grpcCertificateHash {return false} + if lhs.weight != rhs.weight {return false} + if lhs.deleted != rhs.deleted {return false} + if lhs.ledgerID != rhs.ledgerID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Proto_NodeGetInfoResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeGetInfoResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "header"), + 2: .same(proto: "nodeInfo"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._header) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._nodeInfo) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._header { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._nodeInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeGetInfoResponse, rhs: Proto_NodeGetInfoResponse) -> Bool { + if lhs._header != rhs._header {return false} + if lhs._nodeInfo != rhs._nodeInfo {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/HederaProtobufs/Services/node_stake_update.pb.swift b/Sources/HederaProtobufs/Services/node_stake_update.pb.swift index 8a24add5..30555a09 100644 --- a/Sources/HederaProtobufs/Services/node_stake_update.pb.swift +++ b/Sources/HederaProtobufs/Services/node_stake_update.pb.swift @@ -248,7 +248,15 @@ extension Proto_NodeStakeUpdateTransactionBody: SwiftProtobuf.Message, SwiftProt var _maxStakeRewarded: Int64 = 0 var _maxTotalReward: Int64 = 0 - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/node_update.pb.swift b/Sources/HederaProtobufs/Services/node_update.pb.swift new file mode 100644 index 00000000..93c6af04 --- /dev/null +++ b/Sources/HederaProtobufs/Services/node_update.pb.swift @@ -0,0 +1,179 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: node_update.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +///* +/// Modify the attribute of a node. If a field is not set in the transaction body, the +/// corresponding node attribute will be unchanged. +/// For phase 2, this marks node to be updated in the merkle tree and will be used to write config.txt and +/// a-pulbic-NodeAlias.pem file per each node during prepare freeze. +/// The node will not be updated until the network is upgraded. +/// Original node account ID has to sign the transaction. +public struct Proto_NodeUpdateTransactionBody { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// The unique id of the Node to be updated. This must refer to an existing, non-deleted node. + public var nodeID: UInt64 = 0 + + ///* + /// If set, the new node account_id. + public var accountID: Proto_AccountID { + get {return _accountID ?? Proto_AccountID()} + set {_accountID = newValue} + } + /// Returns true if `accountID` has been explicitly set. + public var hasAccountID: Bool {return self._accountID != nil} + /// Clears the value of `accountID`. Subsequent reads from it will return its default value. + public mutating func clearAccountID() {self._accountID = nil} + + ///* + /// If set, the new description to be associated with the node. + public var description_p: SwiftProtobuf.Google_Protobuf_StringValue { + get {return _description_p ?? SwiftProtobuf.Google_Protobuf_StringValue()} + set {_description_p = newValue} + } + /// Returns true if `description_p` has been explicitly set. + public var hasDescription_p: Bool {return self._description_p != nil} + /// Clears the value of `description_p`. Subsequent reads from it will return its default value. + public mutating func clearDescription_p() {self._description_p = nil} + + ///* + /// If set, the new ip address and port. + public var gossipEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// If set, replace the current list of service_endpoints. + public var serviceEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// If set, the new X509 certificate of the gossip node. + public var gossipCaCertificate: SwiftProtobuf.Google_Protobuf_BytesValue { + get {return _gossipCaCertificate ?? SwiftProtobuf.Google_Protobuf_BytesValue()} + set {_gossipCaCertificate = newValue} + } + /// Returns true if `gossipCaCertificate` has been explicitly set. + public var hasGossipCaCertificate: Bool {return self._gossipCaCertificate != nil} + /// Clears the value of `gossipCaCertificate`. Subsequent reads from it will return its default value. + public mutating func clearGossipCaCertificate() {self._gossipCaCertificate = nil} + + ///* + /// If set, the new grpc x509 certificate hash. + public var grpcCertificateHash: SwiftProtobuf.Google_Protobuf_BytesValue { + get {return _grpcCertificateHash ?? SwiftProtobuf.Google_Protobuf_BytesValue()} + set {_grpcCertificateHash = newValue} + } + /// Returns true if `grpcCertificateHash` has been explicitly set. + public var hasGrpcCertificateHash: Bool {return self._grpcCertificateHash != nil} + /// Clears the value of `grpcCertificateHash`. Subsequent reads from it will return its default value. + public mutating func clearGrpcCertificateHash() {self._grpcCertificateHash = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _accountID: Proto_AccountID? = nil + fileprivate var _description_p: SwiftProtobuf.Google_Protobuf_StringValue? = nil + fileprivate var _gossipCaCertificate: SwiftProtobuf.Google_Protobuf_BytesValue? = nil + fileprivate var _grpcCertificateHash: SwiftProtobuf.Google_Protobuf_BytesValue? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Proto_NodeUpdateTransactionBody: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "proto" + +extension Proto_NodeUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".NodeUpdateTransactionBody" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "node_id"), + 2: .standard(proto: "account_id"), + 3: .same(proto: "description"), + 4: .standard(proto: "gossip_endpoint"), + 5: .standard(proto: "service_endpoint"), + 6: .standard(proto: "gossip_ca_certificate"), + 7: .standard(proto: "grpc_certificate_hash"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.nodeID) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._accountID) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._description_p) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.gossipEndpoint) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.serviceEndpoint) }() + case 6: try { try decoder.decodeSingularMessageField(value: &self._gossipCaCertificate) }() + case 7: try { try decoder.decodeSingularMessageField(value: &self._grpcCertificateHash) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.nodeID != 0 { + try visitor.visitSingularUInt64Field(value: self.nodeID, fieldNumber: 1) + } + try { if let v = self._accountID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._description_p { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + if !self.gossipEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.gossipEndpoint, fieldNumber: 4) + } + if !self.serviceEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.serviceEndpoint, fieldNumber: 5) + } + try { if let v = self._gossipCaCertificate { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + try { if let v = self._grpcCertificateHash { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_NodeUpdateTransactionBody, rhs: Proto_NodeUpdateTransactionBody) -> Bool { + if lhs.nodeID != rhs.nodeID {return false} + if lhs._accountID != rhs._accountID {return false} + if lhs._description_p != rhs._description_p {return false} + if lhs.gossipEndpoint != rhs.gossipEndpoint {return false} + if lhs.serviceEndpoint != rhs.serviceEndpoint {return false} + if lhs._gossipCaCertificate != rhs._gossipCaCertificate {return false} + if lhs._grpcCertificateHash != rhs._grpcCertificateHash {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/HederaProtobufs/Services/query.pb.swift b/Sources/HederaProtobufs/Services/query.pb.swift index f2b92f9d..0b407fd0 100644 --- a/Sources/HederaProtobufs/Services/query.pb.swift +++ b/Sources/HederaProtobufs/Services/query.pb.swift @@ -282,6 +282,16 @@ public struct Proto_Query { set {query = .accountDetails(newValue)} } + ///* + /// Get all information about a node + public var nodeGetInfo: Proto_NodeGetInfoQuery { + get { + if case .nodeGetInfo(let v)? = query {return v} + return Proto_NodeGetInfoQuery() + } + set {query = .nodeGetInfo(newValue)} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public enum OneOf_Query: Equatable { @@ -362,6 +372,9 @@ public struct Proto_Query { ///* /// Gets all information about an account including allowances granted by the account case accountDetails(Proto_GetAccountDetailsQuery) + ///* + /// Get all information about a node + case nodeGetInfo(Proto_NodeGetInfoQuery) #if !swift(>=4.1) public static func ==(lhs: Proto_Query.OneOf_Query, rhs: Proto_Query.OneOf_Query) -> Bool { @@ -469,6 +482,10 @@ public struct Proto_Query { guard case .accountDetails(let l) = lhs, case .accountDetails(let r) = rhs else { preconditionFailure() } return l == r }() + case (.nodeGetInfo, .nodeGetInfo): return { + guard case .nodeGetInfo(let l) = lhs, case .nodeGetInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -515,6 +532,7 @@ extension Proto_Query: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 56: .same(proto: "tokenGetNftInfos"), 57: .same(proto: "networkGetExecutionTime"), 58: .same(proto: "accountDetails"), + 59: .same(proto: "nodeGetInfo"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -848,6 +866,19 @@ extension Proto_Query: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati self.query = .accountDetails(v) } }() + case 59: try { + var v: Proto_NodeGetInfoQuery? + var hadOneofValue = false + if let current = self.query { + hadOneofValue = true + if case .nodeGetInfo(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.query = .nodeGetInfo(v) + } + }() default: break } } @@ -959,6 +990,10 @@ extension Proto_Query: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati guard case .accountDetails(let v)? = self.query else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 58) }() + case .nodeGetInfo?: try { + guard case .nodeGetInfo(let v)? = self.query else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 59) + }() case nil: break } try unknownFields.traverse(visitor: &visitor) diff --git a/Sources/HederaProtobufs/Services/query_header.pb.swift b/Sources/HederaProtobufs/Services/query_header.pb.swift index ac926fa0..4763d7e9 100644 --- a/Sources/HederaProtobufs/Services/query_header.pb.swift +++ b/Sources/HederaProtobufs/Services/query_header.pb.swift @@ -45,7 +45,7 @@ public enum Proto_ResponseType: SwiftProtobuf.Enum { ///* /// (NOT YET SUPPORTED) Response returns the total cost of answer and state proof case costAnswerStateProof // = 3 - case unrecognized(Int) + case UNRECOGNIZED(Int) public init() { self = .answerOnly @@ -57,7 +57,7 @@ public enum Proto_ResponseType: SwiftProtobuf.Enum { case 1: self = .answerStateProof case 2: self = .costAnswer case 3: self = .costAnswerStateProof - default: self = .unrecognized(rawValue) + default: self = .UNRECOGNIZED(rawValue) } } @@ -67,7 +67,7 @@ public enum Proto_ResponseType: SwiftProtobuf.Enum { case .answerStateProof: return 1 case .costAnswer: return 2 case .costAnswerStateProof: return 3 - case .unrecognized(let i): return i + case .UNRECOGNIZED(let i): return i } } @@ -76,7 +76,7 @@ public enum Proto_ResponseType: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_ResponseType: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_ResponseType] = [ .answerOnly, .answerStateProof, diff --git a/Sources/HederaProtobufs/Services/response_code.pb.swift b/Sources/HederaProtobufs/Services/response_code.pb.swift index 8f14471a..7f1e292c 100644 --- a/Sources/HederaProtobufs/Services/response_code.pb.swift +++ b/Sources/HederaProtobufs/Services/response_code.pb.swift @@ -1206,7 +1206,43 @@ public enum Proto_ResponseCodeEnum: SwiftProtobuf.Enum { ///* /// NFT serial numbers are missing in the TokenUpdateNftsTransactionBody case missingSerialNumbers // = 336 - case unrecognized(Int) + + ///* + /// Admin key is not set on token + case tokenHasNoAdminKey // = 337 + + ///* + /// The node has been marked as deleted + case nodeDeleted // = 338 + + ///* + /// A node is not found during update and delete node transaction + case invalidNodeID // = 339 + + ///* + /// gossip_endpoint has a fully qualified domain name instead of ip + case invalidGossipEndpoint // = 340 + + ///* + /// The node account_id is invalid + case invalidNodeAccountID // = 341 + + ///* + /// The node description is invalid + case invalidNodeDescription // = 342 + + ///* + /// service_endpoint is invalid + case invalidServiceEndpoint // = 343 + + ///* + /// gossip_ca_certificate is invalid + case invalidGossipCaeCertificate // = 344 + + ///* + /// grpc_certificate_hash is invalid + case invalidGrpcCertificate // = 345 + case UNRECOGNIZED(Int) public init() { self = .ok @@ -1509,7 +1545,16 @@ public enum Proto_ResponseCodeEnum: SwiftProtobuf.Enum { case 334: self = .tokenHasNoMetadataKey case 335: self = .missingTokenMetadata case 336: self = .missingSerialNumbers - default: self = .unrecognized(rawValue) + case 337: self = .tokenHasNoAdminKey + case 338: self = .nodeDeleted + case 339: self = .invalidNodeID + case 340: self = .invalidGossipEndpoint + case 341: self = .invalidNodeAccountID + case 342: self = .invalidNodeDescription + case 343: self = .invalidServiceEndpoint + case 344: self = .invalidGossipCaeCertificate + case 345: self = .invalidGrpcCertificate + default: self = .UNRECOGNIZED(rawValue) } } @@ -1810,7 +1855,16 @@ public enum Proto_ResponseCodeEnum: SwiftProtobuf.Enum { case .tokenHasNoMetadataKey: return 334 case .missingTokenMetadata: return 335 case .missingSerialNumbers: return 336 - case .unrecognized(let i): return i + case .tokenHasNoAdminKey: return 337 + case .nodeDeleted: return 338 + case .invalidNodeID: return 339 + case .invalidGossipEndpoint: return 340 + case .invalidNodeAccountID: return 341 + case .invalidNodeDescription: return 342 + case .invalidServiceEndpoint: return 343 + case .invalidGossipCaeCertificate: return 344 + case .invalidGrpcCertificate: return 345 + case .UNRECOGNIZED(let i): return i } } @@ -1819,7 +1873,7 @@ public enum Proto_ResponseCodeEnum: SwiftProtobuf.Enum { #if swift(>=4.2) extension Proto_ResponseCodeEnum: CaseIterable { - // The compiler won't synthesize support with the unrecognized case. + // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Proto_ResponseCodeEnum] = [ .ok, .invalidTransaction, @@ -2116,6 +2170,15 @@ extension Proto_ResponseCodeEnum: CaseIterable { .tokenHasNoMetadataKey, .missingTokenMetadata, .missingSerialNumbers, + .tokenHasNoAdminKey, + .nodeDeleted, + .invalidNodeID, + .invalidGossipEndpoint, + .invalidNodeAccountID, + .invalidNodeDescription, + .invalidServiceEndpoint, + .invalidGossipCaeCertificate, + .invalidGrpcCertificate, ] } @@ -2424,5 +2487,14 @@ extension Proto_ResponseCodeEnum: SwiftProtobuf._ProtoNameProviding { 334: .same(proto: "TOKEN_HAS_NO_METADATA_KEY"), 335: .same(proto: "MISSING_TOKEN_METADATA"), 336: .same(proto: "MISSING_SERIAL_NUMBERS"), + 337: .same(proto: "TOKEN_HAS_NO_ADMIN_KEY"), + 338: .same(proto: "NODE_DELETED"), + 339: .same(proto: "INVALID_NODE_ID"), + 340: .same(proto: "INVALID_GOSSIP_ENDPOINT"), + 341: .same(proto: "INVALID_NODE_ACCOUNT_ID"), + 342: .same(proto: "INVALID_NODE_DESCRIPTION"), + 343: .same(proto: "INVALID_SERVICE_ENDPOINT"), + 344: .same(proto: "INVALID_GOSSIP_CAE_CERTIFICATE"), + 345: .same(proto: "INVALID_GRPC_CERTIFICATE"), ] } diff --git a/Sources/HederaProtobufs/Services/schedulable_transaction_body.pb.swift b/Sources/HederaProtobufs/Services/schedulable_transaction_body.pb.swift index a07a8069..abff0feb 100644 --- a/Sources/HederaProtobufs/Services/schedulable_transaction_body.pb.swift +++ b/Sources/HederaProtobufs/Services/schedulable_transaction_body.pb.swift @@ -442,6 +442,36 @@ public struct Proto_SchedulableTransactionBody { set {_uniqueStorage()._data = .tokenUpdateNfts(newValue)} } + ///* + /// Transaction body for a scheduled transaction to create a new node. + public var nodeCreate: Proto_NodeCreateTransactionBody { + get { + if case .nodeCreate(let v)? = _storage._data {return v} + return Proto_NodeCreateTransactionBody() + } + set {_uniqueStorage()._data = .nodeCreate(newValue)} + } + + ///* + /// Transaction body for a scheduled transaction to modify an existing node. + public var nodeUpdate: Proto_NodeUpdateTransactionBody { + get { + if case .nodeUpdate(let v)? = _storage._data {return v} + return Proto_NodeUpdateTransactionBody() + } + set {_uniqueStorage()._data = .nodeUpdate(newValue)} + } + + ///* + /// Transaction body for a scheduled transaction to remove a node. + public var nodeDelete: Proto_NodeDeleteTransactionBody { + get { + if case .nodeDelete(let v)? = _storage._data {return v} + return Proto_NodeDeleteTransactionBody() + } + set {_uniqueStorage()._data = .nodeDelete(newValue)} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() ///* @@ -564,6 +594,15 @@ public struct Proto_SchedulableTransactionBody { ///* /// Update the metadata of one or more NFT's of a specific token type. case tokenUpdateNfts(Proto_TokenUpdateNftsTransactionBody) + ///* + /// Transaction body for a scheduled transaction to create a new node. + case nodeCreate(Proto_NodeCreateTransactionBody) + ///* + /// Transaction body for a scheduled transaction to modify an existing node. + case nodeUpdate(Proto_NodeUpdateTransactionBody) + ///* + /// Transaction body for a scheduled transaction to remove a node. + case nodeDelete(Proto_NodeDeleteTransactionBody) #if !swift(>=4.1) public static func ==(lhs: Proto_SchedulableTransactionBody.OneOf_Data, rhs: Proto_SchedulableTransactionBody.OneOf_Data) -> Bool { @@ -727,6 +766,18 @@ public struct Proto_SchedulableTransactionBody { guard case .tokenUpdateNfts(let l) = lhs, case .tokenUpdateNfts(let r) = rhs else { preconditionFailure() } return l == r }() + case (.nodeCreate, .nodeCreate): return { + guard case .nodeCreate(let l) = lhs, case .nodeCreate(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeUpdate, .nodeUpdate): return { + guard case .nodeUpdate(let l) = lhs, case .nodeUpdate(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeDelete, .nodeDelete): return { + guard case .nodeDelete(let l) = lhs, case .nodeDelete(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -791,6 +842,9 @@ extension Proto_SchedulableTransactionBody: SwiftProtobuf.Message, SwiftProtobuf 34: .same(proto: "scheduleDelete"), 40: .standard(proto: "util_prng"), 41: .standard(proto: "token_update_nfts"), + 42: .same(proto: "nodeCreate"), + 43: .same(proto: "nodeUpdate"), + 44: .same(proto: "nodeDelete"), ] fileprivate class _StorageClass { @@ -798,7 +852,15 @@ extension Proto_SchedulableTransactionBody: SwiftProtobuf.Message, SwiftProtobuf var _memo: String = String() var _data: Proto_SchedulableTransactionBody.OneOf_Data? - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} @@ -1333,6 +1395,45 @@ extension Proto_SchedulableTransactionBody: SwiftProtobuf.Message, SwiftProtobuf _storage._data = .tokenUpdateNfts(v) } }() + case 42: try { + var v: Proto_NodeCreateTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeCreate(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeCreate(v) + } + }() + case 43: try { + var v: Proto_NodeUpdateTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeUpdate(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeUpdate(v) + } + }() + case 44: try { + var v: Proto_NodeDeleteTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeDelete(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeDelete(v) + } + }() default: break } } @@ -1508,6 +1609,18 @@ extension Proto_SchedulableTransactionBody: SwiftProtobuf.Message, SwiftProtobuf guard case .tokenUpdateNfts(let v)? = _storage._data else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 41) }() + case .nodeCreate?: try { + guard case .nodeCreate(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 42) + }() + case .nodeUpdate?: try { + guard case .nodeUpdate(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 43) + }() + case .nodeDelete?: try { + guard case .nodeDelete(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 44) + }() case nil: break } } diff --git a/Sources/HederaProtobufs/Services/schedule_get_info.pb.swift b/Sources/HederaProtobufs/Services/schedule_get_info.pb.swift index 586de4de..040e7e08 100644 --- a/Sources/HederaProtobufs/Services/schedule_get_info.pb.swift +++ b/Sources/HederaProtobufs/Services/schedule_get_info.pb.swift @@ -369,7 +369,15 @@ extension Proto_ScheduleInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImple var _ledgerID: Data = Data() var _waitForExpiry: Bool = false - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_addressbook_node.pb.swift b/Sources/HederaProtobufs/Services/state_addressbook_node.pb.swift new file mode 100644 index 00000000..6b6242c9 --- /dev/null +++ b/Sources/HederaProtobufs/Services/state_addressbook_node.pb.swift @@ -0,0 +1,237 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: state/addressbook/node.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public enum Proto_NodeStatus: SwiftProtobuf.Enum { + public typealias RawValue = Int + + ///* + /// node in this state is deleted + case deleted // = 0 + + ///* + /// node in this state is waiting to be added by consensus roster + case pendingAddition // = 1 + + ///* + /// node in this state is waiting to be deleted by consensus roster + case pendingDeletion // = 2 + + ///* + /// node in this state is active on the network and participating + /// in network consensus. + case inConsensus // = 3 + case UNRECOGNIZED(Int) + + public init() { + self = .deleted + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .deleted + case 1: self = .pendingAddition + case 2: self = .pendingDeletion + case 3: self = .inConsensus + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .deleted: return 0 + case .pendingAddition: return 1 + case .pendingDeletion: return 2 + case .inConsensus: return 3 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Proto_NodeStatus: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Proto_NodeStatus] = [ + .deleted, + .pendingAddition, + .pendingDeletion, + .inConsensus, + ] +} + +#endif // swift(>=4.2) + +///* +/// Representation of a Node in the network Merkle tree +/// +/// A Node is identified by a single uint64 number, which is unique among all nodes. +public struct Proto_Node { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + ///* + /// The unique id of the Node. + public var nodeID: UInt64 = 0 + + ///* + /// The account is charged for transactions submitted by the node that fail due diligence + public var accountID: Proto_AccountID { + get {return _accountID ?? Proto_AccountID()} + set {_accountID = newValue} + } + /// Returns true if `accountID` has been explicitly set. + public var hasAccountID: Bool {return self._accountID != nil} + /// Clears the value of `accountID`. Subsequent reads from it will return its default value. + public mutating func clearAccountID() {self._accountID = nil} + + ///* + /// A description of the node, with UTF-8 encoding up to 100 bytes + public var description_p: String = String() + + ///* + /// Node Gossip Endpoints, ip address or FQDN and port + public var gossipEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// A node's service Endpoints, ip address or FQDN and port + public var serviceEndpoint: [Proto_ServiceEndpoint] = [] + + ///* + /// The node's X509 certificate used to sign stream files (e.g., record stream + /// files). Precisely, this field is the DER encoding of gossip X509 certificate. + public var gossipCaCertificate: Data = Data() + + ///* + /// node x509 certificate hash. Hash of the node's TLS certificate. Precisely, this field is a string of + /// hexadecimal characters which, translated to binary, are the SHA-384 hash of + /// the UTF-8 NFKD encoding of the node's TLS cert in PEM format. Its value can be + /// used to verify the node's certificate it presents during TLS negotiations. + public var grpcCertificateHash: Data = Data() + + ///* + /// The consensus weight of this node in the network. + public var weight: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _accountID: Proto_AccountID? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Proto_NodeStatus: @unchecked Sendable {} +extension Proto_Node: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "proto" + +extension Proto_NodeStatus: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "DELETED"), + 1: .same(proto: "PENDING_ADDITION"), + 2: .same(proto: "PENDING_DELETION"), + 3: .same(proto: "IN_CONSENSUS"), + ] +} + +extension Proto_Node: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Node" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "node_id"), + 2: .standard(proto: "account_id"), + 3: .same(proto: "description"), + 4: .standard(proto: "gossip_endpoint"), + 5: .standard(proto: "service_endpoint"), + 6: .standard(proto: "gossip_ca_certificate"), + 7: .standard(proto: "grpc_certificate_hash"), + 8: .same(proto: "weight"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.nodeID) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._accountID) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.description_p) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.gossipEndpoint) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.serviceEndpoint) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.gossipCaCertificate) }() + case 7: try { try decoder.decodeSingularBytesField(value: &self.grpcCertificateHash) }() + case 8: try { try decoder.decodeSingularUInt64Field(value: &self.weight) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.nodeID != 0 { + try visitor.visitSingularUInt64Field(value: self.nodeID, fieldNumber: 1) + } + try { if let v = self._accountID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + if !self.description_p.isEmpty { + try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 3) + } + if !self.gossipEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.gossipEndpoint, fieldNumber: 4) + } + if !self.serviceEndpoint.isEmpty { + try visitor.visitRepeatedMessageField(value: self.serviceEndpoint, fieldNumber: 5) + } + if !self.gossipCaCertificate.isEmpty { + try visitor.visitSingularBytesField(value: self.gossipCaCertificate, fieldNumber: 6) + } + if !self.grpcCertificateHash.isEmpty { + try visitor.visitSingularBytesField(value: self.grpcCertificateHash, fieldNumber: 7) + } + if self.weight != 0 { + try visitor.visitSingularUInt64Field(value: self.weight, fieldNumber: 8) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Proto_Node, rhs: Proto_Node) -> Bool { + if lhs.nodeID != rhs.nodeID {return false} + if lhs._accountID != rhs._accountID {return false} + if lhs.description_p != rhs.description_p {return false} + if lhs.gossipEndpoint != rhs.gossipEndpoint {return false} + if lhs.serviceEndpoint != rhs.serviceEndpoint {return false} + if lhs.gossipCaCertificate != rhs.gossipCaCertificate {return false} + if lhs.grpcCertificateHash != rhs.grpcCertificateHash {return false} + if lhs.weight != rhs.weight {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/HederaProtobufs/Services/state_consensus_topic.pb.swift b/Sources/HederaProtobufs/Services/state_consensus_topic.pb.swift index d70ce59d..15cf4092 100644 --- a/Sources/HederaProtobufs/Services/state_consensus_topic.pb.swift +++ b/Sources/HederaProtobufs/Services/state_consensus_topic.pb.swift @@ -181,7 +181,15 @@ extension Proto_Topic: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati var _adminKey: Proto_Key? = nil var _submitKey: Proto_Key? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_schedule_schedule.pb.swift b/Sources/HederaProtobufs/Services/state_schedule_schedule.pb.swift index e1266398..65d66f92 100644 --- a/Sources/HederaProtobufs/Services/state_schedule_schedule.pb.swift +++ b/Sources/HederaProtobufs/Services/state_schedule_schedule.pb.swift @@ -259,7 +259,15 @@ extension Proto_Schedule: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement var _originalCreateTransaction: Proto_TransactionBody? = nil var _signatories: [Proto_Key] = [] - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_token_account.pb.swift b/Sources/HederaProtobufs/Services/state_token_account.pb.swift index 7e1fe935..b875a020 100644 --- a/Sources/HederaProtobufs/Services/state_token_account.pb.swift +++ b/Sources/HederaProtobufs/Services/state_token_account.pb.swift @@ -536,7 +536,15 @@ extension Proto_Account: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa var _expiredAndPendingRemoval: Bool = false var _firstContractStorageKey: Data = Data() - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_token_nft.pb.swift b/Sources/HederaProtobufs/Services/state_token_nft.pb.swift index 3196b08d..dfe86c91 100644 --- a/Sources/HederaProtobufs/Services/state_token_nft.pb.swift +++ b/Sources/HederaProtobufs/Services/state_token_nft.pb.swift @@ -142,7 +142,15 @@ extension Proto_Nft: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation var _ownerPreviousNftID: Proto_NftID? = nil var _ownerNextNftID: Proto_NftID? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_token_token.pb.swift b/Sources/HederaProtobufs/Services/state_token_token.pb.swift index 05d42036..8a0f6ee8 100644 --- a/Sources/HederaProtobufs/Services/state_token_token.pb.swift +++ b/Sources/HederaProtobufs/Services/state_token_token.pb.swift @@ -364,7 +364,15 @@ extension Proto_Token: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati var _metadata: Data = Data() var _metadataKey: Proto_Key? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/state_token_token_relation.pb.swift b/Sources/HederaProtobufs/Services/state_token_token_relation.pb.swift index 62a62d88..87bd81d7 100644 --- a/Sources/HederaProtobufs/Services/state_token_token_relation.pb.swift +++ b/Sources/HederaProtobufs/Services/state_token_token_relation.pb.swift @@ -33,87 +33,71 @@ public struct Proto_TokenRelation { ///* /// The token involved in this relation.It takes only positive public var tokenID: Proto_TokenID { - get {return _storage._tokenID ?? Proto_TokenID()} - set {_uniqueStorage()._tokenID = newValue} + get {return _tokenID ?? Proto_TokenID()} + set {_tokenID = newValue} } /// Returns true if `tokenID` has been explicitly set. - public var hasTokenID: Bool {return _storage._tokenID != nil} + public var hasTokenID: Bool {return self._tokenID != nil} /// Clears the value of `tokenID`. Subsequent reads from it will return its default value. - public mutating func clearTokenID() {_uniqueStorage()._tokenID = nil} + public mutating func clearTokenID() {self._tokenID = nil} ///* /// The account involved in this association. public var accountID: Proto_AccountID { - get {return _storage._accountID ?? Proto_AccountID()} - set {_uniqueStorage()._accountID = newValue} + get {return _accountID ?? Proto_AccountID()} + set {_accountID = newValue} } /// Returns true if `accountID` has been explicitly set. - public var hasAccountID: Bool {return _storage._accountID != nil} + public var hasAccountID: Bool {return self._accountID != nil} /// Clears the value of `accountID`. Subsequent reads from it will return its default value. - public mutating func clearAccountID() {_uniqueStorage()._accountID = nil} + public mutating func clearAccountID() {self._accountID = nil} ///* /// The balance of the token relationship. - public var balance: Int64 { - get {return _storage._balance} - set {_uniqueStorage()._balance = newValue} - } + public var balance: Int64 = 0 ///* /// The flags specifying the token relationship is frozen or not. - public var frozen: Bool { - get {return _storage._frozen} - set {_uniqueStorage()._frozen = newValue} - } + public var frozen: Bool = false ///* /// The flag indicating if the token relationship has been granted KYC. - public var kycGranted: Bool { - get {return _storage._kycGranted} - set {_uniqueStorage()._kycGranted = newValue} - } - - ///* - /// The flag indicating if the token relationship was deleted. - public var deleted: Bool { - get {return _storage._deleted} - set {_uniqueStorage()._deleted = newValue} - } + public var kycGranted: Bool = false ///* /// The flag indicating if the token relationship was created using automatic association. - public var automaticAssociation: Bool { - get {return _storage._automaticAssociation} - set {_uniqueStorage()._automaticAssociation = newValue} - } + public var automaticAssociation: Bool = false ///* /// The previous token id of account's association linked list public var previousToken: Proto_TokenID { - get {return _storage._previousToken ?? Proto_TokenID()} - set {_uniqueStorage()._previousToken = newValue} + get {return _previousToken ?? Proto_TokenID()} + set {_previousToken = newValue} } /// Returns true if `previousToken` has been explicitly set. - public var hasPreviousToken: Bool {return _storage._previousToken != nil} + public var hasPreviousToken: Bool {return self._previousToken != nil} /// Clears the value of `previousToken`. Subsequent reads from it will return its default value. - public mutating func clearPreviousToken() {_uniqueStorage()._previousToken = nil} + public mutating func clearPreviousToken() {self._previousToken = nil} ///* /// The next token id of account's association linked list public var nextToken: Proto_TokenID { - get {return _storage._nextToken ?? Proto_TokenID()} - set {_uniqueStorage()._nextToken = newValue} + get {return _nextToken ?? Proto_TokenID()} + set {_nextToken = newValue} } /// Returns true if `nextToken` has been explicitly set. - public var hasNextToken: Bool {return _storage._nextToken != nil} + public var hasNextToken: Bool {return self._nextToken != nil} /// Clears the value of `nextToken`. Subsequent reads from it will return its default value. - public mutating func clearNextToken() {_uniqueStorage()._nextToken = nil} + public mutating func clearNextToken() {self._nextToken = nil} public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _tokenID: Proto_TokenID? = nil + fileprivate var _accountID: Proto_AccountID? = nil + fileprivate var _previousToken: Proto_TokenID? = nil + fileprivate var _nextToken: Proto_TokenID? = nil } #if swift(>=5.5) && canImport(_Concurrency) @@ -132,125 +116,71 @@ extension Proto_TokenRelation: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl 3: .same(proto: "balance"), 4: .same(proto: "frozen"), 5: .standard(proto: "kyc_granted"), - 6: .same(proto: "deleted"), - 7: .standard(proto: "automatic_association"), - 8: .standard(proto: "previous_token"), - 9: .standard(proto: "next_token"), + 6: .standard(proto: "automatic_association"), + 7: .standard(proto: "previous_token"), + 8: .standard(proto: "next_token"), ] - fileprivate class _StorageClass { - var _tokenID: Proto_TokenID? = nil - var _accountID: Proto_AccountID? = nil - var _balance: Int64 = 0 - var _frozen: Bool = false - var _kycGranted: Bool = false - var _deleted: Bool = false - var _automaticAssociation: Bool = false - var _previousToken: Proto_TokenID? = nil - var _nextToken: Proto_TokenID? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _tokenID = source._tokenID - _accountID = source._accountID - _balance = source._balance - _frozen = source._frozen - _kycGranted = source._kycGranted - _deleted = source._deleted - _automaticAssociation = source._automaticAssociation - _previousToken = source._previousToken - _nextToken = source._nextToken - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - public mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &_storage._tokenID) }() - case 2: try { try decoder.decodeSingularMessageField(value: &_storage._accountID) }() - case 3: try { try decoder.decodeSingularInt64Field(value: &_storage._balance) }() - case 4: try { try decoder.decodeSingularBoolField(value: &_storage._frozen) }() - case 5: try { try decoder.decodeSingularBoolField(value: &_storage._kycGranted) }() - case 6: try { try decoder.decodeSingularBoolField(value: &_storage._deleted) }() - case 7: try { try decoder.decodeSingularBoolField(value: &_storage._automaticAssociation) }() - case 8: try { try decoder.decodeSingularMessageField(value: &_storage._previousToken) }() - case 9: try { try decoder.decodeSingularMessageField(value: &_storage._nextToken) }() - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._tokenID) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._accountID) }() + case 3: try { try decoder.decodeSingularInt64Field(value: &self.balance) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.frozen) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.kycGranted) }() + case 6: try { try decoder.decodeSingularBoolField(value: &self.automaticAssociation) }() + case 7: try { try decoder.decodeSingularMessageField(value: &self._previousToken) }() + case 8: try { try decoder.decodeSingularMessageField(value: &self._nextToken) }() + default: break } } } public func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._tokenID { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._accountID { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - if _storage._balance != 0 { - try visitor.visitSingularInt64Field(value: _storage._balance, fieldNumber: 3) - } - if _storage._frozen != false { - try visitor.visitSingularBoolField(value: _storage._frozen, fieldNumber: 4) - } - if _storage._kycGranted != false { - try visitor.visitSingularBoolField(value: _storage._kycGranted, fieldNumber: 5) - } - if _storage._deleted != false { - try visitor.visitSingularBoolField(value: _storage._deleted, fieldNumber: 6) - } - if _storage._automaticAssociation != false { - try visitor.visitSingularBoolField(value: _storage._automaticAssociation, fieldNumber: 7) - } - try { if let v = _storage._previousToken { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() - try { if let v = _storage._nextToken { - try visitor.visitSingularMessageField(value: v, fieldNumber: 9) - } }() + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._tokenID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._accountID { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + if self.balance != 0 { + try visitor.visitSingularInt64Field(value: self.balance, fieldNumber: 3) + } + if self.frozen != false { + try visitor.visitSingularBoolField(value: self.frozen, fieldNumber: 4) + } + if self.kycGranted != false { + try visitor.visitSingularBoolField(value: self.kycGranted, fieldNumber: 5) } + if self.automaticAssociation != false { + try visitor.visitSingularBoolField(value: self.automaticAssociation, fieldNumber: 6) + } + try { if let v = self._previousToken { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + try { if let v = self._nextToken { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Proto_TokenRelation, rhs: Proto_TokenRelation) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._tokenID != rhs_storage._tokenID {return false} - if _storage._accountID != rhs_storage._accountID {return false} - if _storage._balance != rhs_storage._balance {return false} - if _storage._frozen != rhs_storage._frozen {return false} - if _storage._kycGranted != rhs_storage._kycGranted {return false} - if _storage._deleted != rhs_storage._deleted {return false} - if _storage._automaticAssociation != rhs_storage._automaticAssociation {return false} - if _storage._previousToken != rhs_storage._previousToken {return false} - if _storage._nextToken != rhs_storage._nextToken {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._tokenID != rhs._tokenID {return false} + if lhs._accountID != rhs._accountID {return false} + if lhs.balance != rhs.balance {return false} + if lhs.frozen != rhs.frozen {return false} + if lhs.kycGranted != rhs.kycGranted {return false} + if lhs.automaticAssociation != rhs.automaticAssociation {return false} + if lhs._previousToken != rhs._previousToken {return false} + if lhs._nextToken != rhs._nextToken {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Sources/HederaProtobufs/Services/token_create.pb.swift b/Sources/HederaProtobufs/Services/token_create.pb.swift index 1201fba3..8ec305b6 100644 --- a/Sources/HederaProtobufs/Services/token_create.pb.swift +++ b/Sources/HederaProtobufs/Services/token_create.pb.swift @@ -364,7 +364,15 @@ extension Proto_TokenCreateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf var _metadata: Data = Data() var _metadataKey: Proto_Key? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/token_get_info.pb.swift b/Sources/HederaProtobufs/Services/token_get_info.pb.swift index 18fb642a..6eddd75b 100644 --- a/Sources/HederaProtobufs/Services/token_get_info.pb.swift +++ b/Sources/HederaProtobufs/Services/token_get_info.pb.swift @@ -490,7 +490,15 @@ extension Proto_TokenInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen var _metadata: Data = Data() var _metadataKey: Proto_Key? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/token_get_nft_info.pb.swift b/Sources/HederaProtobufs/Services/token_get_nft_info.pb.swift index d513a250..5162e836 100644 --- a/Sources/HederaProtobufs/Services/token_get_nft_info.pb.swift +++ b/Sources/HederaProtobufs/Services/token_get_nft_info.pb.swift @@ -294,7 +294,15 @@ extension Proto_TokenGetNftInfoResponse: SwiftProtobuf.Message, SwiftProtobuf._M var _header: Proto_ResponseHeader? = nil var _nft: Proto_TokenNftInfo? = nil - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Sources/HederaProtobufs/Services/token_update.pb.swift b/Sources/HederaProtobufs/Services/token_update.pb.swift index 344f61f7..41bbd503 100644 --- a/Sources/HederaProtobufs/Services/token_update.pb.swift +++ b/Sources/HederaProtobufs/Services/token_update.pb.swift @@ -242,6 +242,13 @@ public struct Proto_TokenUpdateTransactionBody { /// Clears the value of `metadataKey`. Subsequent reads from it will return its default value. public mutating func clearMetadataKey() {_uniqueStorage()._metadataKey = nil} + ///* + /// Determines whether the system should check the validity of the passed keys for update. + public var keyVerificationMode: Proto_TokenKeyValidation { + get {return _storage._keyVerificationMode} + set {_uniqueStorage()._keyVerificationMode = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -277,6 +284,7 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf 15: .standard(proto: "pause_key"), 16: .same(proto: "metadata"), 17: .standard(proto: "metadata_key"), + 18: .standard(proto: "key_verification_mode"), ] fileprivate class _StorageClass { @@ -297,8 +305,17 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf var _pauseKey: Proto_Key? = nil var _metadata: SwiftProtobuf.Google_Protobuf_BytesValue? = nil var _metadataKey: Proto_Key? = nil - - static let defaultInstance = _StorageClass() + var _keyVerificationMode: Proto_TokenKeyValidation = .fullValidation + + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} @@ -320,6 +337,7 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf _pauseKey = source._pauseKey _metadata = source._metadata _metadataKey = source._metadataKey + _keyVerificationMode = source._keyVerificationMode } } @@ -355,6 +373,7 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf case 15: try { try decoder.decodeSingularMessageField(value: &_storage._pauseKey) }() case 16: try { try decoder.decodeSingularMessageField(value: &_storage._metadata) }() case 17: try { try decoder.decodeSingularMessageField(value: &_storage._metadataKey) }() + case 18: try { try decoder.decodeSingularEnumField(value: &_storage._keyVerificationMode) }() default: break } } @@ -418,6 +437,9 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf try { if let v = _storage._metadataKey { try visitor.visitSingularMessageField(value: v, fieldNumber: 17) } }() + if _storage._keyVerificationMode != .fullValidation { + try visitor.visitSingularEnumField(value: _storage._keyVerificationMode, fieldNumber: 18) + } } try unknownFields.traverse(visitor: &visitor) } @@ -444,6 +466,7 @@ extension Proto_TokenUpdateTransactionBody: SwiftProtobuf.Message, SwiftProtobuf if _storage._pauseKey != rhs_storage._pauseKey {return false} if _storage._metadata != rhs_storage._metadata {return false} if _storage._metadataKey != rhs_storage._metadataKey {return false} + if _storage._keyVerificationMode != rhs_storage._keyVerificationMode {return false} return true } if !storagesAreEqual {return false} diff --git a/Sources/HederaProtobufs/Services/transaction_body.pb.swift b/Sources/HederaProtobufs/Services/transaction_body.pb.swift index 2826709c..049a9842 100644 --- a/Sources/HederaProtobufs/Services/transaction_body.pb.swift +++ b/Sources/HederaProtobufs/Services/transaction_body.pb.swift @@ -552,6 +552,36 @@ public struct Proto_TransactionBody { set {_uniqueStorage()._data = .tokenUpdateNfts(newValue)} } + ///* + /// A transaction body for a `createNode` request. + public var nodeCreate: Proto_NodeCreateTransactionBody { + get { + if case .nodeCreate(let v)? = _storage._data {return v} + return Proto_NodeCreateTransactionBody() + } + set {_uniqueStorage()._data = .nodeCreate(newValue)} + } + + ///* + /// A transaction body for an `updateNode` request. + public var nodeUpdate: Proto_NodeUpdateTransactionBody { + get { + if case .nodeUpdate(let v)? = _storage._data {return v} + return Proto_NodeUpdateTransactionBody() + } + set {_uniqueStorage()._data = .nodeUpdate(newValue)} + } + + ///* + /// A transaction body for a `deleteNode` request. + public var nodeDelete: Proto_NodeDeleteTransactionBody { + get { + if case .nodeDelete(let v)? = _storage._data {return v} + return Proto_NodeDeleteTransactionBody() + } + set {_uniqueStorage()._data = .nodeDelete(newValue)} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() ///* @@ -695,6 +725,15 @@ public struct Proto_TransactionBody { ///* /// Update the metadata of one or more NFT's of a specific token type. case tokenUpdateNfts(Proto_TokenUpdateNftsTransactionBody) + ///* + /// A transaction body for a `createNode` request. + case nodeCreate(Proto_NodeCreateTransactionBody) + ///* + /// A transaction body for an `updateNode` request. + case nodeUpdate(Proto_NodeUpdateTransactionBody) + ///* + /// A transaction body for a `deleteNode` request. + case nodeDelete(Proto_NodeDeleteTransactionBody) #if !swift(>=4.1) public static func ==(lhs: Proto_TransactionBody.OneOf_Data, rhs: Proto_TransactionBody.OneOf_Data) -> Bool { @@ -886,6 +925,18 @@ public struct Proto_TransactionBody { guard case .tokenUpdateNfts(let l) = lhs, case .tokenUpdateNfts(let r) = rhs else { preconditionFailure() } return l == r }() + case (.nodeCreate, .nodeCreate): return { + guard case .nodeCreate(let l) = lhs, case .nodeCreate(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeUpdate, .nodeUpdate): return { + guard case .nodeUpdate(let l) = lhs, case .nodeUpdate(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeDelete, .nodeDelete): return { + guard case .nodeDelete(let l) = lhs, case .nodeDelete(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -961,6 +1012,9 @@ extension Proto_TransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageIm 51: .standard(proto: "node_stake_update"), 52: .standard(proto: "util_prng"), 53: .standard(proto: "token_update_nfts"), + 54: .same(proto: "nodeCreate"), + 55: .same(proto: "nodeUpdate"), + 56: .same(proto: "nodeDelete"), ] fileprivate class _StorageClass { @@ -972,7 +1026,15 @@ extension Proto_TransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageIm var _memo: String = String() var _data: Proto_TransactionBody.OneOf_Data? - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} @@ -1606,6 +1668,45 @@ extension Proto_TransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageIm _storage._data = .tokenUpdateNfts(v) } }() + case 54: try { + var v: Proto_NodeCreateTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeCreate(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeCreate(v) + } + }() + case 55: try { + var v: Proto_NodeUpdateTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeUpdate(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeUpdate(v) + } + }() + case 56: try { + var v: Proto_NodeDeleteTransactionBody? + var hadOneofValue = false + if let current = _storage._data { + hadOneofValue = true + if case .nodeDelete(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._data = .nodeDelete(v) + } + }() default: break } } @@ -1821,6 +1922,18 @@ extension Proto_TransactionBody: SwiftProtobuf.Message, SwiftProtobuf._MessageIm guard case .tokenUpdateNfts(let v)? = _storage._data else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 53) }() + case .nodeCreate?: try { + guard case .nodeCreate(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 54) + }() + case .nodeUpdate?: try { + guard case .nodeUpdate(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 55) + }() + case .nodeDelete?: try { + guard case .nodeDelete(let v)? = _storage._data else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 56) + }() case nil: break } } diff --git a/Sources/HederaProtobufs/Services/transaction_receipt.pb.swift b/Sources/HederaProtobufs/Services/transaction_receipt.pb.swift index 56ab5bc7..8abf6d8d 100644 --- a/Sources/HederaProtobufs/Services/transaction_receipt.pb.swift +++ b/Sources/HederaProtobufs/Services/transaction_receipt.pb.swift @@ -218,6 +218,13 @@ public struct Proto_TransactionReceipt { set {_uniqueStorage()._serialNumbers = newValue} } + ///* + /// In the receipt of a NodeCreate, NodeUpdate, NodeDelete, the id of the newly created node. + public var nodeID: UInt64 { + get {return _storage._nodeID} + set {_uniqueStorage()._nodeID = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -250,6 +257,7 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag 12: .same(proto: "scheduleID"), 13: .same(proto: "scheduledTransactionID"), 14: .same(proto: "serialNumbers"), + 15: .standard(proto: "node_id"), ] fileprivate class _StorageClass { @@ -267,8 +275,17 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag var _scheduleID: Proto_ScheduleID? = nil var _scheduledTransactionID: Proto_TransactionID? = nil var _serialNumbers: [Int64] = [] - - static let defaultInstance = _StorageClass() + var _nodeID: UInt64 = 0 + + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} @@ -287,6 +304,7 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag _scheduleID = source._scheduleID _scheduledTransactionID = source._scheduledTransactionID _serialNumbers = source._serialNumbers + _nodeID = source._nodeID } } @@ -319,6 +337,7 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag case 12: try { try decoder.decodeSingularMessageField(value: &_storage._scheduleID) }() case 13: try { try decoder.decodeSingularMessageField(value: &_storage._scheduledTransactionID) }() case 14: try { try decoder.decodeRepeatedInt64Field(value: &_storage._serialNumbers) }() + case 15: try { try decoder.decodeSingularUInt64Field(value: &_storage._nodeID) }() default: break } } @@ -373,6 +392,9 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag if !_storage._serialNumbers.isEmpty { try visitor.visitPackedInt64Field(value: _storage._serialNumbers, fieldNumber: 14) } + if _storage._nodeID != 0 { + try visitor.visitSingularUInt64Field(value: _storage._nodeID, fieldNumber: 15) + } } try unknownFields.traverse(visitor: &visitor) } @@ -396,6 +418,7 @@ extension Proto_TransactionReceipt: SwiftProtobuf.Message, SwiftProtobuf._Messag if _storage._scheduleID != rhs_storage._scheduleID {return false} if _storage._scheduledTransactionID != rhs_storage._scheduledTransactionID {return false} if _storage._serialNumbers != rhs_storage._serialNumbers {return false} + if _storage._nodeID != rhs_storage._nodeID {return false} return true } if !storagesAreEqual {return false} diff --git a/Sources/HederaProtobufs/Services/transaction_record.pb.swift b/Sources/HederaProtobufs/Services/transaction_record.pb.swift index 721ce80c..4c42bdce 100644 --- a/Sources/HederaProtobufs/Services/transaction_record.pb.swift +++ b/Sources/HederaProtobufs/Services/transaction_record.pb.swift @@ -345,7 +345,15 @@ extension Proto_TransactionRecord: SwiftProtobuf.Message, SwiftProtobuf._Message var _entropy: Proto_TransactionRecord.OneOf_Entropy? var _evmAddress: Data = Data() - static let defaultInstance = _StorageClass() + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif private init() {} diff --git a/Tests/HederaE2ETests/Token/TokenUpdate.swift b/Tests/HederaE2ETests/Token/TokenUpdate.swift index fd8ccd22..e59dd79b 100644 --- a/Tests/HederaE2ETests/Token/TokenUpdate.swift +++ b/Tests/HederaE2ETests/Token/TokenUpdate.swift @@ -103,6 +103,7 @@ internal final class TokenUpdate: XCTestCase { .name("ffff") .symbol("F") .tokenType(TokenType.fungibleCommon) + .expirationTime(.now + .minutes(5)) .treasuryAccountId(testEnv.operator.accountId) .decimals(3) .initialSupply(100000) @@ -135,4 +136,1532 @@ internal final class TokenUpdate: XCTestCase { XCTAssertEqual(tokenInfoAfterMetadataUpdate.metadata, updatedMetadata) } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Make a token immutable when updating keys to an empty KeyList, signing with an Admin Key, + // and setting the key verification mode to NO_VALIDATION + internal func testUpdateKeysWithAdminSigAndNoValidation() async throws { + let testEnv = try TestEnvironment.nonFree + + let adminKey = PrivateKey.generateEd25519() + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(adminKey) + + // Create the token with all keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let emptyKeyList = KeyList() + + // Update all lower-privilege keys for token with empty key list, + // signing with admin key, and verifying with no validation. + _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.keyList(emptyKeyList)) + .freezeKey(.keyList(emptyKeyList)) + .wipeKey(.keyList(emptyKeyList)) + .kycKey(.keyList(emptyKeyList)) + .supplyKey(.keyList(emptyKeyList)) + .pauseKey(.keyList(emptyKeyList)) + .feeScheduleKey(.keyList(emptyKeyList)) + .metadataKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.adminKey!) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertNil(tokenInfo.adminKey) + XCTAssertNil(tokenInfo.freezeKey) + XCTAssertNil(tokenInfo.wipeKey) + XCTAssertNil(tokenInfo.kycKey) + XCTAssertNil(tokenInfo.supplyKey) + XCTAssertNil(tokenInfo.pauseKey) + XCTAssertNil(tokenInfo.feeScheduleKey) + XCTAssertNil(tokenInfo.metadataKey) + + _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can remove all of token’s lower-privilege keys when updating keys to an empty KeyList, + // signing with an Admin Key, and setting the key verification mode to FULL_VALIDATION + internal func testRemoveKeysWithAdminSigAndFullValidation() async throws { + let testEnv = try TestEnvironment.nonFree + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(PrivateKey.generateEd25519()) + + // Create the token with all keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let emptyKeyList = KeyList() + + // Update all lower-privilege keys for token with empty key list, + // signing with admin key, and verifying with full validation. + _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.keyList(emptyKeyList)) + .freezeKey(.keyList(emptyKeyList)) + .wipeKey(.keyList(emptyKeyList)) + .kycKey(.keyList(emptyKeyList)) + .supplyKey(.keyList(emptyKeyList)) + .pauseKey(.keyList(emptyKeyList)) + .feeScheduleKey(.keyList(emptyKeyList)) + .metadataKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.adminKey!) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertNil(tokenInfo.adminKey) + XCTAssertNil(tokenInfo.freezeKey) + XCTAssertNil(tokenInfo.wipeKey) + XCTAssertNil(tokenInfo.kycKey) + XCTAssertNil(tokenInfo.supplyKey) + XCTAssertNil(tokenInfo.pauseKey) + XCTAssertNil(tokenInfo.feeScheduleKey) + XCTAssertNil(tokenInfo.metadataKey) + + _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can update all of token’s lower-privilege keys to an unusable key (i.e. all-zeros key), + // when signing with an Admin Key, and setting the key verification mode to FULL_VALIDATION, and then revert previous keys + internal func testRevertKeysFromUnusableWithAdminSigAndFullValidation() async throws { + let testEnv = try TestEnvironment.nonFree + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(PrivateKey.generateEd25519()) + + // Create the token with all keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update all lower-privilege keys for token with invalid zeros key, + // signing with admin key, and verifying with full validation. + + _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .wipeKey(.single(unusableKey)) + .kycKey(.single(unusableKey)) + .supplyKey(.single(unusableKey)) + .pauseKey(.single(unusableKey)) + .feeScheduleKey(.single(unusableKey)) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.adminKey!) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfo.freezeKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.wipeKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.kycKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.supplyKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.pauseKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.feeScheduleKey, .single(unusableKey)) + + // Update all lower-privilege keys for token with invalid zeros key, + // signing with admin key, and verifying with full validation. + _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(keys.freezeKey.publicKey)) + .wipeKey(.single(keys.wipeKey.publicKey)) + .kycKey(.single(keys.kycKey.publicKey)) + .supplyKey(.single(keys.supplyKey.publicKey)) + .pauseKey(.single(keys.pauseKey.publicKey)) + .feeScheduleKey(.single(keys.feeScheduleKey.publicKey)) + .metadataKey(.single(keys.metadataKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.adminKey!) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfoAfterUpdate = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfoAfterUpdate.freezeKey, .single(keys.freezeKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.wipeKey, .single(keys.wipeKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.kycKey, .single(keys.kycKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.supplyKey, .single(keys.supplyKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.pauseKey, .single(keys.pauseKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.feeScheduleKey, .single(keys.feeScheduleKey.publicKey)) + XCTAssertEqual(tokenInfoAfterUpdate.metadataKey, .single(keys.metadataKey.publicKey)) + + _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can update all of token’s lower-privilege keys when signing with an Admin Key + // and new respective lower-privilege key, and setting key verification mode to FULL_VALIDATION + internal func testUpdateLowPrivilegeKeysWithAdminSigAndFullValidation() async throws { + let testEnv = try TestEnvironment.nonFree + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(PrivateKey.generateEd25519()) + + // New Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let newKeys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Update all lower-privilege keys for token with new lower-privilege keys, + // signing with admin key and new lower-privilege keys, and verifying with full validation. + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(newKeys.freezeKey.publicKey)) + .wipeKey(.single(newKeys.wipeKey.publicKey)) + .kycKey(.single(newKeys.kycKey.publicKey)) + .supplyKey(.single(newKeys.supplyKey.publicKey)) + .pauseKey(.single(newKeys.pauseKey.publicKey)) + .feeScheduleKey(.single(newKeys.feeScheduleKey.publicKey)) + .metadataKey(.single(newKeys.metadataKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.adminKey!) + .sign(newKeys.freezeKey) + .sign(newKeys.wipeKey) + .sign(newKeys.kycKey) + .sign(newKeys.supplyKey) + .sign(newKeys.pauseKey) + .sign(newKeys.feeScheduleKey) + .sign(newKeys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfoAfterNewKeysUpdate = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.freezeKey, .single(newKeys.freezeKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.wipeKey, .single(newKeys.wipeKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.kycKey, .single(newKeys.kycKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.supplyKey, .single(newKeys.supplyKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.pauseKey, .single(newKeys.pauseKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.feeScheduleKey, .single(newKeys.feeScheduleKey.publicKey)) + XCTAssertEqual(tokenInfoAfterNewKeysUpdate.metadataKey, .single(newKeys.metadataKey.publicKey)) + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot make a token immutable when updating keys to an empty KeyList, + // signing with a key that is different from an Admin Key, and setting the key verification mode to NO_VALIDATION + internal func testUpdateToEmptyKeyListWithDifferentKeySignAndNoValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(PrivateKey.generateEd25519()) + + // Create the token with all keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let emptyKeyList = KeyList() + + // Fails to update the immutable token keys to empty keylist without admin signature (sign implicitly with operator key). + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot make a token immutable when updating keys to an unusable key (i.e. all-zeros key), + // signing with a key that is different from an Admin Key, and setting the key verification mode to NO_VALIDATION + internal func testUpdateToUsuableKeyWithDifferentKeySigFailsAndNoValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Admin, Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys(PrivateKey.generateEd25519()) + + // Create a token with the all keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Fails to update the immutable token keys to unusable key without admin signature (sign implicitly with operator key). + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot update the Admin Key to an unusable key (i.e. all-zeros key), + // signing with an Admin Key, and setting the key verification mode to NO_VALIDATION + internal func testUpdateAdminKeytoUnusableKeyAndNoValidationFail() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Admin and Supply keys. + let adminKey = PrivateKey.generateEd25519() + let supplyKey = PrivateKey.generateEd25519() + + let tx = try await TokenCreateTransaction() + .name("Test NFT") + .symbol("TNFT") + .tokenType(TokenType.nonFungibleUnique) + .expirationTime(.now + .minutes(5)) + .treasuryAccountId(testEnv.operator.accountId) + .adminKey(.single(adminKey.publicKey)) + .supplyKey(.single(supplyKey.publicKey)) + .freezeWith(testEnv.client) + .sign(adminKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenId = try XCTUnwrap(tx.tokenId) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfo.adminKey, .single(adminKey.publicKey)) + + // Generate an unusable key. + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update the Admin Key to an unusable key (i.e., all-zeros key), + // signing with an Admin Key, and setting the key verification mode to NO_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .adminKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(adminKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can update all of token’s lower-privilege keys to an unusable key (i.e. all-zeros key), + // when signing with a respective lower-privilege key, and setting the key verification mode to NO_VALIDATION + internal func testUpdateLowerPrivilegeKeysToUnusableKeyAndNoValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Generate an unusable key. + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update all of token’s lower-privilege keys to an unusable key (i.e., all-zeros key), + // when signing with a respective lower-privilege key, + // and setting the key verification mode to NO_VALIDATION + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .wipeKey(.single(unusableKey)) + .kycKey(.single(unusableKey)) + .supplyKey(.single(unusableKey)) + .pauseKey(.single(unusableKey)) + .feeScheduleKey(.single(unusableKey)) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .sign(keys.wipeKey) + .sign(keys.kycKey) + .sign(keys.supplyKey) + .sign(keys.pauseKey) + .sign(keys.feeScheduleKey) + .sign(keys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfo.freezeKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.wipeKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.kycKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.supplyKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.pauseKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.feeScheduleKey, .single(unusableKey)) + XCTAssertEqual(tokenInfo.metadataKey, .single(unusableKey)) + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can update all of token’s lower-privilege keys when signing with an old lower-privilege key + // and with a new lower-privilege key, and setting key verification mode to FULL_VALIDATION + internal func testUpdateLowerPrivilegeKeysWithFullValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // New Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let newKeys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Update all of token’s lower-privilege keys when signing with an old respective lower-privilege key, + // and setting key verification mode to NO_VALIDATION + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(newKeys.freezeKey.publicKey)) + .wipeKey(.single(newKeys.wipeKey.publicKey)) + .kycKey(.single(newKeys.kycKey.publicKey)) + .supplyKey(.single(newKeys.supplyKey.publicKey)) + .pauseKey(.single(newKeys.pauseKey.publicKey)) + .feeScheduleKey(.single(newKeys.feeScheduleKey.publicKey)) + .metadataKey(.single(newKeys.metadataKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .sign(keys.wipeKey) + .sign(keys.kycKey) + .sign(keys.supplyKey) + .sign(keys.pauseKey) + .sign(keys.feeScheduleKey) + .sign(keys.metadataKey) + .sign(newKeys.freezeKey) + .sign(newKeys.wipeKey) + .sign(newKeys.kycKey) + .sign(newKeys.supplyKey) + .sign(newKeys.pauseKey) + .sign(newKeys.feeScheduleKey) + .sign(newKeys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfo.freezeKey, .single(newKeys.freezeKey.publicKey)) + XCTAssertEqual(tokenInfo.wipeKey, .single(newKeys.wipeKey.publicKey)) + XCTAssertEqual(tokenInfo.kycKey, .single(newKeys.kycKey.publicKey)) + XCTAssertEqual(tokenInfo.supplyKey, .single(newKeys.supplyKey.publicKey)) + XCTAssertEqual(tokenInfo.pauseKey, .single(newKeys.pauseKey.publicKey)) + XCTAssertEqual(tokenInfo.feeScheduleKey, .single(newKeys.feeScheduleKey.publicKey)) + XCTAssertEqual(tokenInfo.metadataKey, .single(newKeys.metadataKey.publicKey)) + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Can update all of token’s lower-privilege keys when signing ONLY with an old lower-privilege key, + // and setting key verification mode to NO_VALIDATION + internal func testUpdateLowerPrivilegeKeysWithOldKeysAndNoValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // New Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let newKeys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Update all of token’s lower-privilege keys when signing with all older respective lower-privilege keys, + // and setting key verification mode to NO_VALIDATION + let _ = try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(newKeys.freezeKey.publicKey)) + .wipeKey(.single(newKeys.wipeKey.publicKey)) + .kycKey(.single(newKeys.kycKey.publicKey)) + .supplyKey(.single(newKeys.supplyKey.publicKey)) + .pauseKey(.single(newKeys.pauseKey.publicKey)) + .feeScheduleKey(.single(newKeys.feeScheduleKey.publicKey)) + .metadataKey(.single(newKeys.metadataKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .sign(keys.wipeKey) + .sign(keys.kycKey) + .sign(keys.supplyKey) + .sign(keys.pauseKey) + .sign(keys.feeScheduleKey) + .sign(keys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + XCTAssertEqual(tokenInfo.freezeKey, .single(newKeys.freezeKey.publicKey)) + XCTAssertEqual(tokenInfo.wipeKey, .single(newKeys.wipeKey.publicKey)) + XCTAssertEqual(tokenInfo.kycKey, .single(newKeys.kycKey.publicKey)) + XCTAssertEqual(tokenInfo.supplyKey, .single(newKeys.supplyKey.publicKey)) + XCTAssertEqual(tokenInfo.pauseKey, .single(newKeys.pauseKey.publicKey)) + XCTAssertEqual(tokenInfo.feeScheduleKey, .single(newKeys.feeScheduleKey.publicKey)) + XCTAssertEqual(tokenInfo.metadataKey, .single(newKeys.metadataKey.publicKey)) + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot remove all of token’s lower-privilege keys when updating them to an empty KeyList, + // signing with a respective lower-privilege key, and setting the key verification mode to NO_VALIDATION + internal func testRemoveLowerPrivilegeKeysWithOldKeysSigAndNoValidationFails() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let emptyKeyList = KeyList() + + // Remove all of token’s lower-privilege keys + // when updating them to an empty KeyList (trying to remove keys one by one to check all errors), + // signing with a respective lower-privilege key, + // and setting the key verification mode to NO_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.wipeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.pauseKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.kycKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.supplyKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.feeScheduleKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.keyList(emptyKeyList)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .freezeWith(testEnv.client) + .sign(keys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .tokenIsImmutable) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot update all of token’s lower-privilege keys to an unusable key (i.e. all-zeros key), + // when signing with a key that is different from a respective lower-privilege key, and setting + // the key verification mode to NO_VALIDATION + func testUpdateToLowPrivilegeKeysUsusableKeyWithDifferentKeySigAndNoValidationFails() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Generate an unusable key. + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update all of token’s lower-privilege keys to an unusable key (i.e., all-zeros key), + // when signing with a respective lower-privilege key, + // and setting the key verification mode to NO_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.noValidation) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot update all of token’s lower-privilege keys to an unusable key (i.e. all-zeros key), + // when signing ONLY with an old respective lower-privilege key, and setting the key + // verification mode to FULL_VALIDATION + func testUpdateLowerPrivilegeKeysToUnusableKeysAndFullValidationFails() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update all of token’s lower-privilege keys to an unusable key (i.e., all-zeros key) + // (trying to remove keys one by one to check all errors), + // signing ONLY with an old respective lower-privilege key, + // and setting the key verification mode to FULL_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.wipeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.pauseKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.kycKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.supplyKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.feeScheduleKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot update all of token’s lower-privilege keys to an unusable key (i.e. all-zeros key), + // when signing with an old respective lower-privilege key and new respective lower-privilege key, + // and setting the key verification mode to FULL_VALIDATION + internal func testUpdateToUnusableKeyWithOldAndNewKeysAndFullValidationFails() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // New Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let newKeys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Generate an unusable key. + let unusableKey = try PublicKey.fromStringEd25519( + "0x0000000000000000000000000000000000000000000000000000000000000000") + + // Update all of token’s lower-privilege keys to an unusable key (i.e., all-zeros key) + // (trying to remove keys one by one to check all errors), + // signing with an old respective lower-privilege key and new respective lower-privilege key, + // and setting the key verification mode to FULL_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.wipeKey) + .sign(newKeys.wipeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .sign(newKeys.freezeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.pauseKey) + .sign(newKeys.pauseKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.kycKey) + .sign(newKeys.kycKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.supplyKey) + .sign(newKeys.supplyKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.feeScheduleKey) + .sign(newKeys.feeScheduleKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.single(unusableKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.metadataKey) + .sign(newKeys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } + + // HIP-540 (https://hips.hedera.com/hip/hip-540) + // Cannot update all of token’s lower-privilege keys, when signing ONLY with an + // old respective lower-privilege key, and setting the key verification mode to + // FULL_VALIDATION + internal func testUpdateToNewKeysWithOldKeysSigAndFullValidation() async throws { + let testEnv: NonfreeTestEnvironment = try TestEnvironment.nonFree + + // Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let keys = generateKeys() + + // New Freeze, Wipe, Kyc, Supply, Pause, Fee Schedule, and Metadata keys. + let newKeys = generateKeys() + + // Create the NFT with all of token’s lower-privilege keys. + let tokenId = try await createTokenWithKeys(testEnv, keys) + + // Update all of token’s lower-privilege keys + // (trying to update keys one by one to check all errors), + // signing ONLY with an old respective lower-privilege key, + // and setting the key verification mode to FULL_VALIDATION + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .wipeKey(.single(newKeys.wipeKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.wipeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .freezeKey(.single(newKeys.freezeKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.freezeKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .pauseKey(.single(newKeys.pauseKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.pauseKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .kycKey(.single(newKeys.kycKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.kycKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .supplyKey(.single(newKeys.supplyKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.supplyKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .feeScheduleKey(.single(newKeys.feeScheduleKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.feeScheduleKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + await assertThrowsHErrorAsync( + try await TokenUpdateTransaction() + .tokenId(tokenId) + .metadataKey(.single(newKeys.metadataKey.publicKey)) + .keyVerificationMode(TokenKeyValidation.fullValidation) + .freezeWith(testEnv.client) + .sign(keys.metadataKey) + .execute(testEnv.client) + .getReceipt(testEnv.client) + ) { error in + guard case .receiptStatus(let status, transactionId: _) = error.kind else { + XCTFail("`\(error.kind)` is not `.receiptStatus`") + return + } + + XCTAssertEqual(status, .invalidSignature) + } + + let _ = try await TokenDeleteTransaction().tokenId(tokenId).execute(testEnv.client) + } +} + +struct Keys { + let adminKey: PrivateKey? + let freezeKey: PrivateKey + let wipeKey: PrivateKey + let supplyKey: PrivateKey + let pauseKey: PrivateKey + let kycKey: PrivateKey + let feeScheduleKey: PrivateKey + let metadataKey: PrivateKey +} + +func generateKeys(_ adminKey: PrivateKey? = nil) -> Keys { + .init( + adminKey: adminKey, freezeKey: PrivateKey.generateEd25519(), wipeKey: PrivateKey.generateEd25519(), + supplyKey: PrivateKey.generateEd25519(), pauseKey: PrivateKey.generateEd25519(), + kycKey: PrivateKey.generateEd25519(), feeScheduleKey: PrivateKey.generateEd25519(), + metadataKey: PrivateKey.generateEd25519()) +} + +func createTokenWithKeys(_ testEnv: NonfreeTestEnvironment, _ keys: Keys) async throws -> TokenId { + let tx = TokenCreateTransaction() + .name("Test NFT") + .symbol("TNFT") + .tokenType(TokenType.nonFungibleUnique) + .expirationTime(.now + .minutes(5)) + .treasuryAccountId(testEnv.operator.accountId) + .freezeKey(.single(keys.freezeKey.publicKey)) + .wipeKey(.single(keys.wipeKey.publicKey)) + .supplyKey(.single(keys.supplyKey.publicKey)) + .pauseKey(.single(keys.pauseKey.publicKey)) + .kycKey(.single(keys.kycKey.publicKey)) + .feeScheduleKey(.single(keys.feeScheduleKey.publicKey)) + .metadataKey(.single(keys.metadataKey.publicKey)) + + if let adminKey = keys.adminKey { + try tx.adminKey(.single(adminKey.publicKey)).freezeWith(testEnv.client).sign(adminKey) + } + + let tokenId = try await tx.execute(testEnv.client).getReceipt(testEnv.client).tokenId! + + let tokenInfo = try await TokenInfoQuery().tokenId(tokenId).execute(testEnv.client) + + if let adminKey = keys.adminKey { + XCTAssertEqual(tokenInfo.adminKey, .single(adminKey.publicKey)) + } else { + XCTAssertNil(tokenInfo.adminKey) + } + + XCTAssertEqual(tokenInfo.freezeKey, .single(keys.freezeKey.publicKey)) + XCTAssertEqual(tokenInfo.wipeKey, .single(keys.wipeKey.publicKey)) + XCTAssertEqual(tokenInfo.supplyKey, .single(keys.supplyKey.publicKey)) + XCTAssertEqual(tokenInfo.pauseKey, .single(keys.pauseKey.publicKey)) + XCTAssertEqual(tokenInfo.kycKey, .single(keys.kycKey.publicKey)) + XCTAssertEqual(tokenInfo.feeScheduleKey, .single(keys.feeScheduleKey.publicKey)) + XCTAssertEqual(tokenInfo.metadataKey, .single(keys.metadataKey.publicKey)) + + return tokenId } diff --git a/Tests/HederaTests/StatusTests.swift b/Tests/HederaTests/StatusTests.swift index 4f699bcb..9914aeda 100644 --- a/Tests/HederaTests/StatusTests.swift +++ b/Tests/HederaTests/StatusTests.swift @@ -26,7 +26,7 @@ import XCTest internal final class StatusTests: XCTestCase { internal func testToResponseCode() { for code in Proto_ResponseCodeEnum.allCases { - if code == Proto_ResponseCodeEnum.unrecognized(-1) { + if code == Proto_ResponseCodeEnum.UNRECOGNIZED(-1) { continue } diff --git a/protobufs b/protobufs index e650477f..17fb1486 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit e650477fc5f061fb9229db67944a7911fa5c65bc +Subproject commit 17fb148652b1e2badda1c5cdff531f0fcf7f4c55