Skip to content

Commit 84e3e81

Browse files
committed
⚡️ Improve empty subaccount
1 parent afec452 commit 84e3e81

File tree

1 file changed

+28
-22
lines changed

1 file changed

+28
-22
lines changed

lib/principal/principal.dart

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ const _typeOpaque = 1;
1717
final _emptySubAccount = Uint8List(32);
1818

1919
class Principal {
20-
Principal(
21-
this.principal, {
20+
const Principal(
21+
this._principal, {
2222
Uint8List? subAccount,
2323
}) : assert(subAccount == null || subAccount.length == 32),
24-
subAccount = subAccount != null && subAccount.eq(_emptySubAccount)
25-
? null
26-
: subAccount;
24+
_subAccount = subAccount;
2725

2826
factory Principal.selfAuthenticating(Uint8List publicKey) {
2927
final sha = sha224Hash(publicKey.buffer);
@@ -41,7 +39,7 @@ class Principal {
4139
} else if (other is Map<String, dynamic> && other['_isPrincipal'] == true) {
4240
return Principal(other['_arr'], subAccount: other['_subAccount']);
4341
} else if (other is Principal) {
44-
return Principal(other.principal, subAccount: other.subAccount);
42+
return Principal(other._principal, subAccount: other.subAccount);
4543
}
4644
throw UnreachableError();
4745
}
@@ -131,30 +129,37 @@ class Principal {
131129
return principal;
132130
}
133131

134-
final Uint8List principal;
135-
final Uint8List? subAccount;
132+
final Uint8List _principal;
133+
final Uint8List? _subAccount;
134+
135+
Uint8List? get subAccount {
136+
if (_subAccount case final v when v == null || v.eq(_emptySubAccount)) {
137+
return null;
138+
}
139+
return _subAccount;
140+
}
136141

137142
Principal newSubAccount(Uint8List? subAccount) {
138143
if (subAccount == null || subAccount.eq(_emptySubAccount)) {
139144
return this;
140145
}
141146
if (this.subAccount == null || !this.subAccount!.eq(subAccount)) {
142-
return Principal(principal, subAccount: subAccount);
147+
return Principal(_principal, subAccount: subAccount);
143148
}
144149
return this;
145150
}
146151

147152
bool isAnonymous() {
148-
return principal.lengthInBytes == 1 && principal[0] == _suffixAnonymous;
153+
return _principal.lengthInBytes == 1 && _principal[0] == _suffixAnonymous;
149154
}
150155

151-
Uint8List toUint8List() => principal;
156+
Uint8List toUint8List() => _principal;
152157

153-
String toHex() => _toHexString(principal).toUpperCase();
158+
String toHex() => _toHexString(_principal).toUpperCase();
154159

155160
String toText() {
156-
final checksum = _getChecksum(principal.buffer);
157-
final bytes = Uint8List.fromList(principal);
161+
final checksum = _getChecksum(_principal.buffer);
162+
final bytes = Uint8List.fromList(_principal);
158163
final array = Uint8List.fromList([...checksum, ...bytes]);
159164
final result = base32Encode(array);
160165
final reg = RegExp(r'.{1,5}');
@@ -164,8 +169,9 @@ class Principal {
164169
throw StateError('No characters found.');
165170
}
166171
final buffer = StringBuffer(matches.map((e) => e.group(0)).join('-'));
167-
if (subAccount != null) {
168-
final subAccountHex = subAccount!.toHex();
172+
if (_subAccount case final subAccount?
173+
when !subAccount.eq(_emptySubAccount)) {
174+
final subAccountHex = subAccount.toHex();
169175
int nonZeroStart = 0;
170176
while (nonZeroStart < subAccountHex.length) {
171177
if (subAccountHex[nonZeroStart] != '0') {
@@ -175,7 +181,7 @@ class Principal {
175181
}
176182
if (nonZeroStart != subAccountHex.length) {
177183
final checksum = base32Encode(
178-
_getChecksum(Uint8List.fromList(principal + subAccount!).buffer),
184+
_getChecksum(Uint8List.fromList(_principal + subAccount).buffer),
179185
);
180186
buffer.write('-$checksum');
181187
buffer.write('.');
@@ -189,7 +195,7 @@ class Principal {
189195
final hash = SHA224();
190196
hash.update('\x0Aaccount-id'.plainToU8a());
191197
hash.update(toUint8List());
192-
hash.update(subAccount ?? Uint8List(32));
198+
hash.update(subAccount ?? _emptySubAccount);
193199
final data = hash.digest();
194200
final view = ByteData(4);
195201
view.setUint32(0, getCrc32(data.buffer));
@@ -207,12 +213,12 @@ class Principal {
207213
bool operator ==(Object other) =>
208214
identical(this, other) ||
209215
other is Principal &&
210-
principal.eq(other.principal) &&
211-
(subAccount?.eq(other.subAccount ?? Uint8List(0)) ??
212-
subAccount == null && other.subAccount == null);
216+
_principal.eq(other._principal) &&
217+
(_subAccount?.eq(other._subAccount ?? _emptySubAccount) ??
218+
_subAccount == null && other._subAccount == null);
213219

214220
@override
215-
int get hashCode => Object.hash(principal, subAccount);
221+
int get hashCode => Object.hash(_principal, subAccount);
216222
}
217223

218224
class CanisterId extends Principal {

0 commit comments

Comments
 (0)