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%
3.6 KB · 100 lines swift
Raw Blame History
1import Foundation23public protocol BorshDeserializable {4    init(from reader: inout BinaryReader) throws5}67public extension FixedWidthInteger {8    init(from reader: inout BinaryReader) throws {9        var value: Self = .zero10        let bytes = try reader.read(count: UInt32(MemoryLayout<Self>.size))11        let size = withUnsafeMutableBytes(of: &value) { bytes.copyBytes(to: $0) }12        assert(size == MemoryLayout<Self>.size)13        self = Self(littleEndian: value)14    }15}1617extension UInt8: BorshDeserializable {}18extension UInt16: BorshDeserializable {}19extension UInt32: BorshDeserializable {}20extension UInt64: BorshDeserializable {}21extension UInt128: BorshDeserializable {}22extension Int8: BorshDeserializable {}23extension Int16: BorshDeserializable {}24extension Int32: BorshDeserializable {}25extension Int64: BorshDeserializable {}26extension Int128: BorshDeserializable {}2728extension Float32: BorshDeserializable {29    public init(from reader: inout BinaryReader) throws {30        var value: Self = .zero31        let bytes = try reader.read(count: UInt32(MemoryLayout<Self>.size))32        let size = withUnsafeMutableBytes(of: &value) { bytes.copyBytes(to: $0) }33        assert(size == MemoryLayout<Self>.size)34        assert(!value.isNaN, "For portability reasons we do not allow to deserialize NaNs.")35        self = value36    }37}3839extension Float64: BorshDeserializable {40    public init(from reader: inout BinaryReader) throws {41        var value: Self = .zero42        let bytes = try reader.read(count: UInt32(MemoryLayout<Self>.size))43        let size = withUnsafeMutableBytes(of: &value) { bytes.copyBytes(to: $0) }44        assert(size == MemoryLayout<Self>.size)45        assert(!value.isNaN, "For portability reasons we do not allow to deserialize NaNs.")46        self = value47    }48}4950extension Bool: BorshDeserializable {51    public init(from reader: inout BinaryReader) throws {52        var value: Self = false53        let bytes = try reader.read(count: UInt32(MemoryLayout<Self>.size))54        let size = withUnsafeMutableBytes(of: &value) { bytes.copyBytes(to: $0) }55        assert(size == MemoryLayout<Self>.size)56        self = value57    }58}5960extension Optional where Wrapped: BorshDeserializable {61    init(from reader: inout BinaryReader) throws {62        let isSomeValue: UInt8 = try .init(from: &reader)63        switch isSomeValue {64        case 1: self = try Wrapped(from: &reader)65        default: self = .none66        }67    }68}6970extension String: BorshDeserializable {71    public init(from reader: inout BinaryReader) throws {72        let count: UInt32 = try .init(from: &reader)73        let bytes = try reader.read(count: count)74        guard let value = String(bytes: bytes, encoding: .utf8) else { throw BorshCodableError.invalidData }75        self = value76    }77}7879extension Array: BorshDeserializable where Element: BorshDeserializable {80    public init(from reader: inout BinaryReader) throws {81        let count: UInt32 = try .init(from: &reader)82        self = try [UInt32](0 ..< count).map { _ in try Element(from: &reader) }83    }84}8586extension Set: BorshDeserializable where Element: BorshDeserializable & Equatable {87    public init(from reader: inout BinaryReader) throws {88        self = try Set([Element].init(from: &reader))89    }90}9192extension Dictionary: BorshDeserializable where Key: BorshDeserializable & Equatable, Value: BorshDeserializable {93    public init(from reader: inout BinaryReader) throws {94        let count: UInt32 = try .init(from: &reader)95        let keyValuePairs = try [UInt32](0 ..< count)96            .map { _ in try (Key(from: &reader), Value(from: &reader)) }97        self = Dictionary(uniqueKeysWithValues: keyValuePairs)98    }99}100