Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Sources/Network/FlowAccess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ extension Flow: FlowAccessProtocol {
return try await flow.accessAPI.ping()
}

public func getLatestBlockHeader() async throws -> BlockHeader {
return try await flow.accessAPI.getLatestBlockHeader()
public func getLatestBlockHeader(blockStatus: Flow.BlockStatus = .final) async throws -> BlockHeader {
return try await flow.accessAPI.getLatestBlockHeader(blockStatus: blockStatus)
}

public func getBlockHeaderById(id: ID) async throws -> BlockHeader {
Expand All @@ -24,8 +24,8 @@ extension Flow: FlowAccessProtocol {
return try await flow.accessAPI.getBlockHeaderByHeight(height: height)
}

public func getLatestBlock(sealed: Bool) async throws -> Block {
return try await flow.accessAPI.getLatestBlock(sealed: sealed)
public func getLatestBlock(blockStatus: Flow.BlockStatus = .final) async throws -> Block {
return try await flow.accessAPI.getLatestBlock(blockStatus: blockStatus)
}

public func getBlockById(id: ID) async throws -> Block {
Expand All @@ -52,8 +52,8 @@ extension Flow: FlowAccessProtocol {
return try await flow.accessAPI.getTransactionResultById(id: id)
}

public func getAccountAtLatestBlock(address: Address) async throws -> Account {
return try await flow.accessAPI.getAccountAtLatestBlock(address: address)
public func getAccountAtLatestBlock(address: Address, blockStatus: Flow.BlockStatus = .final) async throws -> Account {
return try await flow.accessAPI.getAccountAtLatestBlock(address: address, blockStatus: blockStatus)
}

public func getAccountByBlockHeight(address: Address, height: UInt64) async throws -> Account {
Expand All @@ -68,8 +68,8 @@ extension Flow: FlowAccessProtocol {
return try await flow.accessAPI.getEventsForBlockIds(type: type, ids: ids)
}

public func executeScriptAtLatestBlock(script: Script, arguments: [Argument]) async throws -> ScriptResponse {
return try await flow.accessAPI.executeScriptAtLatestBlock(script: script, arguments: arguments)
public func executeScriptAtLatestBlock(script: Script, arguments: [Argument], blockStatus: Flow.BlockStatus = .final) async throws -> ScriptResponse {
return try await flow.accessAPI.executeScriptAtLatestBlock(script: script, arguments: arguments, blockStatus: blockStatus)
}

public func getNetworkParameters() async throws -> ChainID {
Expand Down
45 changes: 29 additions & 16 deletions Sources/Network/FlowAccessProtocol.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// CadenceTypeTest
//
// Copyright 2022 Outblock Pty Ltd

Check warning on line 4 in Sources/Network/FlowAccessProtocol.swift

View workflow job for this annotation

GitHub Actions / lint

File Header Violation: Header comments should be consistent with project patterns (file_header)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,7 +42,7 @@

/// Get latest block header
/// - Returns: Most recent block header
func getLatestBlockHeader() async throws -> Flow.BlockHeader
func getLatestBlockHeader(blockStatus: Flow.BlockStatus) async throws -> Flow.BlockHeader

/// Get block header by ID
/// - Parameter id: Block identifier
Expand All @@ -51,7 +51,7 @@

func getBlockHeaderByHeight(height: UInt64) async throws -> Flow.BlockHeader

func getLatestBlock(sealed: Bool) async throws -> Flow.Block
func getLatestBlock(blockStatus: Flow.BlockStatus) async throws -> Flow.Block

func getBlockById(id: Flow.ID) async throws -> Flow.Block

Expand All @@ -65,13 +65,13 @@

func getTransactionResultById(id: Flow.ID) async throws -> Flow.TransactionResult

func getAccountAtLatestBlock(address: Flow.Address) async throws -> Flow.Account
func getAccountAtLatestBlock(address: Flow.Address, blockStatus: Flow.BlockStatus) async throws -> Flow.Account

func getAccountByBlockHeight(address: Flow.Address, height: UInt64) async throws -> Flow.Account

func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument]) async throws -> Flow.ScriptResponse
func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument], blockStatus: Flow.BlockStatus) async throws -> Flow.ScriptResponse

func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Cadence.FValue]) async throws -> Flow.ScriptResponse
func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Cadence.FValue], blockStatus: Flow.BlockStatus) async throws -> Flow.ScriptResponse

func executeScriptAtBlockId(script: Flow.Script, blockId: Flow.ID, arguments: [Flow.Argument]) async throws -> Flow.ScriptResponse

