Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add latest blockhash #2

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
105 changes: 56 additions & 49 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,52 +1,59 @@
{
"object": {
"pins": [
{
"package": "secp256k1",
"repositoryURL": "https://github.com/Boilertalk/secp256k1.swift.git",
"state": {
"branch": null,
"revision": "cd187c632fb812fd93711a9f7e644adb7e5f97f0",
"version": "0.1.7"
}
},
{
"package": "SwiftDocCPlugin",
"repositoryURL": "https://github.com/apple/swift-docc-plugin",
"state": {
"branch": null,
"revision": "9b1258905c21fc1b97bf03d1b4ca12c4ec4e5fda",
"version": "1.2.0"
}
},
{
"package": "SymbolKit",
"repositoryURL": "https://github.com/apple/swift-docc-symbolkit",
"state": {
"branch": null,
"revision": "b45d1f2ed151d057b54504d653e0da5552844e34",
"version": "1.0.0"
}
},
{
"package": "Task_retrying",
"repositoryURL": "https://github.com/bigearsenal/task-retrying-swift.git",
"state": {
"branch": null,
"revision": "208f1e8dfa93022a7d39ab5b334d5f43a934d4b1",
"version": "2.0.0"
}
},
{
"package": "TweetNacl",
"repositoryURL": "https://github.com/bitmark-inc/tweetnacl-swiftwrap.git",
"state": {
"branch": null,
"revision": "f8fd111642bf2336b11ef9ea828510693106e954",
"version": "1.1.0"
}
"pins" : [
{
"identity" : "generic-json-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/iwill/generic-json-swift.git",
"state" : {
"revision" : "0a06575f4038b504e78ac330913d920f1630f510",
"version" : "2.0.2"
}
]
},
"version": 1
},
{
"identity" : "secp256k1.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Boilertalk/secp256k1.swift.git",
"state" : {
"revision" : "cd187c632fb812fd93711a9f7e644adb7e5f97f0",
"version" : "0.1.7"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "9b1258905c21fc1b97bf03d1b4ca12c4ec4e5fda",
"version" : "1.2.0"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "task-retrying-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/bigearsenal/task-retrying-swift.git",
"state" : {
"revision" : "208f1e8dfa93022a7d39ab5b334d5f43a934d4b1",
"version" : "2.0.0"
}
},
{
"identity" : "tweetnacl-swiftwrap",
"kind" : "remoteSourceControl",
"location" : "https://github.com/bitmark-inc/tweetnacl-swiftwrap.git",
"state" : {
"revision" : "f8fd111642bf2336b11ef9ea828510693106e954",
"version" : "1.1.0"
}
}
],
"version" : 2
}
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ let package = Package(
.package(url: "https://github.com/Boilertalk/secp256k1.swift.git", from: "0.1.0"),
.package(url: "https://github.com/bitmark-inc/tweetnacl-swiftwrap.git", from: "1.0.2"),
.package(url: "https://github.com/bigearsenal/task-retrying-swift.git", from: "2.0.0"),
.package(url: "https://github.com/iwill/generic-json-swift.git", from: "2.0.2"),

// Docs generator
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
Expand All @@ -32,6 +33,7 @@ let package = Package(
.product(name: "secp256k1", package: "secp256k1.swift"),
.product(name: "TweetNacl", package: "tweetnacl-swiftwrap"),
.product(name: "Task_retrying", package: "task-retrying-swift"),
.product(name: "GenericJSON", package: "generic-json-swift"),
]
),
.testTarget(
Expand Down
4 changes: 4 additions & 0 deletions Sources/SolanaSwift/APIClient/APIClient+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public extension SolanaAPIClient {
func getRecentBlockhash() async throws -> String {
try await getRecentBlockhash(commitment: nil)
}

func getLatestBlockhash() async throws -> String {
try await getLatestBlockhash(commitment: nil)
}

func observeSignatureStatus(signature: String) -> AsyncStream<PendingTransactionStatus> {
observeSignatureStatus(signature: signature, timeout: 60, delay: 2)
Expand Down
64 changes: 42 additions & 22 deletions Sources/SolanaSwift/APIClient/Networking/JSONRPCAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ public class JSONRPCAPIClient: SolanaAPIClient {
) async throws -> TransactionInfo? {
try await get(
method: "getTransaction",
params: [signature, RequestConfiguration(commitment: commitment, encoding: "jsonParsed")]
params: [
signature,
RequestConfiguration(
commitment: commitment,
encoding: "jsonParsed",
maxSupportedTransactionVersion: 0
)
]
)
}

Expand Down Expand Up @@ -83,7 +90,16 @@ public class JSONRPCAPIClient: SolanaAPIClient {
}

public func getTransaction(transactionSignature: String) async throws -> TransactionInfo {
try await get(method: "getTransaction", params: [transactionSignature, "jsonParsed"])
try await get(
method: "getTransaction",
params: [
transactionSignature,
RequestConfiguration(
encoding: "jsonParsed",
maxSupportedTransactionVersion: 0
)
]
)
}

public func getEpochInfo(commitment: Commitment? = nil) async throws -> EpochInfo {
Expand Down Expand Up @@ -112,19 +128,32 @@ public class JSONRPCAPIClient: SolanaAPIClient {
}
return blockhash
}

public func getLatestBlockhash(commitment: Commitment? = nil) async throws -> String {
let result: Rpc<Blockhash> = try await get(method: "getLatestBlockhash",
params: [RequestConfiguration(commitment: commitment)])
guard let blockhash = result.value.blockhash else {
throw APIClientError.blockhashNotFound
}
return blockhash
}

public func getSignatureStatuses(signatures: [String],
configs: RequestConfiguration? = nil) async throws -> [SignatureStatus?]
{
public func getSignatureStatuses(
signatures: [String],
configs: RequestConfiguration? = nil
) async throws -> [SignatureStatus?] {

let result: Rpc<[SignatureStatus?]> = try await get(method: "getSignatureStatuses",
params: [signatures, configs])
return result.value
}

public func getSignatureStatus(signature: String,
configs _: RequestConfiguration? = nil) async throws -> SignatureStatus
{
guard let result = try await getSignatureStatuses(signatures: [signature]).first else {
public func getSignatureStatus(
signature: String,
configs: RequestConfiguration? = nil
) async throws -> SignatureStatus {

guard let result = try await getSignatureStatuses(signatures: [signature], configs: configs).first else {
throw APIClientError.invalidResponse
}
return try result ?! APIClientError.invalidResponse
Expand Down Expand Up @@ -176,9 +205,10 @@ public class JSONRPCAPIClient: SolanaAPIClient {

public func getParsedTokenAccountsByOwner(
pubkey: String,
params: OwnerInfoParams?
params: OwnerInfoParams?,
commitment: Commitment? = nil
) async throws -> [ParsedTokenAccount] {
let configs = RequestConfiguration(encoding: "jsonParsed")
let configs = RequestConfiguration(commitment: commitment,encoding: "jsonParsed")

let result: Rpc<[ParsedTokenAccount]> = try await get(
method: "getTokenAccountsByOwner",
Expand Down Expand Up @@ -277,16 +307,6 @@ public class JSONRPCAPIClient: SolanaAPIClient {
)!
) async throws -> SimulationResult {
let result: Rpc<SimulationResult> = try await get(method: "simulateTransaction", params: [transaction, configs])

// Error assertion
if let err = result.value.err {
if (err.wrapped as? String) == "BlockhashNotFound" {
throw APIClientError.blockhashNotFound
}
throw APIClientError.transactionSimulationError(logs: result.value.logs)
}

// Return value
return result.value
}

Expand Down Expand Up @@ -326,7 +346,7 @@ public class JSONRPCAPIClient: SolanaAPIClient {

public func getMultipleAccounts<T>(
pubkeys: [String],
commitment: Commitment
commitment: Commitment?
) async throws -> [BufferInfo<T>?]
where T: BufferLayout
{
Expand Down
10 changes: 9 additions & 1 deletion Sources/SolanaSwift/APIClient/SolanaAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public protocol SolanaAPIClient {
/// - Returns The result will be an RpcResponse
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#getmultipleaccounts
///
func getMultipleAccounts<T: BufferLayout>(pubkeys: [String], commitment: Commitment) async throws
func getMultipleAccounts<T: BufferLayout>(pubkeys: [String], commitment: Commitment?) async throws
-> [BufferInfo<T>?]

/// Observe status of a sending transaction by periodically calling getSignatureStatuses
Expand All @@ -287,6 +287,14 @@ public protocol SolanaAPIClient {
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#getrecentblockhash
///
func getRecentBlockhash(commitment: Commitment?) async throws -> String

/// Returns the latest blockhash
/// - Parameters:
/// - commitment: (optional) Commitment
/// - Throws: APIClientError
/// - SeeAlso https://solana.com/docs/rpc/http/getlatestblockhash
///
func getLatestBlockhash(commitment: Commitment?) async throws -> String

/// Returns signatures for confirmed transactions that include the given address in their accountKeys list.
/// Returns signatures backwards in time from the provided signature or most recent confirmed block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class BlockchainClient: SolanaBlockchainClient {
}
let expectedFee = try feeCalculator.calculateNetworkFee(transaction: transaction)

let blockhash = try await apiClient.getRecentBlockhash()
let blockhash = try await apiClient.getLatestBlockhash()
transaction.recentBlockhash = blockhash

// if any signers, sign
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public extension SolanaBlockchainClient {
retryDelay: 1,
timeoutInSeconds: 60
) {
let recentBlockhash = try await self.apiClient.getRecentBlockhash()
let recentBlockhash = try await self.apiClient.getLatestBlockhash()
let serializedTransaction = try self.signAndSerialize(
preparedTransaction: preparedTransaction,
recentBlockhash: recentBlockhash
Expand All @@ -67,7 +67,7 @@ public extension SolanaBlockchainClient {
func simulateTransaction(
preparedTransaction: PreparedTransaction
) async throws -> SimulationResult {
let recentBlockhash = try await apiClient.getRecentBlockhash()
let recentBlockhash = try await apiClient.getLatestBlockhash()
let serializedTransaction = try signAndSerialize(
preparedTransaction: preparedTransaction,
recentBlockhash: recentBlockhash
Expand Down
2 changes: 1 addition & 1 deletion Sources/SolanaSwift/Models/Message/VersionedMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public enum VersionedMessage: Equatable {
case legacy(Message)
case v0(MessageV0)

static func deserialize(data: Data) throws -> Self {
public static func deserialize(data: Data) throws -> Self {
guard !data.isEmpty else {
throw VersionedMessageError.deserializationError("Data is empty")
}
Expand Down
Loading