@@ -8,23 +8,93 @@ import Web3Core
8
8
@testable import web3swift
9
9
10
10
final class BIP44Tests : LocalTestCase {
11
+ private var mockTransactionChecker : MockTransactionChecker !
12
+
13
+ override func setUpWithError( ) throws {
14
+ try super. setUpWithError ( )
15
+ mockTransactionChecker = MockTransactionChecker ( )
16
+ }
17
+
18
+ override func tearDownWithError( ) throws {
19
+ try super. tearDownWithError ( )
20
+ mockTransactionChecker = nil
21
+ }
11
22
23
+ //MARK: - warns false
24
+
12
25
func testDeriveNoWarn( ) async throws {
13
26
let rootNode = try rootNode ( )
14
27
15
- let childNode = try await rootNode. derive ( path: " m/44'/60'/8096'/0/1 " , warns: false )
28
+ let childNode = try await rootNode. derive ( path: " m/44'/60'/8096'/0/1 " , warns: false , transactionChecker : mockTransactionChecker )
16
29
17
30
XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 035785d4918449c87892371c0f9ccf6e4eda40a7fb0f773f1254c064d3bba64026 " )
18
31
}
19
-
20
- func testAccountZeroCanBeDerived( ) async throws {
32
+
33
+ //MARK: - warns true
34
+
35
+ func testDeriveInvalidPath( ) async throws {
21
36
let rootNode = try rootNode ( )
22
37
23
- let childNode = try await rootNode. derive ( path: " m/44'/60'/0'/0/255 " , warns: true )
38
+ let childNode = try ? await rootNode. derive ( path: " " , warns: true , transactionChecker: mockTransactionChecker)
39
+
40
+ XCTAssertNil ( childNode)
41
+ }
42
+
43
+ func testAccountZeroCanBeDerivedAlways( ) async throws {
44
+ let rootNode = try rootNode ( )
45
+
46
+ let childNode = try await rootNode. derive ( path: " m/44'/60'/0'/0/255 " , warns: true , transactionChecker: mockTransactionChecker)
24
47
25
48
XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 0262fba1af8f149258123265318114066decf50d16c1222a9d657b7de2296c2734 " )
26
49
}
27
50
51
+ func testAccountOneWithoutTransactionsInAccountZeroWarns( ) async throws {
52
+ do {
53
+ let rootNode = try rootNode ( )
54
+ let path = " m/44'/60'/1'/0/0 "
55
+ mockTransactionChecker. results = false . times ( n: 20 )
56
+
57
+ let _ = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
58
+
59
+ XCTFail ( " Child must not be created usign warns true for the path: \( path) " )
60
+ } catch BIP44Error . warning {
61
+ XCTAssertTrue ( true )
62
+ }
63
+ }
64
+
65
+ func testAccountOneWithTransactionsInAccountZeroNotWarns( ) async throws {
66
+ do {
67
+ let rootNode = try rootNode ( )
68
+ let path = " m/44'/60'/1'/0/0 "
69
+ var results = false . times ( n: 19 )
70
+ results. append ( true )
71
+ mockTransactionChecker. results = results
72
+
73
+ let childNode = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
74
+
75
+ XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 036cd8f1bad46fa7caf7a80d48528b90db2a3b7a5c9a18d74d61b286e03850abf4 " )
76
+ } catch BIP44Error . warning {
77
+ XCTFail ( " BIP44Error.warning must not be thrown " )
78
+ }
79
+ }
80
+
81
+ func testAccountTwoWithTransactionsInAccountZeroButNotInOneWarns( ) async throws {
82
+ do {
83
+ let rootNode = try rootNode ( )
84
+ let path = " m/44'/60'/2'/0/0 "
85
+ var results : Array < Bool > = . init( )
86
+ results. append ( true )
87
+ results. append ( contentsOf: false . times ( n: 20 ) )
88
+ mockTransactionChecker. results = results
89
+
90
+ let _ = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
91
+
92
+ XCTFail ( " Child must not be created usign warns true for the path: \( path) " )
93
+ } catch BIP44Error . warning {
94
+ XCTAssertTrue ( true )
95
+ }
96
+ }
97
+
28
98
// MARK: - private
29
99
30
100
private func rootNode( ) throws -> HDNode {
@@ -33,3 +103,23 @@ final class BIP44Tests: LocalTestCase {
33
103
return try XCTUnwrap ( HDNode ( seed: seed) )
34
104
}
35
105
}
106
+
107
+ extension Bool {
108
+ func times( n: Int ) -> Array < Bool > {
109
+ var array : Array < Bool > = . init( )
110
+ ( 0 ..< n) . forEach { _ in
111
+ array. append ( self )
112
+ }
113
+ return array
114
+ }
115
+ }
116
+
117
+ private final class MockTransactionChecker : TransactionChecker {
118
+ var addresses : [ String ] = . init( )
119
+ var results : [ Bool ] = . init( )
120
+
121
+ func hasTransactions( address: String ) async throws -> Bool {
122
+ addresses. append ( address)
123
+ return results. removeFirst ( )
124
+ }
125
+ }
0 commit comments