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

vaariance / eip-712 / 15665149611

15 Jun 2025 04:24PM UTC coverage: 95.341% (+1.0%) from 94.386%
15665149611

push

github

code-z2
refactor(typed_data): improve type safety and documentation

- Add comprehensive documentation for EIP-712 implementation
- Replace switch statement with pattern matching in MessageTypesIndexing
- Improve type safety by adding Object? return type to decode method
- Remove unused StateError catch block in README
- Add debug prints in example file for better visibility
- Simplify ObjectExtension implementation

4 of 4 new or added lines in 2 files covered. (100.0%)

1 existing line in 1 file now uncovered.

266 of 279 relevant lines covered (95.34%)

1.43 hits per line

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

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

3
/// Represents a pair of type and value used in EIP-712 typed data
4
typedef TypeValuePair = ({String type, Object value});
5

6
/// Specifies the version of EIP-712 typed data
7
@JsonEnum(valueField: 'version')
8
enum TypedDataVersion {
9
  /// Version 3 of the EIP-712 specification
10
  v3(version: 'V3'),
11

12
  /// Version 4 of the EIP-712 specification
13
  v4(version: 'V4');
14

15
  final String version;
16

17
  const TypedDataVersion({required this.version});
18
}
19

20
/// Converts between EthereumAddress and JSON representation
21
class EthereumAddressConverter extends JsonConverter<EthereumAddress, Object> {
22
  const EthereumAddressConverter();
4✔
23

24
  /// Converts a JSON value to an EthereumAddress
25
  @override
1✔
26
  fromJson(address) {
27
    if (address is EthereumAddress) {
1✔
28
      return address;
29
    }
30
    return EthereumAddress.fromHex(address.toString());
2✔
31
  }
32

33
  /// Converts an EthereumAddress to its JSON representation
34
  @override
1✔
35
  toJson(address) {
36
    return address.with0x;
1✔
37
  }
38
}
39

40
/// Converts between Uint8List and JSON representation
41
class U8AConverter extends JsonConverter<Uint8List, Object> {
42
  const U8AConverter();
4✔
43

44
  /// Converts a JSON value to a Uint8List
45
  @override
1✔
46
  fromJson(bytes) {
47
    if (bytes is Uint8List) {
1✔
48
      return bytes;
49
    } else if (bytes is List<int>) {
1✔
50
      return Uint8List.fromList(bytes);
×
51
    }
52
    return hexToBytes(bytes.toString());
2✔
53
  }
54

55
  /// Converts a Uint8List to its JSON representation
56
  @override
1✔
57
  toJson(bytes) {
58
    return bytesToHex(bytes, include0x: true);
1✔
59
  }
60
}
61

62
/// Converts between BigInt and JSON representation
63
class BigintConverter extends JsonConverter<BigInt, Object> {
64
  const BigintConverter();
3✔
65

66
  /// Converts a JSON value to a BigInt
67
  @override
1✔
68
  fromJson(value) {
69
    return BigInt.parse(value.toString());
2✔
70
  }
71

72
  /// Converts a BigInt to its JSON representation
73
  @override
1✔
74
  toJson(value) {
75
    return value.toInt();
1✔
76
  }
77
}
78

79
/// Represents a property in an EIP-712 message type
80
@freezed
81
abstract class MessageTypeProperty with _$MessageTypeProperty {
82
  const factory MessageTypeProperty({
83
    /// The name of the property
84
    required String name,
85

86
    /// The type of the property
87
    required String type,
88
  }) = _MessageTypeProperty;
89

90
  factory MessageTypeProperty.fromJson(Map<String, String> json) =>
1✔
91
      _$MessageTypePropertyFromJson(json);
1✔
92
}
93

94
/// Represents a complete EIP-712 typed message
95
@freezed
96
abstract class TypedMessage with _$TypedMessage {
97
  @JsonSerializable(explicitToJson: true)
98
  const factory TypedMessage({
99
    /// The type definitions for the message
100
    required Map<String, List<MessageTypeProperty>> types,
101

102
    /// The primary type being signed
103
    required String primaryType,
104

105
    /// The domain separator data
106
    required EIP712Domain? domain,
107

108
    /// The message data
109
    required Map<String, dynamic> message,
110
  }) = _TypedMessage;
111

112
  factory TypedMessage.fromJson(Map<String, Object?> json) =>
1✔
113
      _$TypedMessageFromJson(json);
1✔
114
}
115

116
/// Represents the domain separator for EIP-712 typed data
117
@freezed
118
abstract class EIP712Domain with _$EIP712Domain {
119
  const EIP712Domain._();
2✔
120

121
  const factory EIP712Domain({
122
    /// The name of the signing domain
123
    required String? name,
124

125
    /// The version of the signing domain
126
    required String? version,
127

128
    /// The chain ID of the network
129
    @BigintConverter() required BigInt? chainId,
130

131
    /// The verifying contract address
132
    @EthereumAddressConverter() required EthereumAddress? verifyingContract,
133

134
    /// An optional salt value
135
    @U8AConverter() required Uint8List? salt,
136
  }) = _EIP712Domain;
137

138
  /// The type string for the domain separator
139
  static String get type => 'EIP712Domain';
1✔
140

141
  factory EIP712Domain.fromJson(Map<String, Object?> json) =>
1✔
142
      _$EIP712DomainFromJson(json);
1✔
143

144
  /// Creates an empty EIP712Domain with all fields set to null
UNCOV
145
  factory EIP712Domain.empty() => const EIP712Domain(
×
146
    name: null,
147
    version: null,
148
    chainId: null,
149
    verifyingContract: null,
150
    salt: null,
151
  );
152

153
  /// Provides array access to domain properties
154
  dynamic operator [](String key) {
1✔
155
    switch (key) {
156
      case 'name':
1✔
157
        return name;
1✔
158
      case 'version':
1✔
159
        return version;
1✔
160
      case 'chainId':
1✔
161
        return chainId;
1✔
162
      case 'verifyingContract':
1✔
163
        return verifyingContract;
1✔
164
      case 'salt':
1✔
165
        return salt;
1✔
166
      default:
167
        throw ArgumentError("Var $key is not declared in EIP712Domain");
×
168
    }
169
  }
170
}
171

172
/// Represents different types of messages in EIP-712
173
@freezed
174
sealed class MessageTypes with _$MessageTypes {
175
  /// Creates a domain separator message type
176
  const factory MessageTypes.eip712Domain({required EIP712Domain? value}) =
177
      Eip712Domain;
178

179
  /// Creates an additional data message type
180
  const factory MessageTypes.additionalData({
181
    required Map<String, dynamic>? value,
182
  }) = AdditionalData;
183

184
  /// Creates a MessageTypes instance from raw data
185
  factory MessageTypes.from(dynamic raw) =>
1✔
186
      MessageTypes.additionalData(value: raw as Map<String, dynamic>?);
1✔
187
}
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