-
Notifications
You must be signed in to change notification settings - Fork 96
/
eip712sigs.go
118 lines (100 loc) · 3.22 KB
/
eip712sigs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright © 2022-2024 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1
package cluster
import (
k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/obolnetwork/charon/app/errors"
"github.com/obolnetwork/charon/app/k1util"
"github.com/obolnetwork/charon/eth2util"
"github.com/obolnetwork/charon/eth2util/eip712"
)
// eip712Type defines the EIP712 (https://eips.ethereum.org/EIPS/eip-712) Primary type and the Message field and value.
type eip712Type struct {
PrimaryType string
Field string
ValueFunc func(Definition, Operator) string
}
var (
// eip712CreatorConfigHash defines the EIP712 structure of the legacy config signature for v1.4 and later.
eip712CreatorConfigHash = eip712Type{
PrimaryType: "CreatorConfigHash",
Field: "creator_config_hash",
ValueFunc: func(definition Definition, _ Operator) string {
return to0xHex(definition.ConfigHash)
},
}
// eip712OperatorConfigHash defines the EIP712 structure of the operator config signature for v1.4 and later.
eip712OperatorConfigHash = eip712Type{
PrimaryType: "OperatorConfigHash",
Field: "operator_config_hash",
ValueFunc: func(definition Definition, _ Operator) string {
return to0xHex(definition.ConfigHash)
},
}
// eip712V1x3ConfigHash defines the EIP712 structure of the legacy config signature for v1.3 and before.
eip712V1x3ConfigHash = eip712Type{
PrimaryType: "ConfigHash",
Field: "config_hash",
ValueFunc: func(definition Definition, _ Operator) string {
return to0xHex(definition.ConfigHash)
},
}
// eip712ENR defines the EIP712 structure of the enr signature.
eip712ENR = eip712Type{
PrimaryType: "ENR",
Field: "enr",
ValueFunc: func(_ Definition, operator Operator) string {
return operator.ENR
},
}
)
// getOperatorEIP712Type returns the latest or legacy operator eip712 type.
func getOperatorEIP712Type(version string) eip712Type {
if !supportEIP712Sigs(version) {
panic("invalid eip712 signature version") // This should never happen
}
if isAnyVersion(version, v1_3) {
return eip712V1x3ConfigHash
}
return eip712OperatorConfigHash
}
// digestEIP712 returns the digest for the EIP712 structured type for the provided definition and operator.
func digestEIP712(typ eip712Type, def Definition, operator Operator) ([]byte, error) {
chainID, err := eth2util.ForkVersionToChainID(def.ForkVersion)
if err != nil {
return nil, err
}
data := eip712.TypedData{
Domain: eip712.Domain{
Name: "Obol",
Version: "1",
ChainID: chainID,
},
Type: eip712.Type{
Name: typ.PrimaryType,
Fields: []eip712.Field{
{
Name: typ.Field,
Type: eip712.PrimitiveString,
Value: typ.ValueFunc(def, operator),
},
},
},
}
digest, err := eip712.HashTypedData(data)
if err != nil {
return nil, errors.Wrap(err, "hash EIP712")
}
return digest, nil
}
// signEIP712 returns the EIP712 signature for the primary type.
func signEIP712(secret *k1.PrivateKey, typ eip712Type, def Definition, operator Operator) ([]byte, error) {
digest, err := digestEIP712(typ, def, operator)
if err != nil {
return nil, err
}
sig, err := k1util.Sign(secret, digest)
if err != nil {
return nil, errors.Wrap(err, "sign EIP712")
}
return sig, nil
}