Skip to content

Commit cd53c1a

Browse files
committed
fix: requested changes
Signed-off-by: Ricky Saechao <ricky@launchbadge.com>
1 parent 10fb994 commit cd53c1a

21 files changed

+124
-301
lines changed

Sources/Hedera/Account/AccountBalanceQuery.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ public final class AccountBalanceQuery: Query<AccountBalance> {
9191
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
9292
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)
9393

94-
guard case .cryptogetAccountBalance(let proto) = response else {
94+
guard case .cryptogetAccountBalance(var proto) = response else {
9595
throw HError.fromProtobuf("unexpected \(response) received, expected `cryptogetAccountBalance`")
9696
}
9797

98-
let accountId = try AccountId.fromProtobuf(proto.accountID)
99-
let tokenBalanceProto = try await mirrorNodeService.getTokenBalancesForAccount(String(accountId.num))
98+
let tokenBalanceProto = try await mirrorNodeService.getTokenBalancesForAccount(
99+
String(proto.accountID.accountNum))
100100

101-
return AccountBalance(
102-
accountId: accountId, hbars: .fromTinybars(Int64(proto.balance)),
103-
tokensInner: .fromProtobuf(tokenBalanceProto))
101+
proto.tokenBalances = tokenBalanceProto
102+
103+
return try .fromProtobuf(proto)
104104
}
105105

