Skip to content

Commit

Permalink
Support string, selector base types in StarknetTypedData (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
DelevoXDG authored Feb 28, 2024
1 parent 9ba083a commit a8e2794
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 17 deletions.
34 changes: 23 additions & 11 deletions Sources/Starknet/Data/StarknetTypedData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ public struct StarknetTypedData: Codable, Equatable, Hashable {
public let message: [String: Element]

private init?(types: [String: [TypeDeclaration]], primaryType: String, domain: [String: Element], message: [String: Element]) {
if types.keys.contains("felt") || types.keys.contains("felt*") {
return nil
let reservedTypeNames = ["felt", "felt*", "string", "selector"]
for typeName in reservedTypeNames {
if types.keys.contains(typeName) {
return nil
}
}

self.types = types
Expand Down Expand Up @@ -151,23 +154,21 @@ public struct StarknetTypedData: Codable, Equatable, Hashable {
return hash
}

if typeName == "felt*" {
switch typeName {
case "felt*":
let array = try unwrapArray(from: element)

let hashes = try array.map {
try unwrapFelt(from: $0)
}

let hash = StarknetCurve.pedersenOn(hashes)

return hash
}

if typeName == "felt" {
case "felt", "string":
return try unwrapFelt(from: element)
case "selector":
return try unwrapSelector(from: element)
default:
throw StarknetTypedDataError.decodingError
}

throw StarknetTypedDataError.decodingError
}

private func encode(data: [String: Element], forType typeName: String) throws -> [Felt] {
Expand Down Expand Up @@ -309,6 +310,17 @@ private extension StarknetTypedData {
throw StarknetTypedDataError.decodingError
}
}

func unwrapSelector(from element: Element) throws -> Felt {
switch element {
case let .felt(felt):
return felt
case let .string(string):
return starknetSelector(from: string)
default:
throw StarknetTypedDataError.decodingError
}
}
}

private extension String {
Expand Down
28 changes: 22 additions & 6 deletions Tests/StarknetTests/Data/TypedDataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ final class TypedDataTests: XCTestCase {
static let tdFeltArr = loadTypedDataFromFile(name: "typed_data_felt_array_example")!
static let tdString = loadTypedDataFromFile(name: "typed_data_long_string_example")!
static let tdStructArr = loadTypedDataFromFile(name: "typed_data_struct_array_example")!
static let tdValidate = loadTypedDataFromFile(name: "typed_data_validate_example")!

func testInvalidTypes() {
XCTAssertNil(
StarknetTypedData(types: ["felt": []], primaryType: "felt", domain: "{}", message: "{\"felt\": 1}")
)
func testInvalidType(_ type: String) {
XCTAssertNil(
StarknetTypedData(types: [type: []], primaryType: type, domain: "{}", message: "{\"\(type)\": 1}")
)
}

XCTAssertNil(
StarknetTypedData(types: ["felt*": []], primaryType: "felt*", domain: "{}", message: "{\"felt*\": 1}")
)
testInvalidType("felt")
testInvalidType("felt*")
testInvalidType("string")
testInvalidType("selector")
}

func testMissingDependency() {
Expand All @@ -47,6 +51,7 @@ final class TypedDataTests: XCTestCase {
(Self.tdFeltArr, "Mail", "0x5b03497592c0d1fe2f3667b63099761714a895c7df96ec90a85d17bfc7a7a0"),
(Self.tdStructArr, "Post", "0x1d71e69bf476486b43cdcfaf5a85c00bb2d954c042b281040e513080388356d"),
(Self.tdStructArr, "Mail", "0x873b878e35e258fc99e3085d5aaad3a81a0c821f189c08b30def2cde55ff27"),
(Self.tdValidate, "Validate", "0x2e86ac4735e6012fbeaa68cbd0e5a089014d0da150fa915769a35d5eba30593"),
]

try cases.forEach { data, typeName, expectedResult in
Expand Down Expand Up @@ -83,6 +88,12 @@ final class TypedDataTests: XCTestCase {
"message",
"0x5650ec45a42c4776a182159b9d33118a46860a6e6639bb8166ff71f3c41eaef"
),
(
Self.tdValidate,
"Validate",
"message",
"0x87ecd5622070667d2534fa83dd9b16f6cb497b42998d301e8df0ed5875d02d"
),
]

try cases.forEach { data, typeName, dataSource, expectedResult in
Expand Down Expand Up @@ -116,6 +127,11 @@ final class TypedDataTests: XCTestCase {
"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"0x5914ed2764eca2e6a41eb037feefd3d2e33d9af6225a9e7fe31ac943ff712c"
),
(
Self.tdValidate,
"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"0x28e38c1c65783abb40b871705095584b96bcbf1f80c8268a0659d074b3afd92"
),
]

try cases.forEach { data, address, expectedResult in
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"types": {
"StarkNetDomain": [
{"name": "name", "type": "string"},
{"name": "version", "type": "felt"},
{"name": "chainId", "type": "felt"}
],
"Validate": [
{"name": "id", "type": "felt"},
{"name": "from", "type": "felt"},
{"name": "amount", "type": "felt"},
{"name": "nameGamer", "type": "string"},
{"name": "endDate", "type": "felt"},
{"name": "itemsAuthorized", "type": "felt*"},
{"name": "chkFunction", "type": "selector"}
]
},
"primaryType": "Validate",
"domain": {
"name": "myDapp",
"version": "1",
"chainId": "SN_GOERLI"
},
"message": {
"id": "0x0000004f000f",
"from": "0x2c94f628d125cd0e86eaefea735ba24c262b9a441728f63e5776661829a4066",
"amount": "400",
"nameGamer": "Hector26",
"endDate": "0x27d32a3033df4277caa9e9396100b7ca8c66a4ef8ea5f6765b91a7c17f0109c",
"itemsAuthorized": ["0x01", "0x03", "0x0a", "0x0e"],
"chkFunction": "check_authorization"
}
}

0 comments on commit a8e2794

Please sign in to comment.