Skip to content

Commit a8227aa

Browse files
authored
Revert SNIP-12 code to be compatible with starknet.js (#667)
* Revert code to be compatible with starknet.js * Add new test cases for new starknet.js updates * Refactor typedData tests to use TypedDataName for clarity * Add remaining test cases
1 parent 7bee770 commit a8227aa

File tree

3 files changed

+142
-72
lines changed

3 files changed

+142
-72
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"types": {
3+
"StarknetDomain": [
4+
{ "name": "name", "type": "shortstring" },
5+
{ "name": "version", "type": "shortstring" },
6+
{ "name": "chainId", "type": "shortstring" },
7+
{ "name": "revision", "type": "shortstring" }
8+
],
9+
"Example": [{ "name": "someEnum", "type": "enum", "contains": "EnumA" }],
10+
"EnumA": [
11+
{ "name": "Variant 1", "type": "()" },
12+
{ "name": "Variant 2", "type": "(u128,StructA)" }
13+
],
14+
"StructA": [{ "name": "nestedEnum", "type": "enum", "contains": "EnumB" }],
15+
"EnumB": [
16+
{ "name": "Variant A", "type": "()" },
17+
{ "name": "Variant B", "type": "(StructB*)" }
18+
],
19+
"StructB": [{ "name": "flag", "type": "bool" }]
20+
},
21+
"primaryType": "Example",
22+
"domain": {
23+
"name": "StarkNet Mail",
24+
"version": "1",
25+
"chainId": "1",
26+
"revision": "1"
27+
},
28+
"message": {
29+
"someEnum": {
30+
"Variant 2": [2, { "nestedEnum": { "Variant B": [[{ "flag": true }, { "flag": false }]] } }]
31+
}
32+
}
33+
}

typedData/typedData.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ func shortGetStructHash(
192192
return hash, err
193193
}
194194

195+
// This is not correct according to the SNIP-12 specification, but in order to be compatible with the Starknet.js library
196+
// (and consequently other libraries and dapps), it will be kept this way until Starknet.js is updated.
197+
// Ref: https://github.com/starknet-io/starknet.js/pull/1292
198+
// Ref: https://github.com/starknet-io/starknet.js/issues/1278
199+
// TODO: remove this once Starknet.js is updated.
200+
if isEnum {
201+
return typedData.Revision.HashMethod(encTypeData...), nil
202+
}
203+
195204
return typedData.Revision.HashMethod(append([]*felt.Felt{typeDef.Enconding}, encTypeData...)...), nil
196205
}
197206

@@ -333,6 +342,7 @@ func encodeTypes(typeName string, types map[string]TypeDefinition, revision *rev
333342
return typeDef, fmt.Errorf("can't parse type %s from types %v", typeName, types)
334343
}
335344

345+
// check if the type is already encoded
336346
if newTypeDef = types[typeName]; newTypeDef.EncoddingString != "" {
337347
return newTypeDef, nil
338348
}
@@ -354,7 +364,7 @@ func encodeTypes(typeName string, types map[string]TypeDefinition, revision *rev
354364
}
355365
// clear the array
356366
referencedTypesEnc = make([]string, 0, len(uniqueMap))
357-
// fill it again
367+
// fill it again, but now without duplicates
358368
for typeEncStr := range uniqueMap {
359369
referencedTypesEnc = append(referencedTypesEnc, typeEncStr)
360370
}

typedData/typedData_test.go

Lines changed: 98 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"testing"
88

9+
"github.com/stretchr/testify/assert"
910
"github.com/stretchr/testify/require"
1011
)
1112

@@ -30,6 +31,7 @@ func TestMain(m *testing.M) {
3031
"session_MerkleTree",
3132
"v1Nested",
3233
"allInOne",
34+
"example_enumNested",
3335
}
3436

