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%
11.1 KB · 405 lines swift
Raw Blame History
1import Foundation23public typealias TransactionID = String4public typealias Lamports = UInt645public typealias Decimals = UInt867public struct Response<T: Decodable>: Decodable {8    public let jsonrpc: String9    public let id: String?10    public let result: T?11    public let error: ResponseError?12    public let method: String?1314    // socket15    public let params: SocketParams<T>?16}1718public struct SocketParams<T: Decodable>: Decodable {19    public let result: Rpc<T>?20    public let subscription: UInt64?21}2223public struct ResponseError: Codable, Equatable {24    public init(code: Int?, message: String?, data: ResponseErrorData?) {25        self.code = code26        self.message = message27        self.data = data28    }2930    public let code: Int?31    public let message: String?32    public let data: ResponseErrorData?33}3435public struct ResponseErrorData: Codable, Equatable {36    public init(logs: [String]? = nil, numSlotsBehind: Int? = nil) {37        self.logs = logs38        self.numSlotsBehind = numSlotsBehind39    }4041    // public let err: ResponseErrorDataError42    public let logs: [String]?43    public let numSlotsBehind: Int?44}4546public struct Rpc<T: Decodable>: Decodable {47    public let context: Context48    public let value: T49}5051public struct Context: Decodable {52    public let slot: UInt6453}5455public struct BlockCommitment: Decodable {56    public let commitment: [UInt64]?57    public let totalStake: UInt6458}5960public struct ClusterNodes: Decodable {61    public let pubkey: String62    public let gossip: String63    public let tpu: String?64    public let rpc: String?65    public let version: String?66}6768public struct ConfirmedBlock: Decodable {69    public let blockhash: String70    public let previousBlockhash: String71    public let parentSlot: UInt6472    public let transactions: [TransactionInfo]73    public let rewards: [Reward]74    public let blockTime: UInt64?75}7677public struct Reward: Decodable {78    public let pubkey: String79    public let lamports: Lamports80    public let postBalance: Lamports81    public let rewardType: String?82}8384public struct EpochInfo: Decodable {85    public let absoluteSlot: UInt6486    public let blockHeight: UInt6487    public let epoch: UInt6488    public let slotIndex: UInt6489    public let slotsInEpoch: UInt6490}9192public struct EpochSchedule: Decodable {93    public let slotsPerEpoch: UInt6494    public let leaderScheduleSlotOffset: UInt6495    public let warmup: Bool96    public let firstNormalEpoch: UInt6497    public let firstNormalSlot: UInt6498}99100public struct Fee: Decodable {101    public let feeCalculator: FeeCalculatorResponse?102    public let feeRateGovernor: FeeRateGovernor?103    public let blockhash: String?104    public let lastValidSlot: UInt64?105}106107public struct FeeCalculatorResponse: Decodable {108    public let lamportsPerSignature: Lamports109}110111public struct FeeRateGovernor: Decodable {112    public let burnPercent: UInt64113    public let maxLamportsPerSignature: Lamports114    public let minLamportsPerSignature: Lamports115    public let targetLamportsPerSignature: Lamports116    public let targetSignaturesPerSlot: UInt64117}118119public struct Identity: Decodable {120    public let identity: String121}122123public struct InflationGovernor: Decodable {124    public let foundation: Float64125    public let foundationTerm: Float64126    public let initial: Float64127    public let taper: Float64128    public let terminal: Float64129}130131public struct InflationRate: Decodable {132    public let epoch: Float64133    public let foundation: Float64134    public let total: Float64135    public let validator: Float64136}137138public struct LargestAccount: Decodable {139    public let lamports: Lamports140    public let address: String141}142143public struct ProgramAccounts<T: BufferLayout>: Decodable {144    public let accounts: [ProgramAccount<T>]145    public init(from decoder: Decoder) throws {146        let container = try decoder.singleValueContainer()147        let throwables = try container.decode([Throwable<ProgramAccount<T>>].self)148149        var accounts = [ProgramAccount<T>]()150        throwables.forEach {151            switch $0.result {152            case let .success(account):153                accounts.append(account)154            case let .failure(error):155                Logger.log(156                    event: "Program Accounts",157                    message: "Error decoding an account in program accounts list: \(error.localizedDescription)",158                    logLevel: .error159                )160            }161        }162        self.accounts = accounts163    }164}165166public struct ProgramAccount<T: BufferLayout>: Decodable {167    public let account: BufferInfo<T>168    public let pubkey: String169}170171public struct BufferInfo<T: BufferLayout>: Decodable, Equatable {172    public let lamports: Lamports173    public let owner: String174    public let data: T175    public let executable: Bool176    public let rentEpoch: UInt64177178    public init(lamports: Lamports, owner: String, data: T, executable: Bool, rentEpoch: UInt64) {179        self.lamports = lamports180        self.owner = owner181        self.data = data182        self.executable = executable183        self.rentEpoch = rentEpoch184    }185}186187public struct BufferInfoParsed<T: Decodable>: Decodable {188    public let lamports: Lamports189    public let owner: String190    public let data: T?191    public let executable: Bool192    public let rentEpoch: UInt64193}194195public struct PerformanceSample: Decodable {196    public let numSlots: UInt64197    public let numTransactions: UInt64198    public let samplePeriodSecs: UInt199    public let slot: UInt64200}201202public struct SignatureInfo: Decodable {203    public let signature: String204    public let slot: UInt64?205    public let err: AnyTransactionError?206    public let memo: String?207    public let blockTime: UInt64?208209    public init(signature: String) {210        self.signature = signature211        slot = nil212        err = nil213        memo = nil214        blockTime = nil215    }216}217218public struct SignatureStatus: Decodable {219    public let slot: UInt64220    public let confirmations: UInt64?221    public let err: AnyTransactionError?222    public let confirmationStatus: String?223}224225public struct TransactionInfo: Decodable {226    public let blockTime: UInt64?227    public let meta: TransactionMeta?228    public let transaction: ConfirmedTransaction229    public let slot: UInt64?230}231232public struct TransactionMeta: Decodable {233    public let err: AnyTransactionError?234    public let fee: Lamports?235    public let innerInstructions: [InnerInstruction]?236    public let logMessages: [String]?237    public let postBalances: [Lamports]?238    public let postTokenBalances: [TokenBalance]?239    public let preBalances: [Lamports]?240    public let preTokenBalances: [TokenBalance]?241}242243public enum AnyTransactionError: Codable {244    case detailed(TransactionError)245    case string(String)246247    public init(from decoder: Decoder) throws {248        let container = try decoder.singleValueContainer()249        if let x = try? container.decode(String.self) {250            self = .string(x)251            return252        }253        if let x = try? container.decode(TransactionError.self) {254            self = .detailed(x)255            return256        }257        throw DecodingError.typeMismatch(AnyTransactionError.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ErrUnion"))258    }259260    public func encode(to encoder: Encoder) throws {261        var container = encoder.singleValueContainer()262        switch self {263        case let .detailed(x):264            try container.encode(x)265        case let .string(x):266            try container.encode(x)267        }268    }269}270271public typealias TransactionError = [String: [ErrorDetail]]272public struct ErrorDetail: Codable {273    public init(wrapped: Any) {274        self.wrapped = wrapped275    }276277    let wrapped: Any278279    public init(from decoder: Decoder) throws {280        let container = try decoder.singleValueContainer()281        if let value = try? container.decode(Bool.self) {282            wrapped = value283        } else if let value = try? container.decode(Double.self) {284            wrapped = value285        } else if let value = try? container.decode(String.self) {286            wrapped = value287        } else if let value = try? container.decode(Int.self) {288            wrapped = value289        } else if let value = try? container.decode([String: Int].self) {290            wrapped = value291        } else {292            wrapped = ""293        }294    }295296    public func encode(to encoder: Encoder) throws {297        var container = encoder.singleValueContainer()298        if let wrapped = wrapped as? Encodable {299            let wrapper = EncodableWrapper(wrapped: wrapped)300            try container.encode(wrapper)301        }302    }303}304305public struct InnerInstruction: Decodable {306    public let index: UInt32307    public let instructions: [ParsedInstruction]308}309310public struct TokenBalance: Decodable {311    public let accountIndex: UInt64312    public let mint: String313    public let uiTokenAmount: TokenAccountBalance314}315316public struct SimulationResult: Decodable {317    public let err: ErrorDetail? // TransactionError? // string | object318    public let logs: [String]319}320321public struct StakeActivation: Decodable {322    public let active: UInt64323    public let inactive: UInt64324    public let state: String325}326327public struct Supply: Decodable {328    public let circulating: Lamports329    public let nonCirculating: Lamports330    public let nonCirculatingAccounts: [String]331    public let total: Lamports332}333334public struct TokenAccountBalance: Codable, Equatable, Hashable {335    public init(uiAmount: Float64?, amount: String, decimals: UInt8?, uiAmountString: String?) {336        self.uiAmount = uiAmount337        self.amount = amount338        self.decimals = decimals339        self.uiAmountString = uiAmountString340    }341342    public init(amount: String, decimals: UInt8?) {343        uiAmount = UInt64(amount)?.convertToBalance(decimals: decimals)344        self.amount = amount345        self.decimals = decimals346        uiAmountString = "\(uiAmount ?? 0)"347    }348349    public let uiAmount: Float64?350    public let amount: String351    public let decimals: UInt8?352    public let uiAmountString: String?353354    public var amountInUInt64: UInt64? {355        UInt64(amount)356    }357}358359public struct TokenAccount<T: BufferLayout>: Decodable, Equatable {360    public let pubkey: String361    public let account: BufferInfo<T>362363    public init(pubkey: String, account: BufferInfo<T>) {364        self.pubkey = pubkey365        self.account = account366    }367}368369public struct TokenAmount: Decodable {370    public let address: String?371    public let amount: String372    public let decimals: UInt8373    public let uiAmount: Float64374}375376public struct Version: Decodable {377    public let solanaCore: String378379    private enum CodingKeys: String, CodingKey {380        case solanaCore = "solana-core"381    }382}383384public struct VoteAccounts: Decodable {385    public let current: [VoteAccount]386    public let delinquent: [VoteAccount]387}388389public struct VoteAccount: Decodable {390    public let commission: Int391    public let epochVoteAccount: Bool392    public let epochCredits: [[UInt64]]393    public let nodePubkey: String394    public let lastVote: UInt64395    public let activatedStake: UInt64396    public let votePubkey: String397}398399public struct PerfomanceSamples: Decodable {400    public let numSlots: Int401    public let numTransactions: Int402    public let samplePeriodSecs: Int403    public let slot: Int404}405