• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vaariance / eip-712 / 15663061800

15 Jun 2025 12:13PM UTC coverage: 84.0%. First build
15663061800

push

github

code-z2
feat: implement EIP-712 structured data signing

- Add core EIP-712 signing functionality with v3/v4 support
- Introduce TypedDataEncoder class for message encoding
- Add domain separator and type validation support
- Implement comprehensive type handling including arrays and custom structs
- Add utilities for hex/bigint conversions and ABI encoding
- Include example usage and update documentation
- Set up CI/CD with coverage reporting

210 of 250 new or added lines in 5 files covered. (84.0%)

210 of 250 relevant lines covered (84.0%)

1.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/lib/src/models.dart
1
part of 'typed_data.dart';
2

3
typedef TypeValuePair = ({String type, Object value});
4

5
@JsonEnum(valueField: 'version')
6
enum TypedDataVersion {
7
  v3(version: 'V3'),
8
  v4(version: 'V4');
9

10
  final String version;
11

12
  const TypedDataVersion({required this.version});
13
}
14

15
class EthereumAddressConverter extends JsonConverter<EthereumAddress, Object> {
16
  const EthereumAddressConverter();
3✔
17

18
  @override
1✔
19
  fromJson(address) {
20
    if (address is EthereumAddress) {
1✔
21
      return address;
22
    }
23
    return EthereumAddress.fromHex(address.toString());
2✔
24
  }
25

NEW
26
  @override
×
27
  toJson(address) {
NEW
28
    return address.with0x;
×
29
  }
30
}
31

32
class U8AConverter extends JsonConverter<Uint8List, Object> {
33
  const U8AConverter();
3✔
34

35
  @override
1✔
36
  fromJson(bytes) {
37
    if (bytes is Uint8List) {
1✔
38
      return bytes;
39
    } else if (bytes is List<int>) {
1✔
NEW
40
      return Uint8List.fromList(bytes);
×
41
    }
42
    return hexToBytes(bytes.toString());
2✔
43
  }
44

NEW
45
  @override
×
46
  toJson(bytes) {
NEW
47
    return bytesToHex(bytes, include0x: true);
×
48
  }
49
}
50

51
class BigintConverter extends JsonConverter<BigInt, Object> {
52
  const BigintConverter();
3✔
53

54
  @override
1✔
55
  fromJson(value) {
56
    return BigInt.parse(value.toString());
2✔
57
  }
58

NEW
59
  @override
×
60
  toJson(value) {
NEW
61
    return value.toInt();
×
62
  }
63
}
64

65
@freezed
66
abstract class MessageTypeProperty with _$MessageTypeProperty {
67
  const factory MessageTypeProperty({
68
    required String name,
69
    required String type,
70
  }) = _MessageTypeProperty;
71

72
  factory MessageTypeProperty.fromJson(Map<String, String> json) =>
1✔
73
      _$MessageTypePropertyFromJson(json);
1✔
74
}
75

76
@freezed
77
abstract class TypedMessage with _$TypedMessage {
78
  const factory TypedMessage({
79
    required Map<String, List<MessageTypeProperty>> types,
80
    required String primaryType,
81
    required EIP712Domain? domain,
82
    required Map<String, dynamic> message,
83
  }) = _TypedMessage;
84

85
  factory TypedMessage.fromJson(Map<String, Object?> json) =>
1✔
86
      _$TypedMessageFromJson(json);
1✔
87
}
88

89
@freezed
90
abstract class EIP712Domain with _$EIP712Domain {
91
  const EIP712Domain._();
1✔
92

93
  const factory EIP712Domain({
94
    required String? name,
95
    required String? version,
96
    @BigintConverter() required BigInt? chainId,
97
    @EthereumAddressConverter() required EthereumAddress? verifyingContract,
98
    @U8AConverter() required Uint8List? salt,
99
  }) = _EIP712Domain;
100

101
  factory EIP712Domain.fromJson(Map<String, Object?> json) =>
1✔
102
      _$EIP712DomainFromJson(json);
1✔
103

104
  dynamic operator [](String key) {
1✔
105
    switch (key) {
106
      case 'name':
1✔
107
        return name;
1✔
108
      case 'version':
1✔
109
        return version;
1✔
110
      case 'chainId':
1✔
111
        return chainId;
1✔
112
      case 'verifyingContract':
1✔
113
        return verifyingContract;
1✔
114
      case 'salt':
1✔
115
        return salt;
1✔
116
      default:
NEW
117
        throw ArgumentError("Var $key is not declared in EIP712Domain");
×
118
    }
119
  }
120
}
121

122
@freezed
123
sealed class MessageTypes with _$MessageTypes {
124
  const factory MessageTypes.eip712Domain({required EIP712Domain? value}) =
125
      Eip712Domain;
126

127
  const factory MessageTypes.additionalData({
128
    required Map<String, dynamic>? value,
129
  }) = AdditionalData;
130

131
  factory MessageTypes.from(dynamic raw) =>
1✔
132
      MessageTypes.additionalData(value: raw as Map<String, dynamic>);
1✔
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc