Every comment is reduced to its first sentence plus Parameter, Returns and Throws tags. Comment lines: 20670 to 7626. Apple's swift-format applied to every Swift file outside the Obfs4 submodule with a committed .swift-format: four-space indentation, 100 columns, imports ordered. Three test expectations compared source text and depended on line wrapping; they now compare whitespace-collapsed text. Comments and formatting only. 764 XCTest and 55 Swift Testing pass. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
81 lines
3.4 KiB
Swift
81 lines
3.4 KiB
Swift
import XCTest
|
|
|
|
@testable import FilesEngine
|
|
|
|
final class WalletTests: XCTestCase {
|
|
|
|
private let kek = Data(repeating: 0x2b, count: 32)
|
|
private func words() throws -> [String] { try BIP39.englishWordlist() }
|
|
private func hex(_ s: String) -> Data {
|
|
let c = Array(s)
|
|
var out = Data()
|
|
for i in stride(from: 0, to: c.count, by: 2) {
|
|
out.append(UInt8(String(c[i...i + 1]), radix: 16)!)
|
|
}
|
|
return out
|
|
}
|
|
|
|
/// A record wrapped by the JavaScript, opened here.
|
|
func testAWalletRecordFromTheBrowserOpensHere() throws {
|
|
let record = hex(
|
|
"110bf45333f9d869b6cedd3167dbab1a9eaf77383dc50c8fb9ad18ce58c24a3afdf14accd0da11185c9ef20f33"
|
|
)
|
|
XCTAssertEqual(
|
|
try Wallet.unwrap(record: record, walletKEK: kek),
|
|
hex("0c1e24e5917779d297e14d45f14e1a1a"))
|
|
XCTAssertEqual(
|
|
try Wallet.phrase(record: record, walletKEK: kek, words: try words()),
|
|
"army van defense carry jealous true garbage claim echo media make crunch")
|
|
}
|
|
|
|
func testANewWalletsPhraseAndRecordDescribeTheSameSeed() throws {
|
|
let list = try words()
|
|
let made = try Wallet.create(walletKEK: kek, words: list)
|
|
XCTAssertEqual(made.phrase.split(separator: " ").count, 24)
|
|
XCTAssertEqual(
|
|
try Wallet.phrase(record: made.record, walletKEK: kek, words: list), made.phrase)
|
|
XCTAssertEqual(
|
|
try Wallet.seed(record: made.record, walletKEK: kek, words: list),
|
|
try BIP39.seed(from: made.phrase))
|
|
}
|
|
|
|
func testTwelveWordsAreAvailableForAnyoneWhoWantsThem() throws {
|
|
let made = try Wallet.create(walletKEK: kek, words: try words(), entropyBytes: 16)
|
|
XCTAssertEqual(made.phrase.split(separator: " ").count, 12)
|
|
}
|
|
|
|
/// A phrase from any other wallet restores the same addresses here.
|
|
func testAnImportedPhraseComesBackUnchanged() throws {
|
|
let list = try words()
|
|
let phrase = "army van defense carry jealous true garbage claim echo media make crunch"
|
|
let record = try Wallet.import(phrase: phrase, walletKEK: kek, words: list)
|
|
XCTAssertEqual(try Wallet.phrase(record: record, walletKEK: kek, words: list), phrase)
|
|
}
|
|
|
|
func testAPhraseThatFailsItsChecksumIsRefusedBeforeItIsStored() throws {
|
|
let list = try words()
|
|
XCTAssertThrowsError(
|
|
try Wallet.import(
|
|
phrase: "army van defense carry jealous true garbage claim echo media make abandon",
|
|
walletKEK: kek, words: list)
|
|
) { XCTAssertEqual($0 as? BIP39.Failure, .checksumFailed) }
|
|
}
|
|
|
|
/// The wrap is authenticated, so a different account cannot open it and the
|
|
/// record cannot be moved between accounts by editing a column.
|
|
func testAnotherAccountsKeyDoesNotOpenTheRecord() throws {
|
|
let made = try Wallet.create(walletKEK: kek, words: try words())
|
|
XCTAssertThrowsError(
|
|
try Wallet.unwrap(record: made.record, walletKEK: Data(repeating: 0x2c, count: 32)))
|
|
}
|
|
|
|
/// The context string is part of the stored bytes.
|
|
func testTheRecordIsBoundToTheWalletContext() throws {
|
|
XCTAssertEqual(String(decoding: Wallet.aad, as: UTF8.self), "flamenet/wallet/seed/v1")
|
|
let made = try Wallet.create(walletKEK: kek, words: try words())
|
|
XCTAssertThrowsError(
|
|
try Wrap.openWithKey(
|
|
kek, blob: made.record, aad: Data("flamenet/files/identity/v1".utf8)))
|
|
}
|
|
}
|