Files
jinzhi/lib/features/auth/data/one_key_login_api.dart
T
2026-08-24 19:07:31 +08:00

93 lines
2.4 KiB
Dart

import 'dart:convert';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import '../../../common/network/dio_provider.dart';
/// Compatible with Yanting's protobuf `/api/v1/auth/onekey/verify` contract.
class OneKeyLoginApi {
OneKeyLoginApi(this._dio);
final Dio _dio;
Future<OneKeyLoginReply> verify(String loginToken) async {
final bytes = utf8.encode(loginToken);
final request = Uint8List.fromList([
0x0A,
..._varint(bytes.length),
...bytes,
]);
final response = await _dio.post<List<int>>(
'/api/v1/auth/onekey/verify',
data: request,
options: protobufOptions(),
);
return _decode(Uint8List.fromList(response.data ?? const []));
}
OneKeyLoginReply _decode(Uint8List data) {
final fields = _fields(data);
final token = utf8.decode(fields[1] ?? const []);
final user = _fields(Uint8List.fromList(fields[3] ?? const []));
if (token.isEmpty) throw StateError('一键登录服务未返回登录凭证');
return OneKeyLoginReply(
token: token,
phone: utf8.decode(user[2] ?? const []),
);
}
Map<int, List<int>> _fields(Uint8List data) {
final result = <int, List<int>>{};
var i = 0;
while (i < data.length) {
final tag = _readVarint(data, i);
i = tag.$2;
final wireType = tag.$1 & 7;
if (wireType == 0) {
i = _readVarint(data, i).$2;
continue;
}
if (wireType != 2) {
throw const FormatException('Unsupported protobuf field');
}
final length = _readVarint(data, i);
i = length.$2;
final end = i + length.$1;
if (end > data.length) {
throw const FormatException('Invalid protobuf payload');
}
result[tag.$1 >> 3] = data.sublist(i, end);
i = end;
}
return result;
}
(int, int) _readVarint(Uint8List data, int index) {
var value = 0;
var shift = 0;
while (index < data.length) {
final byte = data[index++];
value |= (byte & 0x7f) << shift;
if (byte & 0x80 == 0) return (value, index);
shift += 7;
}
throw const FormatException('Invalid protobuf varint');
}
List<int> _varint(int value) {
final result = <int>[];
while (value > 0x7f) {
result.add((value & 0x7f) | 0x80);
value >>= 7;
}
result.add(value);
return result;
}
}
class OneKeyLoginReply {
const OneKeyLoginReply({required this.token, required this.phone});
final String token;
final String phone;
}