Skip to content

Commit

Permalink
feat: some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
bigearsenal committed Jan 9, 2024
1 parent 042ed3b commit 8babbb7
Show file tree
Hide file tree
Showing 21 changed files with 101 additions and 113 deletions.
34 changes: 14 additions & 20 deletions Sources/SolanaSwift/APIClient/APIClient+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,6 @@ import Foundation
public extension SolanaAPIClient {
// MARK: - Convenience methods

func getTokenAccountsByOwner(
pubkey: String,
params: OwnerInfoParams?,
configs: RequestConfiguration?
) async throws -> [TokenAccount<SPLTokenAccountState>] {
try await getTokenAccountsByOwner(
pubkey: pubkey,
params: params,
configs: configs,
decodingTo: SPLTokenAccountState.self
)
}

func getMinimumBalanceForRentExemption(span: UInt64) async throws -> UInt64 {
try await getMinimumBalanceForRentExemption(dataLength: span, commitment: "recent")
}
Expand All @@ -40,7 +27,7 @@ public extension SolanaAPIClient {
try await request(method: method, params: [])
}

func getMultipleMintDatas<M: SolanaSPLTokenMintState>(
func getMultipleMintDatas<M: TokenMintState>(
mintAddresses: [String],
commitment: Commitment,
mintType _: M.Type
Expand Down Expand Up @@ -88,13 +75,15 @@ public extension SolanaAPIClient {

func checkIfAssociatedTokenAccountExists(
owner: PublicKey,
mint: String
mint: String,
tokenProgramId: PublicKey
) async throws -> Bool {
let mintAddress = try mint.toPublicKey()

let associatedTokenAccount = try PublicKey.associatedTokenAddress(
walletAddress: owner,
tokenMintAddress: mintAddress
tokenMintAddress: mintAddress,
tokenProgramId: tokenProgramId
)

let bufferInfo: BufferInfo<SPLTokenAccountState>? = try await getAccountInfo(account: associatedTokenAccount
Expand All @@ -114,7 +103,8 @@ public extension SolanaAPIClient {

func findSPLTokenDestinationAddress(
mintAddress: String,
destinationAddress: String
destinationAddress: String,
tokenProgramId: PublicKey
) async throws -> SPLTokenDestinationAddress {
var address: String
var accountInfo: BufferInfo<SPLTokenAccountState>?
Expand All @@ -131,7 +121,8 @@ public extension SolanaAPIClient {
// create associated token address
address = try PublicKey.associatedTokenAddress(
walletAddress: owner,
tokenMintAddress: tokenMint
tokenMintAddress: tokenMint,
tokenProgramId: tokenProgramId
).base58EncodedString
} else {
throw PublicKeyError.invalidAddress(destinationAddress)
Expand All @@ -142,7 +133,8 @@ public extension SolanaAPIClient {
// create associated token address
address = try PublicKey.associatedTokenAddress(
walletAddress: owner,
tokenMintAddress: tokenMint
tokenMintAddress: tokenMint,
tokenProgramId: tokenProgramId
).base58EncodedString
} catch {
throw error
Expand All @@ -163,7 +155,9 @@ public extension SolanaAPIClient {
isUnregisteredAsocciatedToken = true

// if associated token account has been registered
if info?.owner == TokenProgram.id.base58EncodedString, info?.data != nil {
if PublicKey.isSPLTokenOrToken2022ProgramId(info?.owner),
info?.data != nil
{
isUnregisteredAsocciatedToken = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ public class JSONRPCAPIClient: SolanaAPIClient {
return result.value
}

public func getTokenAccountsByDelegate(
public func getTokenAccountsByDelegate<T: TokenAccountState>(
pubkey: String,
mint: String? = nil,
programId: String? = nil,
configs: RequestConfiguration? = nil
) async throws -> [TokenAccount<SPLTokenAccountState>] {
let result: Rpc<[TokenAccount<SPLTokenAccountState>]> = try await get(
) async throws -> [TokenAccount<T>] {
let result: Rpc<[TokenAccount<T>]> = try await get(
method: "getTokenAccountsByDelegate",
params: [
pubkey,
Expand All @@ -161,7 +161,7 @@ public class JSONRPCAPIClient: SolanaAPIClient {
return result.value
}

public func getTokenAccountsByOwner<T: SolanaSPLTokenAccountState>(
public func getTokenAccountsByOwner<T: TokenAccountState>(
pubkey: String,
params: OwnerInfoParams?,
configs: RequestConfiguration?,
Expand Down
6 changes: 3 additions & 3 deletions Sources/SolanaSwift/APIClient/SolanaAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ public protocol SolanaAPIClient {
/// - Returns The result will be an array of TokenAccount<AccountInfo>
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#gettokenaccountsbydelegate
///
func getTokenAccountsByDelegate(
func getTokenAccountsByDelegate<T: TokenAccountState>(
pubkey: String,
mint: String?,
programId: String?,
configs: RequestConfiguration?
) async throws -> [TokenAccount<SPLTokenAccountState>]
) async throws -> [TokenAccount<T>]

/// Returns all SPL Token accounts by token owner
/// - Parameters:
Expand All @@ -183,7 +183,7 @@ public protocol SolanaAPIClient {
/// - Returns The result will be an array of TokenAccount<AccountInfo>
/// - SeeAlso https://docs.solana.com/developing/clients/jsonrpc-api#gettokenaccountsbyowner
///
func getTokenAccountsByOwner<T: SolanaSPLTokenAccountState>(
func getTokenAccountsByOwner<T: TokenAccountState>(
pubkey: String,
params: OwnerInfoParams?,
configs: RequestConfiguration?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,9 @@ public extension SolanaBlockchainClient {
from owner: PublicKey,
amount: Lamports,
payer: PublicKey,
minRentExemption mre: Lamports?
minRentExemption: Lamports
) async throws -> AccountInstructions {
let newAccount: KeyPair
let minRentExemption: Lamports
async let requestNewAccount = KeyPair(network: apiClient.endpoint.network)

if let mre = mre {
minRentExemption = mre
newAccount = try await requestNewAccount
} else {
(minRentExemption, newAccount) = try await (
apiClient.getMinimumBalanceForRentExemption(
dataLength: UInt64(SPLTokenAccountState.BUFFER_LENGTH),
commitment: "recent"
),
requestNewAccount
)
}
let newAccount = try await KeyPair(network: apiClient.endpoint.network)

return .init(
account: newAccount.publicKey,
Expand Down Expand Up @@ -72,19 +57,21 @@ public extension SolanaBlockchainClient {
func prepareForCreatingAssociatedTokenAccount(
owner: PublicKey,
mint: PublicKey,
tokenProgramId: PublicKey,
feePayer: PublicKey,
closeAfterward: Bool
) async throws -> AccountInstructions {
let associatedAddress = try PublicKey.associatedTokenAddress(
walletAddress: owner,
tokenMintAddress: mint
tokenMintAddress: mint,
tokenProgramId: tokenProgramId
)

let isAssociatedTokenAddressRegistered: Bool
do {
let info: BufferInfo<SPLTokenAccountState>? = try await apiClient
.getAccountInfo(account: associatedAddress.base58EncodedString)
if info?.owner == TokenProgram.id.base58EncodedString,
if PublicKey.isSPLTokenOrToken2022ProgramId(info?.owner),
info?.data.owner == owner
{
isAssociatedTokenAddressRegistered = true
Expand Down Expand Up @@ -127,7 +114,8 @@ public extension SolanaBlockchainClient {
.createAssociatedTokenAccountInstruction(
mint: mint,
owner: owner,
payer: feePayer
payer: feePayer,
tokenProgramId: tokenProgramId
),
],
cleanupInstructions: cleanupInstructions,
Expand Down
20 changes: 8 additions & 12 deletions Sources/SolanaSwift/BlockchainClient/BlockchainClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class BlockchainClient: SolanaBlockchainClient {
if let fc = fc {
feeCalculator = fc
} else {
let (lps, minRentExemption) = try await (
let (lps, minRentExemption) = try await(
apiClient.getFees(commitment: nil).feeCalculator?.lamportsPerSignature,
apiClient.getMinimumBalanceForRentExemption(span: 165)
)
Expand Down Expand Up @@ -117,26 +117,21 @@ public class BlockchainClient: SolanaBlockchainClient {
public func prepareSendingSPLTokens(
account: KeyPair,
mintAddress: String,
tokenProgramId: PublicKey,
decimals: Decimals,
from fromPublicKey: String,
to destinationAddress: String,
amount: UInt64,
feePayer: PublicKey? = nil,
transferChecked: Bool = false,
minRentExemption mre: Lamports? = nil
minRentExemption: Lamports
) async throws -> (preparedTransaction: PreparedTransaction, realDestination: String) {
let feePayer = feePayer ?? account.publicKey

let minRenExemption: Lamports
if let mre = mre {
minRenExemption = mre
} else {
minRenExemption = try await apiClient
.getMinimumBalanceForRentExemption(span: SPLTokenAccountState.BUFFER_LENGTH)
}
let splDestination = try await apiClient.findSPLTokenDestinationAddress(
mintAddress: mintAddress,
destinationAddress: destinationAddress
destinationAddress: destinationAddress,
tokenProgramId: tokenProgramId
)

// get address
Expand All @@ -160,10 +155,11 @@ public class BlockchainClient: SolanaBlockchainClient {
let createATokenInstruction = try AssociatedTokenProgram.createAssociatedTokenAccountInstruction(
mint: mint,
owner: owner,
payer: feePayer
payer: feePayer,
tokenProgramId: tokenProgramId
)
instructions.append(createATokenInstruction)
accountsCreationFee += minRenExemption
accountsCreationFee += minRentExemption
}

// send instruction
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

public extension PublicKey {
static func isSPLTokenOrToken2022ProgramId(_ programId: String?) -> Bool {
programId == TokenProgram.id.base58EncodedString ||
programId == Token2022Program.id.base58EncodedString
}
}
16 changes: 3 additions & 13 deletions Sources/SolanaSwift/Models/PublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,13 @@ public enum PublicKeyError: Error, Equatable {
public extension PublicKey {
static func associatedTokenAddress(
walletAddress: PublicKey,
tokenMintAddress: PublicKey
tokenMintAddress: PublicKey,
tokenProgramId: PublicKey
) throws -> PublicKey {
try findProgramAddress(
seeds: [
walletAddress.data,
TokenProgram.id.data,
tokenProgramId.data,
tokenMintAddress.data,
],
programId: AssociatedTokenProgram.id
Expand Down Expand Up @@ -217,25 +218,14 @@ public extension PublicKey {
}

public extension PublicKey {
@available(*, deprecated, renamed: "TokenProgram.id")
static var tokenProgramId: PublicKey { TokenProgram.id }

static var sysvarRent: PublicKey { "SysvarRent111111111111111111111111111111111" }

@available(*, deprecated, renamed: "SystemProgram.id")
static var programId: PublicKey { SystemProgram.id }

static var wrappedSOLMint: PublicKey { "So11111111111111111111111111111111111111112" }
static var solMint: PublicKey { "Ejmc1UB4EsES5oAaRN63SpoxMJidt3ZGBrqrZk49vjTZ"
} // Arbitrary mint to represent SOL (not wrapped SOL).

// @available(*, deprecated, renamed: "OwnerValidationProgram.id")
// static var ownerValidationProgramId: PublicKey { OwnerValidationProgram.id }
static var swapHostFeeAddress: PublicKey { "AHLwq66Cg3CuDJTFtwjPfwjJhifiv6rFwApQNKgX57Yg" }

@available(*, deprecated, renamed: "AssociatedTokenProgram.id")
static var splAssociatedTokenAccountProgramId: PublicKey { AssociatedTokenProgram.id }

static var renBTCMint: PublicKey { "CDJWUqTcYTVAKXAVXoQZFes5JUFc7owSeq7eMQcDSbo5" }
static var renBTCMintDevnet: PublicKey { "FsaLodPu4VmSwXGr3gWfwANe4vKf8XSZcCh1CEeJ3jpD" }
static var fake: PublicKey { "BGcmLttQoYIw4Yfzc7RkZJCKR53IlAybgq8HK0vmovP0\n" }
Expand Down
12 changes: 7 additions & 5 deletions Sources/SolanaSwift/Programs/AssociatedTokenProgram.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,25 @@ public enum AssociatedTokenProgram: SolanaBasicProgram {
public static func createAssociatedTokenAccountInstruction(
mint: PublicKey,
owner: PublicKey,
payer: PublicKey
payer: PublicKey,
tokenProgramId: PublicKey
) throws -> TransactionInstruction {
TransactionInstruction(
try TransactionInstruction(
keys: [
.init(publicKey: payer, isSigner: true, isWritable: true),
try .init(
.init(
publicKey: PublicKey.associatedTokenAddress(
walletAddress: owner,
tokenMintAddress: mint
tokenMintAddress: mint,
tokenProgramId: tokenProgramId
),
isSigner: false,
isWritable: true
),
.init(publicKey: owner, isSigner: false, isWritable: false),
.init(publicKey: mint, isSigner: false, isWritable: false),
.init(publicKey: SystemProgram.id, isSigner: false, isWritable: false),
.init(publicKey: TokenProgram.id, isSigner: false, isWritable: false),
.init(publicKey: tokenProgramId, isSigner: false, isWritable: false),
.init(publicKey: .sysvarRent, isSigner: false, isWritable: false),
],
programId: AssociatedTokenProgram.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Token2022AccountState: SolanaSPLTokenAccountState {
public struct Token2022AccountState: TokenAccountState {
public let mint: PublicKey
public let owner: PublicKey
public let lamports: UInt64
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Token2022MintState: SolanaSPLTokenMintState {
public struct Token2022MintState: TokenMintState {
public let mintAuthorityOption: UInt32
public let mintAuthority: PublicKey?
public let supply: UInt64
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public protocol SolanaSPLTokenAccountState: BufferLayout {
public protocol TokenAccountState: BufferLayout {
var mint: PublicKey { get }
var owner: PublicKey { get }
var lamports: UInt64 { get }
Expand All @@ -18,7 +18,7 @@ public protocol SolanaSPLTokenAccountState: BufferLayout {
var closeAuthority: PublicKey? { get set }
}

extension SolanaSPLTokenAccountState {
extension TokenAccountState {
func serializeCommonProperties(to writer: inout Data) throws {
try mint.serialize(to: &writer)
try owner.serialize(to: &writer)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public protocol SolanaSPLTokenMintState: BufferLayout, Equatable, Hashable, Encodable {
public protocol TokenMintState: BufferLayout, Equatable, Hashable, Encodable {
var mintAuthorityOption: UInt32 { get }
var mintAuthority: PublicKey? { get }
var supply: UInt64 { get }
Expand All @@ -10,7 +10,7 @@ public protocol SolanaSPLTokenMintState: BufferLayout, Equatable, Hashable, Enco
var freezeAuthority: PublicKey? { get }
}

extension SolanaSPLTokenMintState {
extension TokenMintState {
func serializeCommonProperties(to writer: inout Data) throws {
try mintAuthorityOption.serialize(to: &writer)
if let mintAuthority = mintAuthority {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct SPLTokenAccountState: SolanaSPLTokenAccountState {
public struct SPLTokenAccountState: TokenAccountState {
public static let BUFFER_LENGTH: UInt64 = 165

public let mint: PublicKey
Expand Down
Loading

0 comments on commit 8babbb7

Please sign in to comment.