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%
2.6 KB · 58 lines swift
Raw Blame History
1//2//  BitcoinTests.swift3//  OS Vault4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//89import XCTest10import BitcoinDevKit11@testable import OSVaultKit1213final class BitcoinTests: XCTestCase {1415    // Official BIP-84 test vector (public, not a real wallet): the16    // all-"abandon" mnemonic must derive these first addresses at m/84'/0'/0'.17    let vectorMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"1819    func testBIP84VectorFirstAddress() throws {20        let (external, internalD) = try BitcoinService.secretDescriptors(21            mnemonic: vectorMnemonic, network: .mainnet)22        let wallet = try Wallet(descriptor: external, changeDescriptor: internalD,23                                network: .bitcoin, persister: Persister.newInMemory())24        let first = wallet.revealNextAddress(keychain: .external)25        XCTAssertEqual(first.address.description, "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu")26        let second = wallet.revealNextAddress(keychain: .external)27        XCTAssertEqual(second.address.description, "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g")28        let change = wallet.revealNextAddress(keychain: .internal)29        XCTAssertEqual(change.address.description, "bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el")30    }3132    func testPublicDescriptorsAreWatchOnly() throws {33        let (external, _) = try BitcoinService.publicDescriptors(34            mnemonic: vectorMnemonic, network: .mainnet)35        // A public descriptor must not contain private key material.36        XCTAssertFalse(external.description.contains("xprv"))37        XCTAssertTrue(external.description.contains("xpub"))38    }3940    func testAddressValidationPerNetwork() {41        XCTAssertTrue(BitcoinService.validate(42            address: "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", network: .mainnet))43        XCTAssertFalse(BitcoinService.validate(44            address: "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", network: .signet))45        XCTAssertFalse(BitcoinService.validate(address: "not-an-address", network: .mainnet))46        XCTAssertFalse(BitcoinService.validate(47            address: "0x9858EfFD232B4033E47d90003D41EC34EcaEda94", network: .mainnet))48    }4950    func testBTCAmountParsing() {51        XCTAssertEqual(BitcoinService.parseBTC("1"), 100_000_000)52        XCTAssertEqual(BitcoinService.parseBTC("0.00000001"), 1)53        XCTAssertNil(BitcoinService.parseBTC("0.000000001"))   // sub-sat54        XCTAssertEqual(BitcoinService.formatBTC(150_000_000), "1.5")55        XCTAssertEqual(BitcoinService.formatBTC(1), "0.00000001")56    }57}58