|
7 | 7 | import Foundation |
8 | 8 | import XCTest |
9 | 9 | import web3swift |
10 | | -import Web3Core |
| 10 | +@testable import Web3Core |
11 | 11 |
|
| 12 | +// TODO: take more tests from https://github.com/Mrtenz/eip-712/blob/master/src/eip-712.test.ts |
12 | 13 |
|
13 | 14 | /// Tests based primarily on the following example https://eips.ethereum.org/assets/eip-712/Example.js |
14 | 15 | class EIP712TypedDataPayloadTests: XCTestCase { |
@@ -221,4 +222,55 @@ class EIP712TypedDataPayloadTests: XCTestCase { |
221 | 222 | try XCTAssertEqual(parsedEip712TypedData.typeHash("Person"), "0xb9d8c78acf9b987311de6c7b45bb6a9c8e1bf361fa7fd3467a2163f994c79500") |
222 | 223 | try XCTAssertEqual(parsedEip712TypedData.typeHash("Mail"), "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2") |
223 | 224 | } |
| 225 | + |
| 226 | + func testEIP712EncodeData() throws { |
| 227 | + let parsedEip712TypedData = try EIP712Parser.parse(testTypedDataPayload) |
| 228 | + let encodedMessage = "a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8" |
| 229 | + XCTAssertEqual(try parsedEip712TypedData.encodeData().toHexString(), encodedMessage) |
| 230 | + XCTAssertEqual(try parsedEip712TypedData.encodeData(parsedEip712TypedData.primaryType, data: parsedEip712TypedData.message).toHexString(), encodedMessage) |
| 231 | + |
| 232 | + XCTAssertEqual(try parsedEip712TypedData.encodeData("EIP712Domain", data: parsedEip712TypedData.domain).toHexString(), |
| 233 | + "8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400fc70ef06638535b4881fafcac8287e210e3769ff1a8e91f1b95d6246e61e4d3c6c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cccccccccccccccccccccccccccccccccccccccc") |
| 234 | + |
| 235 | + XCTAssertEqual(try parsedEip712TypedData.encodeData("Person", data: parsedEip712TypedData.message["from"] as! [String : AnyObject]).toHexString(), |
| 236 | + "b9d8c78acf9b987311de6c7b45bb6a9c8e1bf361fa7fd3467a2163f994c795008c1d2bd5348394761719da11ec67eedae9502d137e8940fee8ecd6f641ee1648000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd826") |
| 237 | + |
| 238 | + XCTAssertEqual(try parsedEip712TypedData.encodeData("Person", |
| 239 | + data: ["wallet" : "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", |
| 240 | + "name" : "Cow"] as [String : AnyObject]).toHexString(), |
| 241 | + "b9d8c78acf9b987311de6c7b45bb6a9c8e1bf361fa7fd3467a2163f994c795008c1d2bd5348394761719da11ec67eedae9502d137e8940fee8ecd6f641ee1648000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd826") |
| 242 | + } |
| 243 | + |
| 244 | + func testEIP712StructHash() throws { |
| 245 | + let parsedEip712TypedData = try EIP712Parser.parse(testTypedDataPayload) |
| 246 | + XCTAssertEqual(try parsedEip712TypedData.structHash().toHexString(), "c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e") |
| 247 | + XCTAssertEqual(try parsedEip712TypedData.structHash("EIP712Domain", data: parsedEip712TypedData.domain).toHexString(), |
| 248 | + "f2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f") |
| 249 | + } |
| 250 | + |
| 251 | + func testEIP712SignHash() throws { |
| 252 | + let parsedEip712TypedData = try EIP712Parser.parse(testTypedDataPayload) |
| 253 | + XCTAssertEqual(try parsedEip712TypedData.signHash().toHexString(), "be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2") |
| 254 | + } |
| 255 | + |
| 256 | + func testEIP712Signing() throws { |
| 257 | + let parsedEip712TypedData = try EIP712Parser.parse(testTypedDataPayload) |
| 258 | + let privateKey = Data.fromHex("cow".sha3(.keccak256).addHexPrefix())! |
| 259 | + let publicKey = Utilities.privateToPublic(privateKey)! |
| 260 | + let address = Utilities.publicToAddress(publicKey)! |
| 261 | + XCTAssertEqual(address, EthereumAddress("0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826")); |
| 262 | + |
| 263 | + /// This signing doesn't use `"\u{19}Ethereum Signed Message:\n"`. As per EIP712 standard |
| 264 | + /// the following format is used instead: |
| 265 | + /// ``` |
| 266 | + /// encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message) |
| 267 | + /// ``` |
| 268 | + /// |
| 269 | + /// The output of ``EIP712TypedData.signHash`` is exactly that. |
| 270 | + let (compressedSignature, _) = try SECP256K1.signForRecovery(hash: parsedEip712TypedData.signHash(), privateKey: privateKey) |
| 271 | + let unmarshalledSignature = Utilities.unmarshalSignature(signatureData: compressedSignature!)! |
| 272 | + XCTAssertEqual(unmarshalledSignature.v, 28) |
| 273 | + XCTAssertEqual(unmarshalledSignature.r.toHexString(), "4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d") |
| 274 | + XCTAssertEqual(unmarshalledSignature.s.toHexString(), "07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b91562") |
| 275 | + } |
224 | 276 | } |
0 commit comments