feat(grants-create): add configurable grant authorization fields

This commit is contained in:
hdbg
2026-03-29 00:13:45 +01:00
parent 59c7091cba
commit b5507e7d0f
2 changed files with 102 additions and 25 deletions

View File

@@ -5,6 +5,10 @@ import 'package:arbiter/screens/dashboard/evm/grants/create/grants/ether_transfe
import 'package:arbiter/screens/dashboard/evm/grants/create/grants/grant_form_handler.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/grants/grant_form_handler.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/grants/token_transfer_grant.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/grants/token_transfer_grant.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/provider.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/provider.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/chain_id_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/gas_fee_options_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/transaction_rate_limit_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/validity_window_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/shared_grant_fields.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/shared_grant_fields.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/utils.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/utils.dart';
import 'package:arbiter/theme/palette.dart'; import 'package:arbiter/theme/palette.dart';
@@ -101,8 +105,64 @@ class CreateEvmGrantScreen extends HookConsumerWidget {
const _IntroCard(), const _IntroCard(),
SizedBox(height: 1.8.h), SizedBox(height: 1.8.h),
const _Section( const _Section(
title: 'Shared grant options', title: 'Authorization',
child: SharedGrantFields(), tooltip: 'Select which SDK client receives this grant and '
'which of its wallet accesses it applies to.',
child: AuthorizationFields(),
),
SizedBox(height: 1.8.h),
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Expanded(
child: _Section(
title: 'Chain',
tooltip: 'Restrict this grant to a specific EVM chain ID. '
'Leave empty to allow any chain.',
optional: true,
child: ChainIdField(),
),
),
SizedBox(width: 1.8.w),
const Expanded(
child: _Section(
title: 'Timing',
tooltip: 'Set an optional validity window. '
'Signing requests outside this period will be rejected.',
optional: true,
child: ValidityWindowField(),
),
),
],
),
),
SizedBox(height: 1.8.h),
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Expanded(
child: _Section(
title: 'Gas limits',
tooltip: 'Cap the gas fees this grant may authorize. '
'Transactions exceeding these values will be rejected.',
optional: true,
child: GasFeeOptionsField(),
),
),
SizedBox(width: 1.8.w),
const Expanded(
child: _Section(
title: 'Transaction limits',
tooltip: 'Limit how many transactions can be signed '
'within a rolling time window.',
optional: true,
child: TransactionRateLimitField(),
),
),
],
),
), ),
SizedBox(height: 1.8.h), SizedBox(height: 1.8.h),
_GrantTypeSelector( _GrantTypeSelector(
@@ -112,6 +172,8 @@ class CreateEvmGrantScreen extends HookConsumerWidget {
SizedBox(height: 1.8.h), SizedBox(height: 1.8.h),
_Section( _Section(
title: 'Grant-specific options', title: 'Grant-specific options',
tooltip: 'Rules specific to the selected transfer type. '
'Switch between Ether and token above to change these fields.',
child: handler.buildForm(context, ref), child: handler.buildForm(context, ref),
), ),
SizedBox(height: 2.2.h), SizedBox(height: 2.2.h),
@@ -175,13 +237,21 @@ class _IntroCard extends StatelessWidget {
} }
class _Section extends StatelessWidget { class _Section extends StatelessWidget {
const _Section({required this.title, required this.child}); const _Section({
required this.title,
required this.tooltip,
required this.child,
this.optional = false,
});
final String title; final String title;
final String tooltip;
final Widget child; final Widget child;
final bool optional;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final subtleColor = Theme.of(context).colorScheme.outline;
return Container( return Container(
padding: EdgeInsets.all(2.h), padding: EdgeInsets.all(2.h),
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -192,11 +262,33 @@ class _Section extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Row(
title, children: [
style: Theme.of(context).textTheme.titleMedium?.copyWith( Text(
fontWeight: FontWeight.w800, title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w800,
),
),
SizedBox(width: 0.4.w),
Tooltip(
message: tooltip,
child: Icon(
Icons.info_outline_rounded,
size: 16,
color: subtleColor,
), ),
),
if (optional) ...[
SizedBox(width: 0.6.w),
Text(
'(optional)',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: subtleColor,
),
),
],
],
), ),
SizedBox(height: 1.4.h), SizedBox(height: 1.4.h),
child, child,

View File

@@ -1,19 +1,11 @@
// lib/screens/dashboard/evm/grants/create/shared_grant_fields.dart // lib/screens/dashboard/evm/grants/create/shared_grant_fields.dart
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/chain_id_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/client_picker_field.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/fields/client_picker_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/gas_fee_options_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/transaction_rate_limit_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/validity_window_field.dart';
import 'package:arbiter/screens/dashboard/evm/grants/create/fields/wallet_access_picker_field.dart'; import 'package:arbiter/screens/dashboard/evm/grants/create/fields/wallet_access_picker_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sizer/sizer.dart'; import 'package:sizer/sizer.dart';
/// All shared grant fields in a single vertical layout. class AuthorizationFields extends StatelessWidget {
/// const AuthorizationFields({super.key});
/// Every [FormBuilderField] descendant auto-registers with the nearest
/// [FormBuilder] ancestor via [BuildContext] — no controllers passed.
class SharedGrantFields extends StatelessWidget {
const SharedGrantFields({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -23,15 +15,8 @@ class SharedGrantFields extends StatelessWidget {
const ClientPickerField(), const ClientPickerField(),
SizedBox(height: 1.6.h), SizedBox(height: 1.6.h),
const WalletAccessPickerField(), const WalletAccessPickerField(),
SizedBox(height: 1.6.h),
const ChainIdField(),
SizedBox(height: 1.6.h),
const ValidityWindowField(),
SizedBox(height: 1.6.h),
const GasFeeOptionsField(),
SizedBox(height: 1.6.h),
const TransactionRateLimitField(),
], ],
); );
} }
} }