106106
public override func validateChecksums(on ledgerId: LedgerId) throws {

Sources/Hedera/Account/AccountId.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,6 @@ public struct AccountId: Sendable, EntityId, ValidateChecksums {
135135
public func toBytes() -> Data {
136136
toProtobufBytes()
137137
}
138-
139-
public func populateAccountIdNum(_ client: Client) async throws -> Self {
140-
let mirrorNodeGateway = try MirrorNodeGateway.forClient(client)
141-
let mirrorNodeService = MirrorNodeService(mirrorNodeGateway)
142-
143-
let accountNumFromMirror = try await mirrorNodeService.getAccountNum(self.evmAddress!.toString())
144-
145-
return Self(shard: shard, realm: realm, num: accountNumFromMirror)
146-
}
147138
}
148139

149140
extension AccountId: TryProtobufCodable {

Sources/Hedera/Account/AccountInfo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public struct AccountInfo: Sendable {
156156
/// Staking metadata for this account.
157157
public let staking: StakingInfo?
158158

159-
/// Staking metadata for this account.
159+
/// Token relationships for this account.
160160
public let tokenRelationships: [TokenId: TokenRelationship]
161161

162162
/// Decode `Self` from protobuf-encoded `bytes`.

Sources/Hedera/Account/AccountInfoQuery.swift

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,42 +65,16 @@ public final class AccountInfoQuery: Query<AccountInfo> {
6565
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
6666
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)
6767

68-
guard case .cryptoGetInfo(let proto) = response else {
68+
guard case .cryptoGetInfo(var proto) = response else {
6969
throw HError.fromProtobuf("unexpected \(response) received, expected `cryptoGetInfo`")
7070
}
7171

72-
let accountInfo = try AccountInfo.fromProtobuf(proto.accountInfo)
7372
let tokenRelationshipsProto = try await mirrorNodeService.getTokenRelationshipsForAccount(
74-
String(describing: accountInfo.accountId.num))
73+
String(describing: try AccountId.fromProtobuf(proto.accountInfo.accountID).num))
7574

76-
var tokenRelationships: [TokenId: TokenRelationship] = [:]
75+
proto.accountInfo.tokenRelationships = tokenRelationshipsProto
7776

78-
for relationship in tokenRelationshipsProto {
79-
tokenRelationships[.fromProtobuf(relationship.tokenID)] = try TokenRelationship.fromProtobuf(relationship)
80-
}
81-
82-
return AccountInfo(
83-
accountId: accountInfo.accountId,
84-
contractAccountId: accountInfo.contractAccountId,
85-
isDeleted: accountInfo.isDeleted,
86-
proxyAccountId: accountInfo.proxyAccountId,
87-
proxyReceived: accountInfo.proxyReceived,
88-
key: accountInfo.key,
89-
balance: accountInfo.balance,
90-
sendRecordThreshold: accountInfo.sendRecordThreshold,
91-
receiveRecordThreshold: accountInfo.receiveRecordThreshold,
92-
isReceiverSignatureRequired: accountInfo.isReceiverSignatureRequired,
93-
expirationTime: accountInfo.expirationTime,
94-
autoRenewPeriod: accountInfo.autoRenewPeriod,
95-
accountMemo: accountInfo.accountMemo,
96-
ownedNfts: accountInfo.ownedNfts,
97-
maxAutomaticTokenAssociations: accountInfo.maxAutomaticTokenAssociations,
98-
aliasKey: accountInfo.aliasKey,
99-
ethereumNonce: accountInfo.ethereumNonce,
100-
tokenRelationships: tokenRelationships,
101-
ledgerId: accountInfo.ledgerId,
102-
staking: accountInfo.staking
103-
)
77+
return try .fromProtobuf(proto.accountInfo)
10478
}
10579

10680
internal override func validateChecksums(on ledgerId: LedgerId) throws {

Sources/Hedera/ChunkedTransaction.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ extension ChunkedTransaction.FirstChunkView: Execute {
206206
self.transaction.regenerateTransactionId
207207
}
208208

209-
internal func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
209+
internal func makeRequest(
210+
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
211+
_ nodeAccountId: AccountId
212+
) throws -> (
210213
GrpcRequest, Context
211214
) {
212215
assert(transaction.isFrozen)
@@ -265,7 +268,10 @@ extension ChunkedTransaction.ChunkView: Execute {
265268
self.transaction.regenerateTransactionId
266269
}
267270

268-
internal func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
271+
internal func makeRequest(
272+
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
273+
_ nodeAccountId: AccountId
274+
) throws -> (
269275
GrpcRequest, Context
270276
) {
271277
assert(transaction.isFrozen)

Sources/Hedera/Contract/ContractId.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,6 @@ public struct ContractId: EntityId {
119119
public func toBytes() -> Data {
120120
toProtobufBytes()
121121
}
122-
123-
public func populateContractNum(_ client: Client) async throws -> Self {
124-
let address = try EvmAddress.fromBytes(self.evmAddress!)
125-
126-
let mirrorNodeGateway = try MirrorNodeGateway.forClient(client)
127-
let mirrorNodeService = MirrorNodeService(mirrorNodeGateway)
128-
129-
let contractNum = try await mirrorNodeService.getContractNum(address.toString())
130-
131-
return Self(shard: shard, realm: realm, num: contractNum)
132-
}
133122
}
134123

135124
#if compiler(>=5.7)

Sources/Hedera/Contract/ContractInfo.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public struct ContractInfo {
6363

6464
/// The tokens associated to the contract
6565
///
66-
/// Query mirror node
66+
/// Note: Query mirror node for token relationships.
6767
public let tokenRelationships: [TokenId: TokenRelationship]
6868

6969
/// Ledger ID for the network the response was returned from.
@@ -104,7 +104,7 @@ extension ContractInfo: TryProtobufCodable {
104104

105105
self.init(
106106
contractId: try .fromProtobuf(proto.contractID),
107-
accountId: try AccountId.fromProtobuf(proto.accountID),
107+
accountId: try .fromProtobuf(proto.accountID),
108108
contractAccountId: proto.contractAccountID,
109109
adminKey: try .fromProtobuf(adminKey),
110110
expirationTime: .fromProtobuf(expirationTime),

Sources/Hedera/Contract/ContractInfoQuery.swift

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public final class ContractInfoQuery: Query<ContractInfo> {
4242
}
4343

4444
internal override func toQueryProtobufWith(_ header: Proto_QueryHeader) -> Proto_Query {
45-
4645
.with { proto in
4746
proto.contractGetInfo = .with { proto in
4847
proto.header = header
@@ -62,37 +61,16 @@ public final class ContractInfoQuery: Query<ContractInfo> {
6261
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
6362
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)
6463

65-
guard case .contractGetInfo(let proto) = response else {
64+
guard case .contractGetInfo(var proto) = response else {
6665
throw HError.fromProtobuf("unexpected \(response) received, expected `contractGetInfo`")
6766
}
6867

69-
let contractInfo = try ContractInfo.fromProtobuf(proto.contractInfo)
7068
let tokenRelationshipsProto = try await mirrorNodeService.getTokenRelationshipsForAccount(
71-
String(describing: contractInfo.contractId.num))
72-
73-
var tokenRelationships: [TokenId: TokenRelationship] = [:]
69+
String(describing: proto.contractInfo.accountID.accountNum))
7470

75-
for relationship in tokenRelationshipsProto {
76-
tokenRelationships[.fromProtobuf(relationship.tokenID)] = try TokenRelationship.fromProtobuf(relationship)
77-
}
71+
proto.contractInfo.tokenRelationships = tokenRelationshipsProto
7872

79-
return ContractInfo(
80-
contractId: contractInfo.contractId,
81-
accountId: contractInfo.accountId,
82-
contractAccountId: contractInfo.contractAccountId,
83-
adminKey: contractInfo.adminKey,
84-
expirationTime: contractInfo.expirationTime,
85-
autoRenewPeriod: contractInfo.autoRenewPeriod,
86-
storage: contractInfo.storage,
87-
contractMemo: contractInfo.contractMemo,
88-
balance: contractInfo.balance,
89-
isDeleted: contractInfo.isDeleted,
90-
autoRenewAccountId: contractInfo.autoRenewAccountId,
91-
maxAutomaticTokenAssociations: contractInfo.maxAutomaticTokenAssociations,
92-
tokenRelationships: tokenRelationships,
93-
ledgerId: contractInfo.ledgerId,
94-
stakingInfo: contractInfo.stakingInfo
95-
)
73+
return try ContractInfo.fromProtobuf(proto.contractInfo)
9674
}
9775

9876
internal override func validateChecksums(on ledgerId: LedgerId) throws {

Sources/Hedera/Execute.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ internal protocol Execute {
6060
///
6161
/// A created request is cached per node until any request returns
6262
/// `TransactionExpired`; in which case, the request cache is cleared.
63-
func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
63+
func makeRequest(
64+
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
65+
_ nodeAccountId: AccountId
66+
) throws -> (
6467
GrpcRequest, Context
6568
)
6669

@@ -97,7 +100,8 @@ private struct ExecuteContext {
97100
fileprivate let network: Network
98101
fileprivate let backoffConfig: LegacyExponentialBackoff
99102
fileprivate let maxAttempts: Int
100-
fileprivate let client: Client
103+
fileprivate let ledgerId: LedgerId?
104+
fileprivate let mirrorNodeNetworks: [String]
101105
// timeout for a single grpc request.
102106
fileprivate let grpcTimeout: Duration?
103107
}
@@ -153,7 +157,8 @@ internal func executeAny<E: Execute & ValidateChecksums>(
153157
network: client.net,
154158
backoffConfig: backoffBuilder,
155159
maxAttempts: backoff.maxAttempts,
156-
client: client,
160+
ledgerId: client.ledgerId,
161+
mirrorNodeNetworks: client.mirrorNetwork,
157162
grpcTimeout: nil
158163
),
159164
executable: executable)
@@ -189,7 +194,8 @@ private func executeAnyInner<E: Execute>(
189194
}
190195

191196
let (nodeAccountId, channel) = ctx.network.channel(for: nodeIndex)
192-
let (request, context) = try executable.makeRequest(ctx.client, transactionId, nodeAccountId)
197+
let (request, context) = try executable.makeRequest(
198+
ctx.ledgerId, ctx.mirrorNodeNetworks, transactionId, nodeAccountId)
193199
let response: E.GrpcResponse
194200

195201
do {
@@ -313,7 +319,8 @@ private struct NodeIndexesGeneratorMap: AsyncSequence, AsyncIteratorProtocol {
313319
network: ctx.network,
314320
backoffConfig: ctx.backoffConfig,
315321
maxAttempts: ctx.maxAttempts,
316-
client: ctx.client,
322+
ledgerId: ctx.ledgerId,
323+
mirrorNodeNetworks: ctx.mirrorNodeNetworks,
317324
grpcTimeout: ctx.grpcTimeout
318325
),
319326
executable: request

Sources/Hedera/HError.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public struct HError: Error, CustomStringConvertible {
3232
case queryPaymentPreCheckStatus(status: Status, transactionId: TransactionId)
3333
case queryNoPaymentPreCheckStatus(status: Status)
3434
case basicParse
35+
case mirrorNodeQuery
3536
case keyParse
3637
case keyDerive
3738
case noPayerAccountOrTransactionId
@@ -86,6 +87,10 @@ public struct HError: Error, CustomStringConvertible {
8687
Self(kind: .basicParse, description: description)
8788
}
8889

90+
internal static func mirrorNodeQuery(_ description: String) -> Self {
91+
Self(kind: .mirrorNodeQuery, description: description)
92+
}
93+
8994
internal static func keyParse(_ description: String) -> Self {
9095
Self(kind: .keyParse, description: "failed to parse a key: \(description)")
9196
}

Sources/Hedera/MirrorNodeGateway.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ internal struct MirrorNodeGateway {
4545

4646
internal func getAccountInfo(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
4747
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
48-
self.mirrorNodeUrl, MirrorNodeRouter.accountsRoute, idOrAliasOrEvmAddress)
48+
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.accountInfoRoute, idOrAliasOrEvmAddress)
4949

5050
let responseBody = try await queryFromMirrorNode(fullApiUrl)
5151

@@ -56,7 +56,7 @@ internal struct MirrorNodeGateway {
5656

5757
internal func getContractInfo(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
5858
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
59-
self.mirrorNodeUrl, MirrorNodeRouter.contractsRoute, idOrAliasOrEvmAddress)
59+
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.contractInfoRoute, idOrAliasOrEvmAddress)
6060

6161
let responseBody = try await queryFromMirrorNode(fullApiUrl)
6262

@@ -67,7 +67,7 @@ internal struct MirrorNodeGateway {
6767

6868
internal func getAccountTokens(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
6969
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
70-
self.mirrorNodeUrl, MirrorNodeRouter.tokensAccountRoute, idOrAliasOrEvmAddress)
70+
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.tokenRelationshipsRoute, idOrAliasOrEvmAddress)
7171

7272
let responseBody = try await queryFromMirrorNode(fullApiUrl)
7373

@@ -82,6 +82,7 @@ internal struct MirrorNodeGateway {
8282
try? httpClient.syncShutdown()
8383
}
8484

85+
// Delay is needed to fetch data from the mirror node.
8586
if apiUrl.contains("127.0.0.1:5551") {
8687
try await Task.sleep(nanoseconds: 1_000_000_000 * 3)
8788
}
@@ -98,15 +99,11 @@ internal struct MirrorNodeGateway {
9899

99100
func deserializeJson(_ responseBody: String) async throws -> [String: Any] {
100101
guard let jsonData = responseBody.data(using: .utf8) else {
101-
throw NSError(
102-
domain: "InvalidResponseError", code: -1,
103-
userInfo: [NSLocalizedDescriptionKey: "Response body is not valid UTF-8"])
102+
throw HError.mirrorNodeQuery("Response body is not valid UTF-8")
104103
}
105104

106105
guard let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] else {
107-
throw NSError(
108-
domain: "InvalidResponseError", code: -1,
109-
userInfo: [NSLocalizedDescriptionKey: "Response body is not a valid JSON object"])
106+
throw HError.mirrorNodeQuery("Response body is not a valid JSON object")
110107
}
111108

112109
return jsonObject

Sources/Hedera/MirrorNodeRouter.swift

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,11 @@ internal struct MirrorNodeRouter {
3030

3131
static let localNodePort = "5551"
3232

33-
public static let accountsRoute = "accounts"
34-
public static let contractsRoute = "contracts"
35-
public static let tokensAccountRoute = "account_tokens"
36-
37-
static let routes: [String: String] = [
38-
accountsRoute: "/accounts/%@",
39-
contractsRoute: "/contracts/%@",
40-
tokensAccountRoute: "/accounts/%@/tokens",
41-
]
42-
43-
private func mirrorNodeRouter() {}
33+
public enum MirrorNodeRoute: String {
34+
case accountInfoRoute = "/accounts/%@"
35+
case contractInfoRoute = "/contracts/%@"
36+
case tokenRelationshipsRoute = "/accounts/%@/tokens"
37+
}
4438

4539
static func getMirrorNodeUrl(_ mirrorNetwork: [String], _ ledgerId: LedgerId?) throws -> String {
4640
var mirrorNodeAddress: String = ""
@@ -62,7 +56,7 @@ internal struct MirrorNodeRouter {
6256
return fullMirrorNodeUrl
6357
}
6458

65-
static func buildApiUrl(_ mirrorNodeUrl: String, _ route: String, _ id: String) -> String {
66-
return String("\(mirrorNodeUrl)\(apiVersion)\(String(format: "\(String(describing: routes[route]!))", id))")
59+
static func buildApiUrl(_ mirrorNodeUrl: String, _ route: MirrorNodeRoute, _ id: String) -> String {
60+
return String("\(mirrorNodeUrl)\(apiVersion)\(route.rawValue.replacingOccurrences(of: "%@", with: id))")
6761
}
6862
}

0 commit comments

Comments
 (0)