feat(grants-create): add configurable grant authorization fields
This commit is contained in:
@@ -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/token_transfer_grant.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/utils.dart';
|
||||
import 'package:arbiter/theme/palette.dart';
|
||||
@@ -101,8 +105,64 @@ class CreateEvmGrantScreen extends HookConsumerWidget {
|
||||
const _IntroCard(),
|
||||
SizedBox(height: 1.8.h),
|
||||
const _Section(
|
||||
title: 'Shared grant options',
|
||||
child: SharedGrantFields(),
|
||||
title: 'Authorization',
|
||||
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),
|
||||
_GrantTypeSelector(
|
||||
@@ -112,6 +172,8 @@ class CreateEvmGrantScreen extends HookConsumerWidget {
|
||||
SizedBox(height: 1.8.h),
|
||||
_Section(
|
||||
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),
|
||||
),
|
||||
SizedBox(height: 2.2.h),
|
||||
@@ -175,13 +237,21 @@ class _IntroCard 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 tooltip;
|
||||
final Widget child;
|
||||
final bool optional;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final subtleColor = Theme.of(context).colorScheme.outline;
|
||||
return Container(
|
||||
padding: EdgeInsets.all(2.h),
|
||||
decoration: BoxDecoration(
|
||||
@@ -191,6 +261,8 @@ class _Section extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
@@ -198,6 +270,26 @@ class _Section extends StatelessWidget {
|
||||
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),
|
||||
child,
|
||||
],
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
// 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/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:flutter/material.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
|
||||
/// All shared grant fields in a single vertical layout.
|
||||
///
|
||||
/// Every [FormBuilderField] descendant auto-registers with the nearest
|
||||
/// [FormBuilder] ancestor via [BuildContext] — no controllers passed.
|
||||
class SharedGrantFields extends StatelessWidget {
|
||||
const SharedGrantFields({super.key});
|
||||
class AuthorizationFields extends StatelessWidget {
|
||||
const AuthorizationFields({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -23,15 +15,8 @@ class SharedGrantFields extends StatelessWidget {
|
||||
const ClientPickerField(),
|
||||
SizedBox(height: 1.6.h),
|
||||
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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user