https://github.com/anasfik/nostr_relay_management
Dart/Flutter support for NIP-86 (Relay Management API) with better developer experience.
https://github.com/anasfik/nostr_relay_management
86 auth client dart flutter nip nostr
Last synced: 25 days ago
JSON representation
Dart/Flutter support for NIP-86 (Relay Management API) with better developer experience.
- Host: GitHub
- URL: https://github.com/anasfik/nostr_relay_management
- Owner: anasfik
- License: mit
- Created: 2025-09-29T21:01:32.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-10-06T18:33:03.000Z (8 months ago)
- Last Synced: 2025-10-06T19:38:23.826Z (8 months ago)
- Topics: 86, auth, client, dart, flutter, nip, nostr
- Language: Dart
- Homepage: https://pub.dev/packages/nostr_relay_management_api
- Size: 24.4 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-nostr - nostr_relay_management - Dart/Flutter support for NIP-86 (Relay Management) with better developer experience. (Libraries / Client reviews and/or comparisons)
README
# ๐ Nostr Relay Management API for Dart/Flutter
[](https://pub.dev/packages/nostr_relay_management_api)
[](https://opensource.org/licenses/MIT)
A comprehensive Dart/Flutter package that makes **NIP-86 Relay Management** simple and easy! This package abstracts away the complexity of [NIP-98 HTTP Authentication](https://github.com/nostr-protocol/nips/blob/master/98.md) and provides a clean, type-safe API for managing Nostr relays.
## โจ What is NIP-86?
[NIP-86](https://github.com/nostr-protocol/nips/blob/master/86.md) defines a standardized API for managing Nostr relays. It allows you to:
- ๐ซ **Ban/Allow** users and events
- ๐ **Monitor** relay statistics and moderation queues
- โ๏ธ **Configure** relay settings (name, description, icon)
- ๐ **Manage** admin permissions
- ๐ **Block/Unblock** IP addresses
- ๐ **Control** event kinds (allow/disallow specific types)
## ๐ฏ Why Use This Package?
- โ
**Complete NIP-86 Coverage** - All 23+ management methods supported
- ๐ **Secure Authentication** - Handles NIP-98 auth automatically
- ๐จ **Type-Safe** - Full Dart type safety with proper models
- ๐ **Easy to Use** - Simple, intuitive API design
- ๐งช **Well Tested** - Comprehensive example with real relay testing
- ๐ฑ **Flutter Ready** - Works seamlessly in Flutter apps
## ๐ฆ Installation
Add this to your `pubspec.yaml`:
```yaml
dependencies:
nostr_relay_management_api: ^latest_version
```
Then run:
```bash
flutter pub get
# or
dart pub get
```
## ๐ Quick Start
```dart
import 'package:nostr_relay_management_api/nostr_relay_management_api.dart';
void main() async {
// Initialize the relay management service
final relay = NostrRelayManagement(
hexPrivateKey: "your_private_key_here", // Your Nostr private key
url: "https://your-relay.com", // Relay URL that supports NIP-86
);
// Get supported methods
final methods = await relay.methods.supportedmethods();
print('Available methods: $methods');
// List banned users
final bannedUsers = await relay.methods.listbannedpubkeys();
print('Banned users: $bannedUsers');
}
```
## ๐ Complete API Reference
### ๐ **Discovery & Information**
#### Get Supported Methods
```dart
final methods = await relay.methods.supportedmethods();
// Returns: List of all available management methods
```
#### Get Relay Statistics
```dart
final stats = await relay.methods.stats();
// Returns: Map with relay statistics and metrics
```
### ๐ฅ **User Management**
#### Ban a User
```dart
final success = await relay.methods.banpubkey(
pubkey: "npub1...",
reason: "Spam behavior"
);
```
#### Allow a User
```dart
final success = await relay.methods.allowpubkey(
pubkey: "npub1...",
reason: "Appealed successfully"
);
```
#### List Banned Users
```dart
final bannedUsers = await relay.methods.listbannedpubkeys();
bannedUsers?.forEach((user) {
print('Banned: ${user.pubkey} - ${user.reason}');
});
```
#### List Allowed Users
```dart
final allowedUsers = await relay.methods.listallowedpubkeys();
allowedUsers?.forEach((user) {
print('Whitelisted: ${user.pubkey} - ${user.reason}');
});
```
### ๐ **Event Management**
#### Ban an Event
```dart
final success = await relay.methods.banevent(
eventId: "event_id_here",
reason: "Inappropriate content"
);
```
#### Allow an Event
```dart
final success = await relay.methods.allowevent(
eventId: "event_id_here",
reason: "Content reviewed and approved"
);
```
#### List Banned Events
```dart
final bannedEvents = await relay.methods.listbannedevents();
bannedEvents?.forEach((event) {
print('Banned Event: ${event.id} - ${event.reason}');
});
```
#### List Allowed Events
```dart
final allowedEvents = await relay.methods.listallowedevents();
allowedEvents?.forEach((event) {
print('Whitelisted Event: ${event.id} - ${event.reason}');
});
```
#### Events Needing Moderation
```dart
final pendingEvents = await relay.methods.listeventsneedingmoderation();
pendingEvents?.forEach((event) {
print('Needs Review: ${event.id} - ${event.reason}');
});
```
### ๐๏ธ **Kind Management**
#### Allow Event Kind
```dart
final success = await relay.methods.allowkind(kind: 1); // Text notes
```
#### Disallow Event Kind
```dart
final success = await relay.methods.disallowkind(kind: 4); // Encrypted DMs
```
#### List Allowed Kinds
```dart
final allowedKinds = await relay.methods.listallowedkinds();
print('Allowed kinds: $allowedKinds'); // [0, 1, 3, ...]
```
#### List Disallowed Kinds
```dart
final disallowedKinds = await relay.methods.listdisallowedkinds();
print('Disallowed kinds: $disallowedKinds'); // [4, 5, 6, ...]
```
### ๐ **IP Management**
#### Block IP Address
```dart
final success = await relay.methods.blockip(
ip: "192.168.1.100",
reason: "DoS attack detected"
);
```
#### Unblock IP Address
```dart
final success = await relay.methods.unblockip(ip: "192.168.1.100");
```
#### List Blocked IPs
```dart
final blockedIPs = await relay.methods.listblockedips();
blockedIPs?.forEach((ip) {
print('Blocked IP: ${ip.ip} - ${ip.reason}');
});
```
### โ๏ธ **Relay Configuration**
#### Change Relay Name
```dart
final success = await relay.methods.changerelayname(
newName: "My Awesome Relay"
);
```
#### Change Relay Description
```dart
final success = await relay.methods.changerelaydescription(
newDescription: "A fast and reliable Nostr relay"
);
```
#### Change Relay Icon
```dart
final success = await relay.methods.changerelayicon(
newIconUrl: "https://example.com/relay-icon.png"
);
```
### ๐ **Admin Management**
#### Grant Admin Permissions
```dart
final success = await relay.methods.grantadmin(
pubkey: "npub1...",
methods: ["banpubkey", "allowpubkey", "banevent"]
);
```
#### Revoke Admin Permissions
```dart
final success = await relay.methods.revokeadmin(
pubkey: "npub1...",
methods: ["banpubkey", "allowpubkey"]
);
```
### ๐ง **Custom Methods**
For relays with custom methods not covered by NIP-86:
```dart
// Example: Custom backup method
final backupResult = await relay.methods.customMethod(
methodName: "backupdatabaseInternally",
params: ["full", "compress"],
adapter: (result) {
final data = result as Map;
return BackupInfo(
backedUpEvents: data['events'] as int,
backupLocation: data['location'] as String,
);
},
);
```
## ๐งช Testing & Examples
Check out the comprehensive example in `example/nostr_relay_management_api_example.dart` that demonstrates all 17 categories of NIP-86 functionality:
```bash
# Run the example (make sure you have a NIP-86 compatible relay running)
cd example
dart run nostr_relay_management_api_example.dart
```
## ๐ Authentication
This package uses **NIP-98 HTTP Authentication** automatically. You just need to provide your Nostr private key, and the package handles:
- โ
Creating proper authentication headers
- โ
Signing requests with your private key
- โ
Managing authentication tokens
- โ
Error handling for auth failures
## ๐ ๏ธ Error Handling
All methods return nullable types and handle errors gracefully:
```dart
final result = await relay.methods.banpubkey(
pubkey: "invalid_pubkey",
reason: "test"
);
if (result == null) {
print('Operation failed - check logs for details');
} else {
print('Success: $result');
}
```
## ๐ค Contributing
We welcome contributions! Here's how you can help:
- ๐ **Report bugs** - Open an issue with details
- ๐ก **Suggest features** - Propose new functionality
- ๐ง **Add methods** - Implement new NIP-86 methods as they're added
- ๐ **Improve docs** - Help make the documentation better
- ๐งช **Add tests** - Increase test coverage
## ๐ License
This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
## ๐ Links
- ๐ [NIP-86 Specification](https://github.com/nostr-protocol/nips/blob/master/86.md)
- ๐ [NIP-98 HTTP Auth](https://github.com/nostr-protocol/nips/blob/master/98.md)
- ๐ฆ [Pub.dev Package](https://pub.dev/packages/nostr_relay_management_api)
- ๐ [GitHub Repository](https://github.com/anasfik/nostr_relay_management)
---
**Made with โค๏ธ for the Nostr community**