Expand All @@ -91,8 +91,17 @@
}

public extension FlowAccessProtocol {
func getAccountAtLatestBlock(address: String) async throws -> Flow.Account {
return try await getAccountAtLatestBlock(address: .init(hex: address.addHexPrefix()))

Check warning on line 94 in Sources/Network/FlowAccessProtocol.swift

View workflow job for this annotation

GitHub Actions / lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
func getLatestBlockHeader(blockStatus: Flow.BlockStatus = .final) async throws -> Flow.BlockHeader {
return try await getLatestBlockHeader(blockStatus: blockStatus)
}

Check warning on line 98 in Sources/Network/FlowAccessProtocol.swift

View workflow job for this annotation

GitHub Actions / lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
func getAccountAtLatestBlock(address: Flow.Address, blockStatus: Flow.BlockStatus = .final) async throws -> Flow.Account {
return try await getAccountAtLatestBlock(address: address, blockStatus: blockStatus)
}

Check warning on line 102 in Sources/Network/FlowAccessProtocol.swift

View workflow job for this annotation

GitHub Actions / lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
func getAccountAtLatestBlock(address: String, blockStatus: Flow.BlockStatus = .final) async throws -> Flow.Account {
return try await getAccountAtLatestBlock(address: .init(hex: address.addHexPrefix()), blockStatus: blockStatus)
}

func getTransactionById(id: String) async throws -> Flow.Transaction {
Expand All @@ -104,24 +113,28 @@
}

func getLatestBlock(sealed: Bool = true) async throws -> Flow.Block {
return try await getLatestBlock(sealed: sealed)
return try await getLatestBlock(blockStatus: .final)
}

func executeScriptAtLatestBlock(cadence: String, arguments: [Flow.Argument] = []) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: .init(text: cadence), arguments: arguments)
func executeScriptAtLatestBlock(cadence: String, arguments: [Flow.Argument] = [], blockStatus: Flow.BlockStatus = .final) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: .init(text: cadence), arguments: arguments, blockStatus: blockStatus)
}

func executeScriptAtLatestBlock(cadence: String, arguments: [Flow.Cadence.FValue] = []) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: .init(text: cadence), arguments: arguments.map { $0.toArgument() })
func executeScriptAtLatestBlock(cadence: String, arguments: [Flow.Cadence.FValue] = [], blockStatus: Flow.BlockStatus = .final) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: .init(text: cadence), arguments: arguments, blockStatus: blockStatus)
}

func executeScriptAtLatestBlock(script: Flow.Script) async throws -> Flow.ScriptResponse {
func executeScriptAtLatestBlock(script: Flow.Script, blockStatus: Flow.BlockStatus = .final) async throws -> Flow.ScriptResponse {
let list: [Flow.Argument] = []
return try await executeScriptAtLatestBlock(script: script, arguments: list)
return try await executeScriptAtLatestBlock(script: script, arguments: list, blockStatus: blockStatus)
}

Check warning on line 131 in Sources/Network/FlowAccessProtocol.swift

View workflow job for this annotation

GitHub Actions / lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument], blockStatus: Flow.BlockStatus = .final) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: script, arguments: arguments, blockStatus: blockStatus)
}

func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Cadence.FValue]) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: script, arguments: arguments.map { $0.toArgument() })
func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Cadence.FValue], blockStatus: Flow.BlockStatus = .final) async throws -> Flow.ScriptResponse {
return try await executeScriptAtLatestBlock(script: script, arguments: arguments.map { $0.toArgument() }, blockStatus: blockStatus)
}

