Skip to content

Commit f730f02

Browse files
Merge pull request #839 from JeneaVranceanu/chore/more-sign-tests
2 parents e8b3cdf + 5614659 commit f730f02

File tree

4 files changed

+83
-4
lines changed

4 files changed

+83
-4
lines changed

Sources/web3swift/HookedFunctions/Web3+Wallet.swift

+10
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@ import Web3Core
99

1010
extension Web3.Web3Wallet {
1111

12+
/// A list of addresses available in the attached keystore.
13+
/// - Returns: a list of addresses or an error.
1214
public func getAccounts() throws -> [EthereumAddress] {
1315
guard let keystoreManager = self.web3.provider.attachedKeystoreManager else {
16+
// TODO: add the following error message: Missing `attachedKeystoreManager`.
1417
throw Web3Error.walletError
1518
}
1619
guard let ethAddresses = keystoreManager.addresses else {
20+
// TODO: add the following error message: Missing attached keystore is empty.
1721
throw Web3Error.walletError
1822
}
1923
return ethAddresses
@@ -42,6 +46,12 @@ extension Web3.Web3Wallet {
4246
}
4347
}
4448

49+
/// Execute `personal_sign` for given arbitrary message.
50+
/// - Parameters:
51+
/// - personalMessage: message. Must be HEX formatted: message -> to 'UTF-8 bytes' -> to hex string!
52+
/// - account: signer address.
53+
/// - password: web3 attached keystore password.
54+
/// - Returns: signature for the given message or throws an error.
4555
public func signPersonalMessage(_ personalMessage: String, account: EthereumAddress, password: String ) throws -> Data {
4656
guard let data = Data.fromHex(personalMessage) else {
4757
throw Web3Error.dataError

Sources/web3swift/Web3/Web3+Contract.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension Web3 {
4747

4848
// MARK: Writing Data flow
4949
// FIXME: Rewrite this to CodableTransaction
50-
/// Deploys a contract instance using the previously provided ABI, some bytecode, constructor parameters and options.
50+
/// Deploys a contract instance using the previously provided ABI, some bytecode, constructor parameters and options.
5151
/// If extraData is supplied it is appended to encoded bytecode and constructor parameters.
5252
///
5353
/// Returns a "Transaction intermediate" object.

Tests/web3swiftTests/localTests/PersonalSignatureTests.swift

+72-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,79 @@ class PersonalSignatureTests: XCTestCase {
2121
let expectedAddress = keystoreManager.addresses![0]
2222

2323
let signature = try await web3.personal.signPersonalMessage(message: message.data(using: .utf8)!, from: expectedAddress, password: "")
24-
let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: signature)!
2524
let signer = web3.personal.recoverAddress(message: message.data(using: .utf8)!, signature: signature)
26-
XCTAssert(expectedAddress == signer, "Failed to sign personal message")
25+
XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message")
26+
}
27+
28+
/// This test was created by using Metamask 10.3.0
29+
/// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592
30+
func testPersonalSignatureCompatibleWithMetaMask() async throws {
31+
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
32+
let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519"
33+
let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c"
34+
35+
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
36+
let address = keystore.addresses!.first!
37+
let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!,
38+
keystore: keystore,
39+
account: address,
40+
password: "")
41+
XCTAssertNotNil(signature)
42+
XCTAssertEqual(signature?.toHexString(), expectedSignature)
43+
}
44+
45+
func testPersonalSignatureCompatibleWithMetaMaskv11_5_1() async throws {
46+
let privateKey = "0xbb5bbb5c11112bf637cca88d3612db25202a6e68df28f15ed7118c6a006c2938"
47+
let messageToSign = "Example `personal_sign` message"
48+
let expectedSignature = "24fef5a5d3757929a8782a96c9df2fa30cf39db52cd56c54fd42f17c6325fff220d1e2028f3c4426a66e8b8e665bff7b45f0766df4a12c9c9c59262d6efe9a6b1b"
49+
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
50+
let address = EthereumAddress("0xeee666c6625aec1807a035b1815264fed21ac566")!
51+
let signature = try Web3Signer.signPersonalMessage(messageToSign.data(using: .utf8)!,
52+
keystore: keystore,
53+
account: address,
54+
password: "")
55+
XCTAssertNotNil(signature)
56+
XCTAssertEqual(signature?.toHexString(), expectedSignature)
57+
}
58+
59+
/// The same as ``PersonalSignatureTests/testPersonalSignatureCompatibleWithMetaMask``
60+
func testPersonalSignatureCompatibleWithMetaMaskUsingWeb3Obj() async throws {
61+
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
62+
let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519"
63+
let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c"
64+
65+
let web3 = try await Web3.new(LocalTestCase.url)
66+
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
67+
let keystoreManager = KeystoreManager([keystore])
68+
web3.addKeystoreManager(keystoreManager)
69+
let expectedAddress = keystoreManager.addresses![0]
70+
71+
let signature = try await web3.personal.signPersonalMessage(message: Data.fromHex(messageToSign)!, from: expectedAddress, password: "")
72+
// ATTENTION: web3.wallet.signPersonalMessage accepts a raw string
73+
// ATTENTION: instead of the message hash but expects it to be
74+
// ATTENTION: 'string' -> to 'UTF-8 bytes' -> to hex string converted!
75+
let signature_walletObj = try web3.wallet.signPersonalMessage(messageToSign, account: expectedAddress, password: "")
76+
let signer = web3.personal.recoverAddress(message: Data.fromHex(messageToSign)!, signature: signature)
77+
78+
XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message")
79+
XCTAssertNotNil(signature)
80+
XCTAssertEqual(signature.toHexString(), expectedSignature)
81+
XCTAssertEqual(signature_walletObj.toHexString(), expectedSignature)
82+
}
83+
84+
/// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592
85+
func testPersonalSignatureCompatibleWithGeth() async throws {
86+
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
87+
let messageToSign = "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979"
88+
let expectedSignature = "9c73dd4937a37eecab3abb54b74b6ec8e500080431d36afedb1726624587ee6710296e10c1194dded7376f13ff03ef6c9e797eb86bae16c20c57776fc69344271c"
89+
90+
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
91+
let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!,
92+
keystore: keystore,
93+
account: keystore.addresses!.first!,
94+
password: "")
95+
XCTAssertNotNil(signature)
96+
XCTAssertEqual(signature?.toHexString(), expectedSignature)
2797
}
2898

2999
// TODO: - write contract

Tests/web3swiftTests/localTests/UncategorizedTests.swift

-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ class UncategorizedTests: LocalTestCase {
138138
let user = try await contract!
139139
.createReadOperation("users", parameters: [0])?
140140
.call()
141-
142141
XCTAssertEqual((userDeviceCount?["0"] as? BigUInt)?.hexString.lowercased(), addr.address.lowercased())
143142
XCTAssertEqual(totalUsers?["0"] as? BigUInt, 100)
144143
XCTAssertEqual(user?["0"] as? BigUInt, 0)

0 commit comments

Comments
 (0)