Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export 'wallet/get_wallet.dart';
export 'wallet/get_wallet_names_request.dart';
export 'wallet/get_wallet_names_response.dart';
export 'wallet/my_balance.dart';
export 'wallet/unban_pubkeys.dart';
export 'withdrawal/send_raw_transaction_request.dart';
export 'withdrawal/withdraw_request.dart';
export 'withdrawal/withdrawal_rpc_namespace.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import 'package:equatable/equatable.dart';
import 'package:komodo_defi_rpc_methods/src/internal_exports.dart';
import 'package:komodo_defi_types/komodo_defi_type_utils.dart';

/// Determines how pubkeys should be unbanned
enum UnbanType {
all,
few;

@override
String toString() => switch (this) {
UnbanType.all => 'All',
UnbanType.few => 'Few',
};

static UnbanType parse(String value) {
final lowerValue = value.toLowerCase();
if (lowerValue == 'all') {
return UnbanType.all;
} else if (lowerValue == 'few') {
return UnbanType.few;
} else {
throw ArgumentError(
'Invalid UnbanType value: $value. Expected "all" or "few".',
);
}
}
}

/// Parameter for [UnbanPubkeysRequest]
class UnbanBy extends Equatable {
const UnbanBy.all() : type = UnbanType.all, data = null;
const UnbanBy.few(this.data) : type = UnbanType.few;

final UnbanType type;
final List<String>? data;

JsonMap toJson() => {'type': type.toString(), if (data != null) 'data': data};

@override
List<Object?> get props => [type, data];
}
Comment thread
CharlVS marked this conversation as resolved.

class UnbanPubkeysRequest
extends BaseRequest<UnbanPubkeysResponse, GeneralErrorResponse> {
UnbanPubkeysRequest({required String rpcPass, required this.unbanBy})
: super(method: 'unban_pubkeys', rpcPass: rpcPass, mmrpc: null);
Comment thread
CharlVS marked this conversation as resolved.

final UnbanBy unbanBy;

@override
JsonMap toJson() => {...super.toJson(), 'unban_by': unbanBy.toJson()};

@override
UnbanPubkeysResponse parse(JsonMap json) => UnbanPubkeysResponse.parse(json);
}

class UnbanPubkeysResponse extends BaseResponse {
UnbanPubkeysResponse({required super.mmrpc, required this.result});

factory UnbanPubkeysResponse.parse(JsonMap json) => UnbanPubkeysResponse(
mmrpc: json.valueOrNull<String>('mmrpc'),
result: UnbanPubkeysResult.fromJson(json.value<JsonMap>('result')),
);

final UnbanPubkeysResult result;

@override
JsonMap toJson() => {'mmrpc': mmrpc, 'result': result.toJson()};
}

class UnbanPubkeysResult extends Equatable {
const UnbanPubkeysResult({
required this.stillBanned,
required this.unbanned,
required this.wereNotBanned,
});

factory UnbanPubkeysResult.fromJson(JsonMap json) {
final still = json.valueOrNull<JsonMap>('still_banned') ?? {};
final unbanned = json.valueOrNull<JsonMap>('unbanned') ?? {};
return UnbanPubkeysResult(
stillBanned: still.map(
(k, v) => MapEntry(k, BannedPubkeyInfo.fromJson(v as JsonMap)),
),
unbanned: unbanned.map(
(k, v) => MapEntry(k, BannedPubkeyInfo.fromJson(v as JsonMap)),
),
wereNotBanned:
(json.valueOrNull<List<dynamic>>('were_not_banned') ?? [])
.cast<String>(),
);
}

final Map<String, BannedPubkeyInfo> stillBanned;
final Map<String, BannedPubkeyInfo> unbanned;
final List<String> wereNotBanned;

JsonMap toJson() => {
'still_banned': stillBanned.map((k, v) => MapEntry(k, v.toJson())),
'unbanned': unbanned.map((k, v) => MapEntry(k, v.toJson())),
'were_not_banned': wereNotBanned,
};

@override
List<Object?> get props => [stillBanned, unbanned, wereNotBanned];
}