func executeScriptAtBlockId(script: Flow.Script, blockId: Flow.ID, arguments: [Flow.Argument] = []) async throws -> Flow.ScriptResponse {
Expand Down
15 changes: 15 additions & 0 deletions Sources/Network/FlowBlockStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// File.swift
// Flow
//
// Created by Hao Fu on 7/5/2025.
//

import Foundation

extension Flow {
public enum BlockStatus: String, Codable {
case sealed
case final
}
}
26 changes: 14 additions & 12 deletions Sources/Network/HTTP/AccessEndpoint.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// CadenceTypeTest
//
// Copyright 2022 Outblock Pty Ltd

Check warning on line 4 in Sources/Network/HTTP/AccessEndpoint.swift

View workflow job for this annotation

GitHub Actions / lint

File Header Violation: Header comments should be consistent with project patterns (file_header)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,17 +24,17 @@
case getNetwork
case getBlockHeaderByHeight(height: UInt64)
case getBlockHeaderById(id: Flow.ID)
case getLatestBlockHeader
case getLatestBlock(sealed: Bool)
case getLatestBlockHeader(blockStatus: Flow.BlockStatus)
case getLatestBlock(blockStatus: Flow.BlockStatus)
case getBlockById(id: Flow.ID)
case getBlockByHeight(height: UInt64)
case getCollectionById(id: Flow.ID)
case sendTransaction(transaction: Flow.Transaction)
case getTransactionById(id: Flow.ID)
case getTransactionResultById(id: Flow.ID)
case getAccountAtLatestBlock(address: Flow.Address)
case getAccountAtLatestBlock(address: Flow.Address, blockStatus: Flow.BlockStatus)
case getAccountByBlockHeight(address: Flow.Address, height: UInt64)
case executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument])
case executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument], blockStatus: Flow.BlockStatus)
case executeScriptAtBlockId(script: Flow.Script, blockId: Flow.ID, arguments: [Flow.Argument])
case executeScriptAtBlockHeight(script: Flow.Script, height: UInt64, arguments: [Flow.Argument])
case getEventsForHeightRange(type: String, range: ClosedRange<UInt64>)
Expand All @@ -45,24 +45,26 @@
extension Flow.AccessEndpoint: TargetType {
var task: Task {
switch self {
case .ping, .getLatestBlockHeader:
case .ping:
return .requestParameters(["height": "sealed"])
case let .getLatestBlockHeader(blockStatus):
return .requestParameters(["height": blockStatus.rawValue])
case let .getBlockHeaderByHeight(height: height):
return .requestParameters(["height": String(height)])
case .getBlockById:
return .requestParameters(["expand": "payload"])
case let .getBlockByHeight(height):
return .requestParameters(["height": String(height), "expand": "payload"])
case let .getLatestBlock(sealed: sealed):
return .requestParameters(["height": sealed ? "sealed" : "finalized", "expand": "payload"])
case .getAccountAtLatestBlock:
return .requestParameters(["block_height": "sealed", "expand": "contracts,keys"])
case let .getLatestBlock(blockStatus):
return .requestParameters(["height": blockStatus.rawValue, "expand": "payload"])
case let .getAccountAtLatestBlock(_, blockStatus):
return .requestParameters(["block_height": blockStatus.rawValue, "expand": "contracts,keys"])
case let .getAccountByBlockHeight(_, height):
return .requestParameters(["block_height": String(height), "expand": "contracts,keys"])
case .getCollectionById:
return .requestParameters(["expand": "transactions"])
case let .executeScriptAtLatestBlock(script, arguments):
return .requestParameters(["block_height": "final"], body: Flow.ScriptRequest(script: script, arguments: arguments))
case let .executeScriptAtLatestBlock(script, arguments, blockStatus):
return .requestParameters(["block_height": blockStatus.rawValue], body: Flow.ScriptRequest(script: script, arguments: arguments))
case let .executeScriptAtBlockHeight(script, height, arguments):
return .requestParameters(["block_height": String(height)], body: Flow.ScriptRequest(script: script, arguments: arguments))
case let .executeScriptAtBlockId(script, id, arguments):
Expand Down Expand Up @@ -109,7 +111,7 @@
return "/v1/blocks/\(id.hex)"
case let .getBlockById(id):
return "/v1/blocks/\(id.hex)"
case let .getAccountAtLatestBlock(address):
case let .getAccountAtLatestBlock(address, _):
return "/v1/accounts/\(address.hex.stripHexPrefix())"
case let .getAccountByBlockHeight(address, _):
return "/v1/accounts/\(address.hex.stripHexPrefix())"
Expand Down
17 changes: 9 additions & 8 deletions Sources/Network/HTTP/FlowHTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension Flow {
/// HTTP client implementation for Flow Access API
/// Handles all network communication with Flow nodes
class FlowHTTPAPI: FlowAccessProtocol {

/// Shared instance of the HTTP client
static let client = FlowHTTPAPI()

Expand Down Expand Up @@ -152,8 +153,8 @@ extension Flow {
return result.chainId
}

func getLatestBlockHeader() async throws -> Flow.BlockHeader {
let result: [Flow.BlockHeaderResponse] = try await request(Flow.AccessEndpoint.getLatestBlockHeader)
func getLatestBlockHeader(blockStatus: Flow.BlockStatus) async throws -> Flow.BlockHeader {
let result: [Flow.BlockHeaderResponse] = try await request(Flow.AccessEndpoint.getLatestBlockHeader(blockStatus: blockStatus))
guard let block = result.first else {
throw FError.invaildResponse
}
Expand All @@ -176,8 +177,8 @@ extension Flow {
return block.header
}

func getLatestBlock(sealed: Bool) async throws -> Flow.Block {
let result: [Flow.BlockResponse] = try await request(Flow.AccessEndpoint.getLatestBlock(sealed: sealed))
func getLatestBlock(blockStatus: Flow.BlockStatus) async throws -> Flow.Block {
let result: [Flow.BlockResponse] = try await request(Flow.AccessEndpoint.getLatestBlock(blockStatus: blockStatus))
guard let block = result.first else {
throw FError.invaildResponse
}
Expand Down Expand Up @@ -217,17 +218,17 @@ extension Flow {
return try await request(Flow.AccessEndpoint.getTransactionResultById(id: id))
}

func getAccountAtLatestBlock(address: Flow.Address) async throws -> Flow.Account {
return try await request(Flow.AccessEndpoint.getAccountAtLatestBlock(address: address))
func getAccountAtLatestBlock(address: Flow.Address, blockStatus: Flow.BlockStatus = .final) async throws -> Flow.Account {
return try await request(Flow.AccessEndpoint.getAccountAtLatestBlock(address: address, blockStatus: blockStatus))
}

func getAccountByBlockHeight(address: Flow.Address, height: UInt64) async throws -> Flow.Account {
return try await request(Flow.AccessEndpoint.getAccountByBlockHeight(address: address, height: height))
}

func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument]) async throws -> Flow.ScriptResponse {
func executeScriptAtLatestBlock(script: Flow.Script, arguments: [Flow.Argument], blockStatus: Flow.BlockStatus) async throws -> Flow.ScriptResponse {
let resolvedScript = flow.addressRegister.resolveImports(in: script.text, for: chainID)
return try await request(Flow.AccessEndpoint.executeScriptAtLatestBlock(script: .init(text: resolvedScript), arguments: arguments))
return try await request(Flow.AccessEndpoint.executeScriptAtLatestBlock(script: .init(text: resolvedScript), arguments: arguments, blockStatus: blockStatus))
}

func executeScriptAtBlockId(script: Flow.Script, blockId: Flow.ID, arguments: [Flow.Argument]) async throws -> Flow.ScriptResponse {
Expand Down
24 changes: 16 additions & 8 deletions Tests/FlowAccessAPIOnTestnetTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ final class FlowAccessAPIOnTestnetTests: XCTestCase {
let result = try! await flow.accessAPI.executeScriptAtLatestBlock(script: .init(text: """
import FlowFees from 0x912d5440f7e3769e

pub fun main(): FlowFees.FeeParameters {
return FlowFees.getFeeParameters()
}
access(all) fun main(): FlowFees.FeeParameters {
return FlowFees.getFeeParameters()
}
"""))
print(result)
}
Expand All @@ -90,19 +90,19 @@ final class FlowAccessAPIOnTestnetTests: XCTestCase {
let accountKey = Flow.AccountKey(publicKey: Flow.PublicKey(hex: "bfa6d9893d4d9b5e53b0b9d79ac44b4e20f57b6443f02e5f12b366ed4e1fb4e7decca4e58b76308cee1a22a4c0c01f6fce698dc62c80120f65e8cdf57a0ffdff"),
signAlgo: .ECDSA_P256,
hashAlgo: .SHA2_256,
weight: 1000)
weight: 1001)

var unsignedTx = try! await flow.buildTransaction {
cadence {
"""
import Crypto
transaction(publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8, weight: UFix64) {
prepare(signer: AuthAccount) {
prepare(signer: auth(BorrowValue | Storage) &Account) {
let key = PublicKey(
publicKey: publicKey.decodeHex(),
signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)!
)
let account = AuthAccount(payer: signer)
let account = Account(payer: signer)
account.keys.add(
publicKey: key,
hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!,
Expand Down Expand Up @@ -137,10 +137,18 @@ final class FlowAccessAPIOnTestnetTests: XCTestCase {
}

let signedTx = try! await unsignedTx.sign(signers: signer)

let txId = try! await flow.sendTransaction(signedTransaction: signedTx)
XCTAssertNotNil(txId)
print("txid --> \(txId.hex)")
XCTAssertNotNil(txId)

let result = try await txId.onceExecuted()
let address = result.getCreatedAddress()!
print("address --> \(address)")
XCTAssertNotNil(address)

let accountInfo = try await flow.getAccountAtLatestBlock(address: .init(address))
print("accountInfo --> \(accountInfo)")
XCTAssertNotNil(accountInfo)
}

func testMultipleSigner() async throws {
Expand Down
Loading