Skip to content

chore: added more of personal_sign test cases #839

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Sources/web3swift/HookedFunctions/Web3+Wallet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import Web3Core

extension Web3.Web3Wallet {

/// A list of addresses available in the attached keystore.
/// - Returns: a list of addresses or an error.
public func getAccounts() throws -> [EthereumAddress] {
guard let keystoreManager = self.web3.provider.attachedKeystoreManager else {
// TODO: add the following error message: Missing `attachedKeystoreManager`.
throw Web3Error.walletError
}
guard let ethAddresses = keystoreManager.addresses else {
// TODO: add the following error message: Missing attached keystore is empty.
Comment on lines +16 to +20
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These TODOs are resolved here: #841

throw Web3Error.walletError
}
return ethAddresses
Expand Down Expand Up @@ -42,6 +46,12 @@ extension Web3.Web3Wallet {
}
}

/// Execute `personal_sign` for given arbitrary message.
/// - Parameters:
/// - personalMessage: message. Must be HEX formatted: message -> to 'UTF-8 bytes' -> to hex string!
/// - account: signer address.
/// - password: web3 attached keystore password.
/// - Returns: signature for the given message or throws an error.
public func signPersonalMessage(_ personalMessage: String, account: EthereumAddress, password: String ) throws -> Data {
guard let data = Data.fromHex(personalMessage) else {
throw Web3Error.dataError
Expand Down
2 changes: 1 addition & 1 deletion Sources/web3swift/Web3/Web3+Contract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extension Web3 {

// MARK: Writing Data flow
// FIXME: Rewrite this to CodableTransaction
/// Deploys a contract instance using the previously provided ABI, some bytecode, constructor parameters and options.
/// Deploys a contract instance using the previously provided ABI, some bytecode, constructor parameters and options.
/// If extraData is supplied it is appended to encoded bytecode and constructor parameters.
///
/// Returns a "Transaction intermediate" object.
Expand Down
74 changes: 72 additions & 2 deletions Tests/web3swiftTests/localTests/PersonalSignatureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,79 @@ class PersonalSignatureTests: XCTestCase {
let expectedAddress = keystoreManager.addresses![0]

let signature = try await web3.personal.signPersonalMessage(message: message.data(using: .utf8)!, from: expectedAddress, password: "")
let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: signature)!
let signer = web3.personal.recoverAddress(message: message.data(using: .utf8)!, signature: signature)
XCTAssert(expectedAddress == signer, "Failed to sign personal message")
XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message")
}

/// This test was created by using Metamask 10.3.0
/// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592
func testPersonalSignatureCompatibleWithMetaMask() async throws {
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519"
let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c"

let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
let address = keystore.addresses!.first!
let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!,
keystore: keystore,
account: address,
password: "")
XCTAssertNotNil(signature)
XCTAssertEqual(signature?.toHexString(), expectedSignature)
}

func testPersonalSignatureCompatibleWithMetaMaskv11_5_1() async throws {
let privateKey = "0xbb5bbb5c11112bf637cca88d3612db25202a6e68df28f15ed7118c6a006c2938"
let messageToSign = "Example `personal_sign` message"
let expectedSignature = "24fef5a5d3757929a8782a96c9df2fa30cf39db52cd56c54fd42f17c6325fff220d1e2028f3c4426a66e8b8e665bff7b45f0766df4a12c9c9c59262d6efe9a6b1b"
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
let address = EthereumAddress("0xeee666c6625aec1807a035b1815264fed21ac566")!
let signature = try Web3Signer.signPersonalMessage(messageToSign.data(using: .utf8)!,
keystore: keystore,
account: address,
password: "")
XCTAssertNotNil(signature)
XCTAssertEqual(signature?.toHexString(), expectedSignature)
}

/// The same as ``PersonalSignatureTests/testPersonalSignatureCompatibleWithMetaMask``
func testPersonalSignatureCompatibleWithMetaMaskUsingWeb3Obj() async throws {
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519"
let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c"

let web3 = try await Web3.new(LocalTestCase.url)
let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
let keystoreManager = KeystoreManager([keystore])
web3.addKeystoreManager(keystoreManager)
let expectedAddress = keystoreManager.addresses![0]

let signature = try await web3.personal.signPersonalMessage(message: Data.fromHex(messageToSign)!, from: expectedAddress, password: "")
// ATTENTION: web3.wallet.signPersonalMessage accepts a raw string
// ATTENTION: instead of the message hash but expects it to be
// ATTENTION: 'string' -> to 'UTF-8 bytes' -> to hex string converted!
let signature_walletObj = try web3.wallet.signPersonalMessage(messageToSign, account: expectedAddress, password: "")
let signer = web3.personal.recoverAddress(message: Data.fromHex(messageToSign)!, signature: signature)

XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message")
XCTAssertNotNil(signature)
XCTAssertEqual(signature.toHexString(), expectedSignature)
XCTAssertEqual(signature_walletObj.toHexString(), expectedSignature)
}

/// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592
func testPersonalSignatureCompatibleWithGeth() async throws {
let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
let messageToSign = "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979"
let expectedSignature = "9c73dd4937a37eecab3abb54b74b6ec8e500080431d36afedb1726624587ee6710296e10c1194dded7376f13ff03ef6c9e797eb86bae16c20c57776fc69344271c"

let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")!
let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!,
keystore: keystore,
account: keystore.addresses!.first!,
password: "")
XCTAssertNotNil(signature)
XCTAssertEqual(signature?.toHexString(), expectedSignature)
}

// TODO: - write contract
Expand Down
1 change: 0 additions & 1 deletion Tests/web3swiftTests/localTests/UncategorizedTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ class UncategorizedTests: LocalTestCase {
let user = try await contract!
.createReadOperation("users", parameters: [0])?
.call()

XCTAssertEqual((userDeviceCount?["0"] as? BigUInt)?.hexString.lowercased(), addr.address.lowercased())
XCTAssertEqual(totalUsers?["0"] as? BigUInt, 100)
XCTAssertEqual(user?["0"] as? BigUInt, 0)
Expand Down