class BannedPubkeyInfo extends Equatable {
const BannedPubkeyInfo({required this.type, required this.reason});

factory BannedPubkeyInfo.fromJson(JsonMap json) => BannedPubkeyInfo(
type: json.value<String>('type'),
reason: json.value<String>('reason'),
);

final String type;
final String reason;

JsonMap toJson() => {'type': type, 'reason': reason};

@override
List<Object?> get props => [type, reason];
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class WalletMethods extends BaseRpcMethodNamespace {

Future<GetPublicKeyHashResponse> getPublicKeyHash([String? rpcPass]) =>
execute(GetPublicKeyHashRequest(rpcPass: rpcPass));

Future<UnbanPubkeysResponse> unbanPubkeys({
required UnbanBy unbanBy,
String? rpcPass,
}) => execute(UnbanPubkeysRequest(rpcPass: rpcPass ?? '', unbanBy: unbanBy));
}

/// KDF v2 Utility Methods not specific to any larger feature
Expand Down
25 changes: 25 additions & 0 deletions packages/komodo_defi_sdk/example/lib/screens/asset_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class _AssetHeaderState extends State<AssetHeader> {

String? _signedMessage;
bool _isSigningMessage = false;
bool _isUnbanning = false;
KdfUser? _currentUser;

Future<void> _loadCurrentUser() async {
Expand Down Expand Up @@ -220,6 +221,24 @@ class _AssetHeaderState extends State<AssetHeader> {
);
}

Future<void> _unbanPubkeys() async {
setState(() => _isUnbanning = true);
try {
final result = await context.read<KomodoDefiSdk>().pubkeys.unbanPubkeys(
const UnbanBy.all(),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Unbanned ${result.unbanned.length} pubkeys')),
);
} catch (e) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $e')));
} finally {
if (mounted) setState(() => _isUnbanning = false);
}
}

Widget _buildBalanceOverview(BuildContext context) {
return Card(
child: Padding(
Expand Down Expand Up @@ -364,6 +383,12 @@ class _AssetHeaderState extends State<AssetHeader> {
icon: const Icon(Icons.qr_code),
label: const Text('Receive'),
),
FilledButton.tonalIcon(
onPressed: _isUnbanning ? null : _unbanPubkeys,
icon: const Icon(Icons.lock_open),
label:
_isUnbanning ? const Text('Unbanning...') : const Text('Unban'),
),

Tooltip(
message:
Expand Down
7 changes: 7 additions & 0 deletions packages/komodo_defi_sdk/lib/src/pubkeys/pubkey_manager.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:komodo_defi_local_auth/komodo_defi_local_auth.dart';
import 'package:komodo_defi_sdk/src/_internal_exports.dart';
import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart';
import 'package:komodo_defi_types/komodo_defi_type_utils.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';

Expand Down Expand Up @@ -43,6 +44,12 @@ class PubkeyManager {
yield* strategy.getNewAddressStream(asset.id, _client);
}

/// Unban pubkeys according to [unbanBy] criteria
Future<UnbanPubkeysResult> unbanPubkeys(UnbanBy unbanBy) async {
final response = await _client.rpc.wallet.unbanPubkeys(unbanBy: unbanBy);
return response.result;
}

Future<PubkeyStrategy> _resolvePubkeyStrategy(Asset asset) async {
final currentUser = await _auth.currentUser;
if (currentUser == null) {
Expand Down
2 changes: 1 addition & 1 deletion packages/komodo_defi_types/lib/src/exported_rpc_types.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'
show AddressFormat, BalanceInfo;
show AddressFormat, BalanceInfo, UnbanBy, UnbanPubkeysResult, BannedPubkeyInfo;
Loading