feat(useragent): bootstrap / unseal flow implementattion

This commit is contained in:
hdbg
2026-03-15 22:12:21 +01:00
parent c61a9e30ac
commit 4db102b3d1
19 changed files with 1213 additions and 114 deletions

View File

@@ -6,6 +6,7 @@ part 'bootstrap_token.g.dart';
@Riverpod(keepAlive: true)
class BootstrapToken extends _$BootstrapToken {
@override
String? build() {
return null;
}
@@ -14,9 +15,13 @@ class BootstrapToken extends _$BootstrapToken {
state = token;
}
void clear() {
state = null;
}
String? take() {
final token = state;
state = null;
return token;
}
}
}

View File

@@ -41,7 +41,7 @@ final class BootstrapTokenProvider
}
}
String _$bootstrapTokenHash() => r'a59e679ab0561ed2ab4148660499891571d439db';
String _$bootstrapTokenHash() => r'5c09ea4480fc3a7fd0d0a0bced712912542cca5d';
abstract class _$BootstrapToken extends $Notifier<String?> {
String? build();

View File

@@ -20,12 +20,18 @@ class ConnectionManager extends _$ConnectionManager {
}
final Connection connection;
try {
connection = await connectAndAuthorize(serverInfo, key, bootstrapToken: token);
connection = await connectAndAuthorize(
serverInfo,
key,
bootstrapToken: token,
);
if (token != null) {
ref.read(bootstrapTokenProvider.notifier).clear();
}
} catch (e) {
talker.handle(e);
rethrow;
}
ref.onDispose(() {
final connection = state.asData?.value;

View File

@@ -33,7 +33,7 @@ final class ConnectionManagerProvider
ConnectionManager create() => ConnectionManager();
}
String _$connectionManagerHash() => r'8923346dff75a9a06127c71a0a39ca65d9733d8c';
String _$connectionManagerHash() => r'd01084e550f315bc6cadfe74413a7f959426a80e';
abstract class _$ConnectionManager extends $AsyncNotifier<Connection?> {
FutureOr<Connection?> build();

View File

@@ -0,0 +1,23 @@
import 'package:arbiter/proto/evm.pb.dart';
import 'package:arbiter/proto/user_agent.pb.dart';
import 'package:arbiter/providers/connection/connection_manager.dart';
import 'package:protobuf/well_known_types/google/protobuf/empty.pb.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'evm.g.dart';
@riverpod
class Evm extends _$Evm {
Future<List<WalletEntry>?> build() async {
final connection = await ref.watch(connectionManagerProvider.future);
if (connection == null) {
return null;
}
await connection.send(UserAgentRequest(
evmWalletList: Empty()
));
final response = await connection.receive();
}
}

View File

@@ -0,0 +1,55 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'evm.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(Evm)
final evmProvider = EvmProvider._();
final class EvmProvider
extends $AsyncNotifierProvider<Evm, List<WalletEntry>?> {
EvmProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'evmProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$evmHash();
@$internal
@override
Evm create() => Evm();
}
String _$evmHash() => r'6d2e0baf7b78a0850d7b99b0be7abde206e088c7';
abstract class _$Evm extends $AsyncNotifier<List<WalletEntry>?> {
FutureOr<List<WalletEntry>?> build();
@$mustCallSuper
@override
void runBuild() {
final ref =
this.ref as $Ref<AsyncValue<List<WalletEntry>?>, List<WalletEntry>?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<WalletEntry>?>, List<WalletEntry>?>,
AsyncValue<List<WalletEntry>?>,
Object?,
Object?
>;
element.handleCreate(ref, build);
}
}

View File

@@ -0,0 +1,27 @@
import 'package:arbiter/proto/user_agent.pb.dart';
import 'package:arbiter/providers/connection/connection_manager.dart';
import 'package:mtcore/markettakers.dart';
import 'package:protobuf/well_known_types/google/protobuf/empty.pb.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'vault_state.g.dart';
@riverpod
Future<VaultState?> vaultState(Ref ref) async {
final conn = await ref.watch(connectionManagerProvider.future);
if (conn == null) {
return null;
}
await conn.send(UserAgentRequest(queryVaultState: Empty()));
final resp = await conn.receive();
if (resp.whichPayload() != UserAgentResponse_Payload.vaultState) {
talker.warning('Expected vault state response, got ${resp.whichPayload()}');
return null;
}
final vaultState = resp.vaultState;
return vaultState;
}

View File

@@ -0,0 +1,49 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'vault_state.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(vaultState)
final vaultStateProvider = VaultStateProvider._();
final class VaultStateProvider
extends
$FunctionalProvider<
AsyncValue<VaultState?>,
VaultState?,
FutureOr<VaultState?>
>
with $FutureModifier<VaultState?>, $FutureProvider<VaultState?> {
VaultStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'vaultStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$vaultStateHash();
@$internal
@override
$FutureProviderElement<VaultState?> $createElement(
$ProviderPointer pointer,
) => $FutureProviderElement(pointer);
@override
FutureOr<VaultState?> create(Ref ref) {
return vaultState(ref);
}
}
String _$vaultStateHash() => r'1fd975a9661de1f62beef9eb1c7c439f377a8b88';