3537
for _, fileName := range fileNames {
@@ -82,63 +84,71 @@ func BMockTypedData(b *testing.B) (ttd TypedData) {
8284
// - None
8385
func TestGetMessageHash(t *testing.T) {
8486
type testSetType struct {
85-
TypedData TypedData
87+
TypedDataName string
8688
Address string
8789
ExpectedMessageHash string
8890
}
8991
testSet := []testSetType{
9092
{
91-
TypedData: typedDataExamples["baseExample"],
93+
TypedDataName: "baseExample",
9294
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
9395
ExpectedMessageHash: "0x6fcff244f63e38b9d88b9e3378d44757710d1b244282b435cb472053c8d78d0",
9496
},
9597
{
96-
TypedData: typedDataExamples["example_array"],
98+
TypedDataName: "example_array",
9799
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
98100
ExpectedMessageHash: "0x88edea26d6177a8bc545b2e73c960ab7ddd67b46237b386b514e50315ce0f4",
99101
},
100102
{
101-
TypedData: typedDataExamples["example_baseTypes"],
103+
TypedDataName: "example_baseTypes",
102104
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
103105
ExpectedMessageHash: "0xdb7829db8909c0c5496f5952bcfc4fc894341ce01842537fc4f448743480b6",
104106
},
105107
{
106-
TypedData: typedDataExamples["example_presetTypes"],
108+
TypedDataName: "example_presetTypes",
107109
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
108110
ExpectedMessageHash: "0x185b339d5c566a883561a88fb36da301051e2c0225deb325c91bb7aa2f3473a",
109111
},
110112
{
111-
TypedData: typedDataExamples["session_MerkleTree"],
113+
TypedDataName: "session_MerkleTree",
112114
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
113115
ExpectedMessageHash: "0x751fb7d98545f7649d0d0eadc80d770fcd88d8cfaa55590b284f4e1b701ef0a",
114116
},
115117
{
116-
TypedData: typedDataExamples["mail_StructArray"],
118+
TypedDataName: "mail_StructArray",
117119
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
118120
ExpectedMessageHash: "0x5914ed2764eca2e6a41eb037feefd3d2e33d9af6225a9e7fe31ac943ff712c",
119121
},
120122
{
121-
TypedData: typedDataExamples["v1Nested"],
123+
TypedDataName: "v1Nested",
122124
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
123125
ExpectedMessageHash: "0x69b57cf0cd7c151c51f9616cc58a1f0a877fec28c8c15ff7537cf777c54a30d",
124126
},
125127
{
126-
TypedData: typedDataExamples["example_enum"],
128+
TypedDataName: "example_enum",
127129
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
128-
ExpectedMessageHash: "0x416b85b18063b1b3420ab709e9d5e35cb716691d397c5841ce7c5198ee30bf",
130+
ExpectedMessageHash: "0x6e61abaf480b1370bbf231f54e298c5f4872f40a6d2dd409ff30accee5bbd1e",
129131
},
130132
{
131-
TypedData: typedDataExamples["allInOne"],
133+
TypedDataName: "allInOne",
132134
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
133-
ExpectedMessageHash: "0x300dc63cc85a15529bba5ed482009be716645fa9f2c64bd8716cf6f34767651",
135+
ExpectedMessageHash: "0x8fa4e453de78c2762493760efd449a38eb46f85b2e02b116b77b3daa9075c8",
136+
},
137+
{
138+
TypedDataName: "example_enumNested",
139+
Address: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
140+
ExpectedMessageHash: "0x691fc54567306a8ea5431130f1b98299e74a748ac391540a86736f20ef5f2b7",
134141
},
135142
}
136143

137144
for _, test := range testSet {
138-
hash, err := test.TypedData.GetMessageHash(test.Address)
139-
require.NoError(t, err)
145+
t.Run(test.TypedDataName, func(t *testing.T) {
146+
td := typedDataExamples[test.TypedDataName]
147+
hash, err := td.GetMessageHash(test.Address)
148+
require.NoError(t, err)
140149

141-
require.Equal(t, test.ExpectedMessageHash, hash.String())
150+
assert.Equal(t, test.ExpectedMessageHash, hash.String())
151+
})
142152
}
143153
}
144154

@@ -177,42 +187,50 @@ func BenchmarkGetMessageHash(b *testing.B) {
177187
// none
178188
func TestGetTypeHash(t *testing.T) {
179189
type testSetType struct {
180-
TypedData TypedData
181-
TypeName string
182-
ExpectedHash string
190+
TypedDataName string
191+
TypeName string
192+
ExpectedHash string
183193
}
184194
testSet := []testSetType{
185195
{
186-
TypedData: typedDataExamples["baseExample"],
187-
TypeName: "StarkNetDomain",
188-
ExpectedHash: "0x1bfc207425a47a5dfa1a50a4f5241203f50624ca5fdf5e18755765416b8e288",
196+
TypedDataName: "baseExample",
197+
TypeName: "StarkNetDomain",
198+
ExpectedHash: "0x1bfc207425a47a5dfa1a50a4f5241203f50624ca5fdf5e18755765416b8e288",
199+
},
200+
{
201+
TypedDataName: "baseExample",
202+
TypeName: "Mail",
203+
ExpectedHash: "0x13d89452df9512bf750f539ba3001b945576243288137ddb6c788457d4b2f79",
189204
},
190205
{
191-
TypedData: typedDataExamples["baseExample"],
192-
TypeName: "Mail",
193-
ExpectedHash: "0x13d89452df9512bf750f539ba3001b945576243288137ddb6c788457d4b2f79",
206+
TypedDataName: "example_baseTypes",
207+
TypeName: "Example",
208+
ExpectedHash: "0x1f94cd0be8b4097a41486170fdf09a4cd23aefbc74bb2344718562994c2c111",
194209
},
195210
{
196-
TypedData: typedDataExamples["example_baseTypes"],
197-
TypeName: "Example",
198-
ExpectedHash: "0x1f94cd0be8b4097a41486170fdf09a4cd23aefbc74bb2344718562994c2c111",
211+
TypedDataName: "example_presetTypes",
212+
TypeName: "Example",
213+
ExpectedHash: "0x1a25a8bb84b761090b1fadaebe762c4b679b0d8883d2bedda695ea340839a55",
199214
},
200215
{
201-
TypedData: typedDataExamples["example_presetTypes"],
202-
TypeName: "Example",
203-
ExpectedHash: "0x1a25a8bb84b761090b1fadaebe762c4b679b0d8883d2bedda695ea340839a55",
216+
TypedDataName: "session_MerkleTree",
217+
TypeName: "Session",
218+
ExpectedHash: "0x1aa0e1c56b45cf06a54534fa1707c54e520b842feb21d03b7deddb6f1e340c",
204219
},
205220
{
206-
TypedData: typedDataExamples["session_MerkleTree"],
207-
TypeName: "Session",
208-
ExpectedHash: "0x1aa0e1c56b45cf06a54534fa1707c54e520b842feb21d03b7deddb6f1e340c",
221+
TypedDataName: "example_enumNested",
222+
TypeName: "Example",
223+
ExpectedHash: "0x2143bb787fabace39d62e9acf8b6e97d9a369000516c3e6ffd963dc1370fc1a",
209224
},
210225
}
211226
for _, test := range testSet {
212-
hash, err := test.TypedData.GetTypeHash(test.TypeName)
213-
require.NoError(t, err)
227+
t.Run(test.TypedDataName, func(t *testing.T) {
228+
td := typedDataExamples[test.TypedDataName]
229+
hash, err := td.GetTypeHash(test.TypeName)
230+
require.NoError(t, err)
214231

215-
require.Equal(t, test.ExpectedHash, hash.String())
232+
assert.Equal(t, test.ExpectedHash, hash.String())
233+
})
216234
}
217235
}
218236

@@ -230,59 +248,67 @@ func TestGetTypeHash(t *testing.T) {
230248
// none
231249
func TestEncodeType(t *testing.T) {
232250
type testSetType struct {
233-
TypedData TypedData
251+
TypedDataName string
234252
TypeName string
235253
ExpectedEncode string
236254
}
237255
testSet := []testSetType{
238256
{
239-
TypedData: typedDataExamples["baseExample"],
257+
TypedDataName: "baseExample",
240258
TypeName: "StarkNetDomain",
241259
ExpectedEncode: "StarkNetDomain(name:felt,version:felt,chainId:felt)",
242260
},
243261
{
244-
TypedData: typedDataExamples["baseExample"],
262+
TypedDataName: "baseExample",
245263
TypeName: "Mail",
246264
ExpectedEncode: "Mail(from:Person,to:Person,contents:felt)Person(name:felt,wallet:felt)",
247265
},
248266
{
249-
TypedData: typedDataExamples["example_array"],
267+
TypedDataName: "example_array",
250268
TypeName: "StarknetDomain",
251269
ExpectedEncode: `"StarknetDomain"("name":"shortstring","version":"shortstring","chainId":"shortstring","revision":"shortstring")`,
252270
},
253271
{
254-
TypedData: typedDataExamples["example_baseTypes"],
272+
TypedDataName: "example_baseTypes",
255273
TypeName: "Example",
256274
ExpectedEncode: `"Example"("n0":"felt","n1":"bool","n2":"string","n3":"selector","n4":"u128","n5":"i128","n6":"ContractAddress","n7":"ClassHash","n8":"timestamp","n9":"shortstring")`,
257275
},
258276
{
259-
TypedData: typedDataExamples["example_presetTypes"],
277+
TypedDataName: "example_presetTypes",
260278
TypeName: "Example",
261279
ExpectedEncode: `"Example"("n0":"TokenAmount","n1":"NftId")"NftId"("collection_address":"ContractAddress","token_id":"u256")"TokenAmount"("token_address":"ContractAddress","amount":"u256")"u256"("low":"u128","high":"u128")`,
262280
},
263281
{
264-
TypedData: typedDataExamples["session_MerkleTree"],
282+
TypedDataName: "session_MerkleTree",
265283
TypeName: "Session",
266284
ExpectedEncode: `Session(key:felt,expires:felt,root:merkletree)`,
267285
},
268286
{
269-
TypedData: typedDataExamples["mail_StructArray"],
287+
TypedDataName: "mail_StructArray",
270288
TypeName: "Mail",
271289
ExpectedEncode: `Mail(from:Person,to:Person,posts_len:felt,posts:Post*)Person(name:felt,wallet:felt)Post(title:felt,content:felt)`,
272290
},
273291
{
274-
TypedData: typedDataExamples["v1Nested"],
292+
TypedDataName: "v1Nested",
275293
TypeName: "TransferERC721",
276294
ExpectedEncode: `"TransferERC721"("MessageId":"felt","From":"Account1","To":"Account1","Nft_to_transfer":"Nft","Comment1":"string","Comment2":"string","Comment3":"string")"Account1"("Name":"string","Address":"felt")"Nft"("Collection":"string","Address":"felt","Nft_id":"felt","Negotiated_for":"Transaction")"Transaction"("Qty":"string","Unit":"string","Token_address":"felt","Amount":"felt")`,
277295
},
278296
{
279-
TypedData: typedDataExamples["example_enum"],
297+
TypedDataName: "example_enum",
280298
TypeName: "Example",
281299
ExpectedEncode: `"Example"("someEnum1":"EnumA","someEnum2":"EnumB")"EnumA"("Variant 1":(),"Variant 2":("u128","u128*"),"Variant 3":("u128"))"EnumB"("Variant 1":(),"Variant 2":("u128"))`,
282300
},
301+
{
302+
TypedDataName: "example_enumNested",
303+
TypeName: "Example",
304+
ExpectedEncode: `"Example"("someEnum":"EnumA")"EnumA"("Variant 1":(),"Variant 2":("u128","StructA"))"EnumB"("Variant A":(),"Variant B":("StructB*"))"StructA"("nestedEnum":"EnumB")"StructB"("flag":"bool")`,
305+
},
283306
}
284307
for _, test := range testSet {
285-
require.Equal(t, test.ExpectedEncode, test.TypedData.Types[test.TypeName].EncoddingString)
308+
t.Run(test.TypedDataName, func(t *testing.T) {
309+
td := typedDataExamples[test.TypedDataName]
310+
assert.Equal(t, test.ExpectedEncode, td.Types[test.TypeName].EncoddingString)
311+
})
286312
}
287313
}
288314

@@ -300,47 +326,48 @@ func TestEncodeType(t *testing.T) {
300326
// none
301327
func TestGetStructHash(t *testing.T) {
302328
type testSetType struct {
303-
TypedData TypedData
304-
TypeName string
305-
Context []string
306-
ExpectedHash string
329+
TypedDataName string
330+
TypeName string
331+
Context []string
332+
ExpectedHash string
307333
}
308334
testSet := []testSetType{
309335
{
310-
TypedData: typedDataExamples["baseExample"],
311-
TypeName: "StarkNetDomain",
312-
ExpectedHash: "0x54833b121883a3e3aebff48ec08a962f5742e5f7b973469c1f8f4f55d470b07",
336+
TypedDataName: "baseExample",
337+
TypeName: "StarkNetDomain",
338+
ExpectedHash: "0x54833b121883a3e3aebff48ec08a962f5742e5f7b973469c1f8f4f55d470b07",
313339
},
314340
{
315-
TypedData: typedDataExamples["example_baseTypes"],
316-
TypeName: "Example",
317-
ExpectedHash: "0x75db031c1f5bf980cc48f46943b236cb85a95c8f3b3c8203572453075d3d39",
341+
TypedDataName: "example_baseTypes",
342+
TypeName: "Example",
343+
ExpectedHash: "0x75db031c1f5bf980cc48f46943b236cb85a95c8f3b3c8203572453075d3d39",
318344
},
319345
{
320-
TypedData: typedDataExamples["example_presetTypes"],
321-
TypeName: "Example",
322-
ExpectedHash: "0x74fba3f77f8a6111a9315bac313bf75ecfa46d1234e0fda60312fb6a6517667",
346+
TypedDataName: "example_presetTypes",
347+
TypeName: "Example",
348+
ExpectedHash: "0x74fba3f77f8a6111a9315bac313bf75ecfa46d1234e0fda60312fb6a6517667",
323349
},
324350
{
325-
TypedData: typedDataExamples["session_MerkleTree"],
326-
TypeName: "Session",
327-
ExpectedHash: "0x73602062421caf6ad2e942253debfad4584bff58930981364dcd378021defe8",
351+
TypedDataName: "session_MerkleTree",
352+
TypeName: "Session",
353+
ExpectedHash: "0x73602062421caf6ad2e942253debfad4584bff58930981364dcd378021defe8",
328354
},
329355
{
330-
TypedData: typedDataExamples["v1Nested"],
331-
TypeName: "TransferERC721",
332-
ExpectedHash: "0x11b5fb80dd88c3d8b6239b065def4ac9a79e6995b117ed5940a3a0734324b79",
356+
TypedDataName: "v1Nested",
357+
TypeName: "TransferERC721",
358+
ExpectedHash: "0x11b5fb80dd88c3d8b6239b065def4ac9a79e6995b117ed5940a3a0734324b79",
333359
},
334360
{
335-
TypedData: typedDataExamples["example_enum"],
336-
TypeName: "Example",
337-
ExpectedHash: "0x1551dc992033e2256a2f7ec849495d90f9759ebb535e3006d16e2b9e3b57b4c",
361+
TypedDataName: "example_enum",
362+
TypeName: "Example",
363+
ExpectedHash: "0x1e1bb5d477e92cbf562b3b766c5c1e5f8590f2df868d4c8249c0db8416f8c37",
338364
},
339365
}
340366
for _, test := range testSet {
341-
hash, err := test.TypedData.GetStructHash(test.TypeName, test.Context...)
367+
td := typedDataExamples[test.TypedDataName]
368+
hash, err := td.GetStructHash(test.TypeName, test.Context...)
342369
require.NoError(t, err)
343370

344-
require.Equal(t, test.ExpectedHash, hash.String())
371+
assert.Equal(t, test.ExpectedHash, hash.String())
345372
}
346373
}

0 commit comments

Comments
 (0)