github.com/status-im/status-go@v1.1.0/services/typeddata/metamask_test.go (about)

     1  package typeddata
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"encoding/json"
     6  	"math/big"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/suite"
    10  
    11  	"github.com/ethereum/go-ethereum/crypto"
    12  
    13  	"github.com/ethereum/go-ethereum/signer/core/apitypes"
    14  	"github.com/status-im/status-go/eth-node/types"
    15  )
    16  
    17  func TestTypedDataSuite(t *testing.T) {
    18  	suite.Run(t, new(TypedDataSuite))
    19  }
    20  
    21  type TypedDataSuite struct {
    22  	suite.Suite
    23  
    24  	privateKey  *ecdsa.PrivateKey
    25  	typedDataV3 apitypes.TypedData
    26  	typedDataV4 apitypes.TypedData
    27  }
    28  
    29  func (s *TypedDataSuite) SetupTest() {
    30  	pk, err := crypto.ToECDSA(crypto.Keccak256([]byte("cow")))
    31  	s.Require().NoError(err)
    32  
    33  	s.privateKey = pk
    34  
    35  	s.Require().NoError(json.Unmarshal([]byte(typedDataV3), &s.typedDataV3))
    36  	s.Require().NoError(json.Unmarshal([]byte(typedDataV4), &s.typedDataV4))
    37  }
    38  
    39  func (s *TypedDataSuite) TestTypedDataV3() {
    40  	signature, err := SignTypedDataV4(s.typedDataV3, s.privateKey, big.NewInt(1))
    41  	s.Require().NoError(err)
    42  	s.Require().Equal("0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c", types.EncodeHex(signature))
    43  }
    44  
    45  func (s *TypedDataSuite) TestTypedDataV4() {
    46  
    47  	expected := "0xfabfe1ed996349fc6027709802be19d047da1aa5d6894ff5f6486d92db2e6860"
    48  	actual := s.typedDataV4.TypeHash("Person")
    49  	s.Require().Equal(expected, actual.String())
    50  
    51  	fromTypedData := apitypes.TypedData{}
    52  	s.Require().NoError(json.Unmarshal([]byte(fromJSON), &fromTypedData))
    53  
    54  	actual, err := s.typedDataV4.HashStruct("Person", fromTypedData.Message)
    55  	s.Require().NoError(err)
    56  	expected = "0x9b4846dd48b866f0ac54d61b9b21a9e746f921cefa4ee94c4c0a1c49c774f67f"
    57  	s.Require().Equal(expected, actual.String())
    58  
    59  	encodedData, err := s.typedDataV4.EncodeData(s.typedDataV4.PrimaryType, s.typedDataV4.Message, 1)
    60  	s.Require().NoError(err)
    61  
    62  	expected = "0x4bd8a9a2b93427bb184aca81e24beb30ffa3c747e2a33d4225ec08bf12e2e7539b4846dd48b866f0ac54d61b9b21a9e746f921cefa4ee94c4c0a1c49c774f67fca322beec85be24e374d18d582a6f2997f75c54e7993ab5bc07404ce176ca7cdb5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"
    63  	s.Require().Equal(expected, encodedData.String())
    64  
    65  	actual, err = s.typedDataV4.HashStruct(s.typedDataV4.PrimaryType, s.typedDataV4.Message)
    66  	s.Require().NoError(err)
    67  
    68  	expected = "0xeb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8"
    69  	s.Require().Equal(expected, actual.String())
    70  
    71  	signature, err := SignTypedDataV4(s.typedDataV4, s.privateKey, big.NewInt(1))
    72  	s.Require().NoError(err)
    73  	s.Require().Equal("0x65cbd956f2fae28a601bebc9b906cea0191744bd4c4247bcd27cd08f8eb6b71c78efdf7a31dc9abee78f492292721f362d296cf86b4538e07b51303b67f749061b", types.EncodeHex(signature))
    74  }
    75  
    76  const typedDataV3 = `
    77  {
    78  	"types": {
    79  		"EIP712Domain": [
    80  			{
    81  				"name": "name",
    82  				"type": "string"
    83  			},
    84  			{
    85  				"name": "version",
    86  				"type": "string"
    87  			},
    88  			{
    89  				"name": "chainId",
    90  				"type": "uint256"
    91  			},
    92  			{
    93  				"name": "verifyingContract",
    94  				"type": "address"
    95  			}
    96  		],
    97  		"Person": [
    98  			{
    99  				"name": "name",
   100  				"type": "string"
   101  			},
   102  			{
   103  				"name": "wallet",
   104  				"type": "address"
   105  			}
   106  		],
   107  		"Mail": [
   108  			{
   109  				"name": "from",
   110  				"type": "Person"
   111  			},
   112  			{
   113  				"name": "to",
   114  				"type": "Person"
   115  			},
   116  			{
   117  				"name": "contents",
   118  				"type": "string"
   119  			}
   120  		]
   121  	},
   122  	"primaryType": "Mail",
   123  	"domain": {
   124  		"name": "Ether Mail",
   125  		"version": "1",
   126  		"chainId": "1",
   127  		"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
   128  	},
   129  	"message": {
   130  		"from": {
   131  			"name": "Cow",
   132  			"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
   133  		},
   134  		"to": {
   135  			"name": "Bob",
   136  			"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
   137  		},
   138  		"contents": "Hello, Bob!"
   139  	}
   140  }
   141  `
   142  
   143  const typedDataV4 = `
   144  {
   145  	"types": {
   146  		"EIP712Domain": [
   147  			{
   148  				"name": "name",
   149  				"type": "string"
   150  			},
   151  			{
   152  				"name": "version",
   153  				"type": "string"
   154  			},
   155  			{
   156  				"name": "chainId",
   157  				"type": "uint256"
   158  			},
   159  			{
   160  				"name": "verifyingContract",
   161  				"type": "address"
   162  			}
   163  		],
   164  		"Person": [
   165  			{
   166  				"name": "name",
   167  				"type": "string"
   168  			},
   169  			{
   170  				"name": "wallets",
   171  				"type": "address[]"
   172  			}
   173  		],
   174  		"Mail": [
   175  			{
   176  				"name": "from",
   177  				"type": "Person"
   178  			},
   179  			{
   180  				"name": "to",
   181  				"type": "Person[]"
   182  			},
   183  			{
   184  				"name": "contents",
   185  				"type": "string"
   186  			}
   187  		],
   188  		"Group": [
   189  			{
   190  				"name": "name",
   191  				"type": "string"
   192  			},
   193  			{
   194  				"name": "members",
   195  				"type": "Person[]"
   196  			}
   197  		]
   198  	},
   199  	"domain": {
   200  		"name": "Ether Mail",
   201  		"version": "1",
   202  		"chainId": "1",
   203  		"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
   204  	},
   205  	"primaryType": "Mail",
   206  	"message": {
   207  		"from": {
   208  			"name": "Cow",
   209  			"wallets": [
   210  				"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
   211  				"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
   212  			]
   213  		},
   214  		"to": [
   215  			{
   216  				"name": "Bob",
   217  				"wallets": [
   218  					"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
   219  					"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
   220  					"0xB0B0b0b0b0b0B000000000000000000000000000"
   221  				]
   222  			}
   223  		],
   224  		"contents": "Hello, Bob!"
   225  	}
   226  }
   227  `
   228  const fromJSON = `
   229  {
   230  	"types": {
   231  		"EIP712Domain": [
   232  			{
   233  				"name": "name",
   234  				"type": "string"
   235  			},
   236  			{
   237  				"name": "version",
   238  				"type": "string"
   239  			},
   240  			{
   241  				"name": "chainId",
   242  				"type": "uint256"
   243  			},
   244  			{
   245  				"name": "verifyingContract",
   246  				"type": "address"
   247  			}
   248  		],
   249  		"Person": [
   250  			{
   251  				"name": "name",
   252  				"type": "string"
   253  			},
   254  			{
   255  				"name": "wallets",
   256  				"type": "address[]"
   257  			}
   258  		],
   259  		"Mail": [
   260  			{
   261  				"name": "from",
   262  				"type": "Person"
   263  			},
   264  			{
   265  				"name": "to",
   266  				"type": "Person[]"
   267  			},
   268  			{
   269  				"name": "contents",
   270  				"type": "string"
   271  			}
   272  		],
   273  		"Group": [
   274  			{
   275  				"name": "name",
   276  				"type": "string"
   277  			},
   278  			{
   279  				"name": "members",
   280  				"type": "Person[]"
   281  			}
   282  		]
   283  	},
   284  	"domain": {
   285  		"name": "Ether Mail",
   286  		"version": "1",
   287  		"chainId": "1",
   288  		"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
   289  	},
   290  	"primaryType": "Mail",
   291  	"message": {
   292  			"name": "Cow",
   293  			"wallets": [
   294  				"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
   295  				"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
   296  			]
   297  		}
   298  	}
   299  `