Skip to content

Commit 064bd43

Browse files
Replace getRecentBlockhash to getLatestBlockhash. Improve calculate fee for prepared transaction
1 parent e505803 commit 064bd43

File tree

12 files changed

+35
-397
lines changed

12 files changed

+35
-397
lines changed

Sources/SolanaSwift/APIClient/APIClient+Extension.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,14 @@ public extension SolanaAPIClient {
2222
try await getMinimumBalanceForRentExemption(dataLength: span, commitment: "recent")
2323
}
2424

25-
func getRecentBlockhash() async throws -> String {
26-
try await getRecentBlockhash(commitment: nil)
25+
func getLatestBlockhash() async throws -> String {
26+
try await getLatestBlockhash(commitment: nil)
2727
}
2828

2929
func observeSignatureStatus(signature: String) -> AsyncStream<PendingTransactionStatus> {
3030
observeSignatureStatus(signature: signature, timeout: 60, delay: 2)
3131
}
3232

33-
/// Get fee per signature
34-
func getLamportsPerSignature() async throws -> UInt64? {
35-
try await getFees(commitment: nil).feeCalculator?.lamportsPerSignature
36-
}
37-
3833
/// Convenience method for request(method:params:) with no params
3934
func request<Entity>(method: String) async throws -> Entity where Entity: Decodable {
4035
try await request(method: method, params: [])

Sources/SolanaSwift/APIClient/Networking/JSONRPCAPIClient.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,6 @@ public class JSONRPCAPIClient: SolanaAPIClient {
8989
public func getEpochInfo(commitment: Commitment? = nil) async throws -> EpochInfo {
9090
try await get(method: "getEpochInfo", params: [RequestConfiguration(commitment: commitment)])
9191
}
92-
93-
public func getFees(commitment: Commitment? = nil) async throws -> Fee {
94-
let result: Rpc<Fee> = try await get(method: "getFees", params: [RequestConfiguration(commitment: commitment)])
95-
return result.value
96-
}
9792

9893
public func getFeeForMessage(message: String, commitment: Commitment? = nil) async throws -> Lamports {
9994
let result: Rpc<Lamports> = try await get(method: "getFeeForMessage", params: [message, RequestConfiguration(commitment: commitment)])
@@ -109,9 +104,9 @@ public class JSONRPCAPIClient: SolanaAPIClient {
109104
)
110105
}
111106

112-
public func getRecentBlockhash(commitment: Commitment? = nil) async throws -> String {
113-
let result: Rpc<Fee> = try await get(method: "getRecentBlockhash",
114-
params: [RequestConfiguration(commitment: commitment)])
107+
public func getLatestBlockhash(commitment: Commitment? = nil) async throws -> String {
108+
let result: Rpc<GetLatestBlockhashResponse> = try await get(method: "getLatestBlockhash",
109+
params: [RequestConfiguration(commitment: commitment)])
115110
guard let blockhash = result.value.blockhash else {
116111
throw APIClientError.blockhashNotFound
117112
}

Sources/SolanaSwift/APIClient/SolanaAPIClient.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,14 @@ public protocol SolanaAPIClient {
110110
///
111111
func getEpochInfo(commitment: Commitment?) async throws -> EpochInfo
112112

113-
/// Returns a recent block hash from the ledger, a fee schedule that can be used to compute the cost of submitting a
114-
/// transaction using it, and the last slot in which the blockhash will be valid.
113+
/// Get the fee the network will charge for a particular Message
115114
/// - Parameters:
115+
/// - message: Base-64 encoded Message; Required
116116
/// - commitment: Optional
117+
/// - minContextSlot: Optional
117118
/// - Throws: APIClientError
118-
/// - Returns The result field will be an array of u64 integers listing confirmed blocks starting at start_slot for
119-
/// up to limit blocks, inclusive
120-
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#getfees
121-
///
122-
func getFees(commitment: Commitment?) async throws -> Fee
123-
119+
/// - Returns Fee corresponding to the message at the specified blockhash
120+
/// - SeeAlso https://solana.com/docs/rpc/http/getfeeformessage
124121
func getFeeForMessage(message: String, commitment: Commitment?) async throws -> Lamports
125122

126123
/// Returns minimum balance required to make account rent exempt
@@ -281,14 +278,13 @@ public protocol SolanaAPIClient {
281278
///
282279
func observeSignatureStatus(signature: String, timeout: Int, delay: Int) -> AsyncStream<PendingTransactionStatus>
283280

284-
/// Returns a recent block hash from the ledger, and a fee schedule that can be used to compute the cost of
285-
/// submitting a transaction using it.
281+
/// Returns the latest blockhash
286282
/// - Parameters:
287283
/// - commitment: (optional) Commitment
288284
/// - Throws: APIClientError
289-
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#getrecentblockhash
285+
/// - SeeAlso https://solana.com/docs/rpc/http/getlatestblockhash
290286
///
291-
func getRecentBlockhash(commitment: Commitment?) async throws -> String
287+
func getLatestBlockhash(commitment: Commitment?) async throws -> String
292288

293289
/// Returns signatures for confirmed transactions that include the given address in their accountKeys list.
294290
/// Returns signatures backwards in time from the provided signature or most recent confirmed block

Sources/SolanaSwift/BlockchainClient/BlockchainClient.swift

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,24 @@ public class BlockchainClient: SolanaBlockchainClient {
1919
/// - instructions: the instructions of the transaction
2020
/// - signers: the signers of the transaction
2121
/// - feePayer: the feePayer of the transaction
22-
/// - feeCalculator: (Optional) fee custom calculator for calculating fee
2322
/// - Returns: PreparedTransaction, can be sent or simulated using SolanaBlockchainClient
2423
public func prepareTransaction(
2524
instructions: [TransactionInstruction],
2625
signers: [KeyPair],
27-
feePayer: PublicKey,
28-
feeCalculator fc: FeeCalculator? = nil
26+
feePayer: PublicKey
2927
) async throws -> PreparedTransaction {
3028
// form transaction
3129
var transaction = Transaction(instructions: instructions, recentBlockhash: nil, feePayer: feePayer)
3230

33-
let feeCalculator: FeeCalculator
34-
if let fc = fc {
35-
feeCalculator = fc
36-
} else {
37-
let (lps, minRentExemption) = try await(
38-
apiClient.getFees(commitment: nil).feeCalculator?.lamportsPerSignature,
39-
apiClient.getMinimumBalanceForRentExemption(span: 165)
40-
)
41-
let lamportsPerSignature = lps ?? 5000
42-
feeCalculator = DefaultFeeCalculator(
43-
lamportsPerSignature: lamportsPerSignature,
44-
minRentExemption: minRentExemption
45-
)
46-
}
47-
let expectedFee = try feeCalculator.calculateNetworkFee(transaction: transaction)
48-
49-
let blockhash = try await apiClient.getRecentBlockhash()
31+
let blockhash = try await apiClient.getLatestBlockhash()
5032
transaction.recentBlockhash = blockhash
5133

5234
// if any signers, sign
5335
if !signers.isEmpty {
5436
try transaction.sign(signers: signers)
5537
}
38+
39+
let expectedFee = try await apiClient.getFeeForMessage(message: transaction.serializeMessage().base64EncodedString(), commitment: nil)
5640

5741
// return formed transaction
5842
return .init(transaction: transaction, signers: signers, expectedFee: expectedFee)
@@ -112,7 +96,6 @@ public class BlockchainClient: SolanaBlockchainClient {
11296
/// - amount: amount to be sent
11397
/// - feePayer: (Optional) if the transaction would be paid by another user
11498
/// - transferChecked: (Default: false) use transferChecked instruction instead of transfer transaction
115-
/// - minRentExemption: (Optional) pre-calculated min rent exemption, will be fetched if not provided
11699
/// - Returns: (preparedTransaction: PreparedTransaction, realDestination: String), preparedTransaction can be sent
117100
/// or simulated using SolanaBlockchainClient, the realDestination is the real spl address of destination. Can be
118101
/// different from destinationAddress if destinationAddress is a native Solana address
@@ -125,9 +108,7 @@ public class BlockchainClient: SolanaBlockchainClient {
125108
to destinationAddress: String,
126109
amount: UInt64,
127110
feePayer: PublicKey? = nil,
128-
transferChecked: Bool = false,
129-
lamportsPerSignature: Lamports,
130-
minRentExemption: Lamports
111+
transferChecked: Bool = false
131112
) async throws -> (preparedTransaction: PreparedTransaction, realDestination: String) {
132113
let feePayer = feePayer ?? account.publicKey
133114

@@ -150,7 +131,6 @@ public class BlockchainClient: SolanaBlockchainClient {
150131
var instructions = [TransactionInstruction]()
151132

152133
// create associated token address
153-
var accountsCreationFee: UInt64 = 0
154134
if splDestination.isUnregisteredAsocciatedToken {
155135
let mint = try PublicKey(string: mintAddress)
156136
let owner = try PublicKey(string: destinationAddress)
@@ -162,7 +142,6 @@ public class BlockchainClient: SolanaBlockchainClient {
162142
tokenProgramId: tokenProgramId
163143
)
164144
instructions.append(createATokenInstruction)
165-
accountsCreationFee += minRentExemption
166145
}
167146

168147
// send instruction
@@ -222,11 +201,7 @@ public class BlockchainClient: SolanaBlockchainClient {
222201
let preparedTransaction = try await prepareTransaction(
223202
instructions: instructions,
224203
signers: [account],
225-
feePayer: feePayer,
226-
feeCalculator: DefaultFeeCalculator(
227-
lamportsPerSignature: lamportsPerSignature,
228-
minRentExemption: minRentExemption
229-
)
204+
feePayer: feePayer
230205
)
231206
return (preparedTransaction, realDestination)
232207
}

Sources/SolanaSwift/BlockchainClient/FeeCalculator/FeeCalculator.swift

Lines changed: 0 additions & 59 deletions
This file was deleted.

Sources/SolanaSwift/BlockchainClient/SolanaBlockchainClient.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ public protocol SolanaBlockchainClient: AnyObject {
1212
/// - signers: the signers
1313
/// - feePayer: the feePayer, usually is the first signer
1414
/// - recentBlockhash: recentBlockhash, can be fetched lately when the value is nil
15-
/// - feeCalculator: the fee calculator, leave it nil to use DefaultFeeCalculator
1615
/// - Returns: information of a prepared transaction
1716
func prepareTransaction(
1817
instructions: [TransactionInstruction],
1918
signers: [KeyPair],
20-
feePayer: PublicKey,
21-
feeCalculator: FeeCalculator?
19+
feePayer: PublicKey
2220
) async throws -> PreparedTransaction
2321

2422
/// Send transaction
@@ -48,7 +46,7 @@ public extension SolanaBlockchainClient {
4846
retryDelay: 1,
4947
timeoutInSeconds: 60
5048
) {
51-
let recentBlockhash = try await self.apiClient.getRecentBlockhash()
49+
let recentBlockhash = try await self.apiClient.getLatestBlockhash()
5250
let serializedTransaction = try self.signAndSerialize(
5351
preparedTransaction: preparedTransaction,
5452
recentBlockhash: recentBlockhash
@@ -67,7 +65,7 @@ public extension SolanaBlockchainClient {
6765
func simulateTransaction(
6866
preparedTransaction: PreparedTransaction
6967
) async throws -> SimulationResult {
70-
let recentBlockhash = try await apiClient.getRecentBlockhash()
68+
let recentBlockhash = try await apiClient.getLatestBlockhash()
7169
let serializedTransaction = try signAndSerialize(
7270
preparedTransaction: preparedTransaction,
7371
recentBlockhash: recentBlockhash

Sources/SolanaSwift/Models/Models.swift

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,9 @@ public struct EpochSchedule: Decodable {
9797
public let firstNormalSlot: UInt64
9898
}
9999

100-
public struct Fee: Decodable {
101-
public let feeCalculator: FeeCalculatorResponse?
102-
public let feeRateGovernor: FeeRateGovernor?
100+
public struct GetLatestBlockhashResponse: Decodable {
103101
public let blockhash: String?
104-
public let lastValidSlot: UInt64?
105-
}
106-
107-
public struct FeeCalculatorResponse: Decodable {
108-
public let lamportsPerSignature: Lamports
109-
}
110-
111-
public struct FeeRateGovernor: Decodable {
112-
public let burnPercent: UInt64
113-
public let maxLamportsPerSignature: Lamports
114-
public let minLamportsPerSignature: Lamports
115-
public let targetLamportsPerSignature: Lamports
116-
public let targetSignaturesPerSlot: UInt64
102+
public let lastValidBlockHeight: UInt64?
117103
}
118104

119105
public struct Identity: Decodable {

Sources/SolanaSwift/Models/PreparedTransaction.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import Foundation
22

33
/// The prepared transaction that can be sent or simulate in SolanaBlockchainClient
44
public struct PreparedTransaction: Equatable {
5-
public init(transaction: Transaction, signers: [KeyPair], expectedFee: FeeAmount) {
5+
public init(transaction: Transaction, signers: [KeyPair], expectedFee: Lamports) {
66
self.transaction = transaction
77
self.signers = signers
88
self.expectedFee = expectedFee
99
}
1010

1111
public var transaction: Transaction
1212
public var signers: [KeyPair]
13-
public var expectedFee: FeeAmount
13+
public var expectedFee: Lamports
1414

1515
public mutating func sign() throws {
1616
try transaction.sign(signers: signers)

0 commit comments

Comments
 (0)