SPB Git

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%
6.8 KB · 209 lines swift
Raw Blame History
1import Foundation23public protocol SolanaTokenProgram: SolanaBasicProgram {}45public extension SolanaTokenProgram {6    static var initalizeMintIndex: UInt8 { 0 }7    static var initializeAccountIndex: UInt8 { 1 }8    static var transferIndex: UInt8 { 3 }9    static var approveIndex: UInt8 { 4 }10    static var mintToIndex: UInt8 { 7 }11    static var closeAccountIndex: UInt8 { 9 }12    static var transferCheckedIndex: UInt8 { 12 }13    static var burnCheckedIndex: UInt8 { 15 }1415    static func initializeMintInstruction(16        mint: PublicKey,17        decimals: UInt8,18        authority: PublicKey,19        freezeAuthority: PublicKey?20    ) -> TransactionInstruction {21        TransactionInstruction(22            keys: [23                AccountMeta(publicKey: mint, isSigner: false, isWritable: true),24                AccountMeta(publicKey: PublicKey.sysvarRent, isSigner: false, isWritable: false),25            ],26            programId: id,27            data: [28                initalizeMintIndex,29                decimals,30                authority,31                freezeAuthority != nil,32                freezeAuthority?.bytes ?? Data(capacity: PublicKey.numberOfBytes).bytes,33            ]34        )35    }3637    static func initializeAccountInstruction(38        account: PublicKey,39        mint: PublicKey,40        owner: PublicKey41    ) -> TransactionInstruction {42        TransactionInstruction(43            keys: [44                AccountMeta(publicKey: account, isSigner: false, isWritable: true),45                AccountMeta(publicKey: mint, isSigner: false, isWritable: false),46                AccountMeta(publicKey: owner, isSigner: false, isWritable: false),47                AccountMeta(publicKey: PublicKey.sysvarRent, isSigner: false, isWritable: false),48            ],49            programId: id,50            data: [initializeAccountIndex]51        )52    }5354    static func transferInstruction(55        source: PublicKey,56        destination: PublicKey,57        owner: PublicKey,58        amount: UInt6459    ) -> TransactionInstruction {60        TransactionInstruction(61            keys: [62                AccountMeta(publicKey: source, isSigner: false, isWritable: true),63                AccountMeta(publicKey: destination, isSigner: false, isWritable: true),64                AccountMeta(publicKey: owner, isSigner: true, isWritable: true),65            ],66            programId: id,67            data: [transferIndex, amount]68        )69    }7071    static func transferCheckedInstruction(72        source: PublicKey,73        mint: PublicKey,74        destination: PublicKey,75        owner: PublicKey,76        multiSigners: [PublicKey],77        amount: Lamports,78        decimals: Decimals79    ) -> TransactionInstruction {80        var keys = [81            AccountMeta(publicKey: source, isSigner: false, isWritable: true),82            AccountMeta(publicKey: mint, isSigner: false, isWritable: false),83            AccountMeta(publicKey: destination, isSigner: false, isWritable: true),84        ]8586        if multiSigners.isEmpty {87            keys.append(.init(publicKey: owner, isSigner: true, isWritable: false))88        } else {89            keys.append(.init(publicKey: owner, isSigner: false, isWritable: false))90            multiSigners.forEach { signer in91                keys.append(.init(publicKey: signer, isSigner: true, isWritable: false))92            }93        }9495        return .init(96            keys: keys,97            programId: id,98            data: [transferCheckedIndex, amount, decimals]99        )100    }101102    static func burnCheckedInstruction(103        mint: PublicKey,104        account: PublicKey,105        owner: PublicKey,106        amount: UInt64,107        decimals: UInt8108    ) -> TransactionInstruction {109        .init(110            keys: [111                .init(publicKey: account, isSigner: false, isWritable: true),112                .init(publicKey: mint, isSigner: false, isWritable: true),113                .init(publicKey: owner, isSigner: true, isWritable: false),114            ],115            programId: id,116            data: [117                burnCheckedIndex,118                amount,119                decimals,120            ]121        )122    }123124    static func approveInstruction(125        account: PublicKey,126        delegate: PublicKey,127        owner: PublicKey,128        multiSigners: [KeyPair],129        amount: UInt64130    ) -> TransactionInstruction {131        var keys = [132            AccountMeta(publicKey: account, isSigner: false, isWritable: true),133            AccountMeta(publicKey: delegate, isSigner: false, isWritable: false),134        ]135136        if multiSigners.isEmpty {137            keys.append(138                AccountMeta(publicKey: owner, isSigner: true, isWritable: false)139            )140        } else {141            keys.append(142                AccountMeta(publicKey: owner, isSigner: false, isWritable: false)143            )144145            for signer in multiSigners {146                keys.append(147                    AccountMeta(publicKey: signer.publicKey, isSigner: true, isWritable: false)148                )149            }150        }151152        return TransactionInstruction(153            keys: keys,154            programId: id,155            data: [approveIndex, amount]156        )157    }158159    static func mintToInstruction(160        mint: PublicKey,161        destination: PublicKey,162        authority: PublicKey,163        amount: UInt64164    ) -> TransactionInstruction {165        TransactionInstruction(166            keys: [167                AccountMeta(publicKey: mint, isSigner: false, isWritable: true),168                AccountMeta(publicKey: destination, isSigner: false, isWritable: true),169                AccountMeta(publicKey: authority, isSigner: true, isWritable: true),170            ],171            programId: id,172            data: [mintToIndex, amount]173        )174    }175176    static func closeAccountInstruction(177        account: PublicKey,178        destination: PublicKey,179        owner: PublicKey180    ) -> TransactionInstruction {181        .init(182            keys: [183                AccountMeta(publicKey: account, isSigner: false, isWritable: true),184                AccountMeta(publicKey: destination, isSigner: false, isWritable: true),185                AccountMeta(publicKey: owner, isSigner: false, isWritable: false),186            ],187            programId: id,188            data: [closeAccountIndex]189        )190    }191192    static func closeAccountInstruction(193        account: PublicKey,194        destination: PublicKey,195        owner: PublicKey,196        signers: [PublicKey]197    ) -> TransactionInstruction {198        .init(199            keys: [200                .writable(publicKey: account, isSigner: false),201                .writable(publicKey: destination, isSigner: false),202                .readonly(publicKey: owner, isSigner: signers.isEmpty),203            ] + signers.map { .readonly(publicKey: $0, isSigner: true) },204            programId: id,205            data: [closeAccountIndex]206        )207    }208}209