spb/os-vault Public
Self-custody, multi-chain crypto wallet for macOS. One recovery phrase, six chain families, zero API keys — nothing leaves your Mac.
Swift 96%
Shell 3.4%
Makefile 0.6%
1import Foundation23public extension SolanaBlockchainClient {4 /// Prepare instructions for creating WSOL account and close it after finishing transaction5 /// to return funds back to native SOL account6 /// - Parameters:7 /// - owner: The owner of new WSOL account8 /// - amount: The initial amount in Lamports to transfer to the new WSOL account9 /// - payer: The payer of the transaction (usually the owner)10 /// - mre: The min rent exemption (leave it nil if there is no pre-defined)11 /// - Returns: AccountInstructions that contains needed instructions, signers, .etc12 func prepareCreatingWSOLAccountAndCloseWhenDone(13 from owner: PublicKey,14 amount: Lamports,15 payer: PublicKey,16 minRentExemption: Lamports17 ) async throws -> AccountInstructions {18 let newAccount = try await KeyPair(network: apiClient.endpoint.network)1920 return .init(21 account: newAccount.publicKey,22 instructions: [23 SystemProgram.createAccountInstruction(24 from: owner,25 toNewPubkey: newAccount.publicKey,26 lamports: amount + minRentExemption,27 space: TokenAccountState.BUFFER_LENGTH,28 programId: TokenProgram.id29 ),30 TokenProgram.initializeAccountInstruction(31 account: newAccount.publicKey,32 mint: .wrappedSOLMint,33 owner: payer34 ),35 ],36 cleanupInstructions: [37 TokenProgram.closeAccountInstruction(38 account: newAccount.publicKey,39 destination: payer,40 owner: payer41 ),42 ],43 signers: [44 newAccount,45 ],46 secretKey: newAccount.secretKey47 )48 }4950 /// Prepare instructions for creating associated token account and close if needed51 /// - Parameters:52 /// - owner: The owner of new WSOL account53 /// - mint: The mint of ther token54 /// - feePayer: The payer of the transaction (usually the owner)55 /// - closeAfterward: close after done or not56 /// - Returns: AccountInstructions that contains needed instructions, signers, .etc57 func prepareForCreatingAssociatedTokenAccount(58 owner: PublicKey,59 mint: PublicKey,60 tokenProgramId: PublicKey,61 feePayer: PublicKey,62 closeAfterward: Bool63 ) async throws -> AccountInstructions {64 let associatedAddress = try PublicKey.associatedTokenAddress(65 walletAddress: owner,66 tokenMintAddress: mint,67 tokenProgramId: tokenProgramId68 )6970 let isAssociatedTokenAddressRegistered: Bool71 do {72 let info: BufferInfo<TokenAccountState>? = try await apiClient73 .getAccountInfo(account: associatedAddress.base58EncodedString)74 if PublicKey.isSPLTokenProgram(info?.owner),75 info?.data.owner == owner76 {77 isAssociatedTokenAddressRegistered = true78 } else {79 throw BlockchainClientError.other("Associated token account is belong to another user")80 }81 } catch {82 if error.isEqualTo(.couldNotRetrieveAccountInfo) {83 isAssociatedTokenAddressRegistered = false84 } else {85 throw error86 }87 }8889 // cleanup intructions90 var cleanupInstructions = [TransactionInstruction]()91 if closeAfterward {92 cleanupInstructions = [93 TokenProgram.closeAccountInstruction(94 account: associatedAddress,95 destination: owner,96 owner: owner97 ),98 ]99 }100101 // if associated address is registered, there is no need to creating it again102 if isAssociatedTokenAddressRegistered {103 return .init(104 account: associatedAddress,105 cleanupInstructions: []106 )107 }108109 // else create associated address110 return try .init(111 account: associatedAddress,112 instructions: [113 AssociatedTokenProgram114 .createAssociatedTokenAccountInstruction(115 mint: mint,116 owner: owner,117 payer: feePayer,118 tokenProgramId: tokenProgramId119 ),120 ],121 cleanupInstructions: cleanupInstructions,122 newWalletPubkey: associatedAddress.base58EncodedString123 )124 }125}126