mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
Comments and zaps fixes
This commit is contained in:
@@ -12,11 +12,5 @@ const kFranzapPubkey =
|
||||
/// Shareable identifier for the Nostr curation set
|
||||
const kNostrCurationSetShareableId = '30267:$kFranzapPubkey:nostr';
|
||||
|
||||
/// Anonymous private key for error reporting and anonymous operations
|
||||
/// This key is used when the user is not signed in
|
||||
const kAnonymousPrivateKey =
|
||||
'c86eda2daae768374526bc54903f388d9a866c00740ec8db418d7ef2dca77b5b';
|
||||
|
||||
/// Identifier for storing user bookmarks
|
||||
const kAppBookmarksIdentifier = 'zapstore-bookmarks';
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import 'package:zapstore/utils/extensions.dart';
|
||||
|
||||
/// Service for reporting errors via NIP-44 encrypted DMs to Zapstore team.
|
||||
///
|
||||
/// Uses [kAnonymousPrivateKey] for signing so error reports can be sent
|
||||
/// even when the user is not signed in.
|
||||
/// Generates an ephemeral signer per report so errors can be sent even when
|
||||
/// the user is not signed in.
|
||||
class ErrorReportingService {
|
||||
ErrorReportingService(this.ref);
|
||||
|
||||
@@ -31,8 +31,6 @@ class ErrorReportingService {
|
||||
Future<void> reportError(Object exception, StackTrace? stackTrace) async {
|
||||
// Don't report in debug mode
|
||||
if (kDebugMode) {
|
||||
debugPrint('Error (not reported in debug): $exception');
|
||||
debugPrint('$stackTrace');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,8 +48,8 @@ class ErrorReportingService {
|
||||
}
|
||||
|
||||
try {
|
||||
// Create anonymous signer for error reporting
|
||||
final signer = Bip340PrivateKeySigner(kAnonymousPrivateKey, ref);
|
||||
// Create ephemeral signer for error reporting
|
||||
final signer = Bip340PrivateKeySigner(Utils.generateRandomHex64(), ref);
|
||||
await signer.signIn(setAsActive: false, registerSigner: false);
|
||||
|
||||
// Format error report
|
||||
@@ -65,19 +63,15 @@ class ErrorReportingService {
|
||||
|
||||
// Sign and publish
|
||||
final signedDm = await dm.signWith(signer);
|
||||
await ref.read(storageNotifierProvider.notifier).publish(
|
||||
{signedDm},
|
||||
source: const RemoteSource(relays: 'social', stream: false),
|
||||
);
|
||||
await ref.read(storageNotifierProvider.notifier).publish({
|
||||
signedDm,
|
||||
}, source: const RemoteSource(relays: 'social', stream: false));
|
||||
|
||||
// Update rate limiting
|
||||
_reportedErrors[errorHash] = DateTime.now();
|
||||
_sessionReportCount++;
|
||||
|
||||
debugPrint('Error report sent successfully');
|
||||
} catch (e) {
|
||||
// Silently fail - we don't want error reporting to cause more errors
|
||||
debugPrint('Failed to send error report: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,4 +106,3 @@ class ErrorReportingService {
|
||||
final errorReportingServiceProvider = Provider<ErrorReportingService>(
|
||||
ErrorReportingService.new,
|
||||
);
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ class CommentsSection extends ConsumerWidget {
|
||||
context,
|
||||
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (comments.isNotEmpty) _CommentCountBadge(count: comments.length),
|
||||
if (comments.isNotEmpty)
|
||||
_CommentCountBadge(count: comments.length),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -80,7 +81,8 @@ class CommentsSection extends ConsumerWidget {
|
||||
// Comments list - only when there are comments
|
||||
if (comments.isNotEmpty) ...[
|
||||
const SizedBox(height: 16),
|
||||
...(comments.toList()..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
...(comments.toList()
|
||||
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
.map(
|
||||
(comment) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
@@ -154,8 +156,8 @@ class _CommentCard extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final author = comment.author.value;
|
||||
// Extract version from d tag (thread key)
|
||||
final version = comment.event.getFirstTagValue('d');
|
||||
// Extract version from v tag (per NIP-22 guidance)
|
||||
final version = comment.event.getFirstTagValue('v');
|
||||
|
||||
return Card(
|
||||
margin: EdgeInsets.zero,
|
||||
@@ -408,8 +410,8 @@ class _CommentComposer extends HookConsumerWidget {
|
||||
// No parentModel for root comments - only A/K/P tags, no e/k/p
|
||||
);
|
||||
|
||||
// Add d tag as thread key (version)
|
||||
comment.event.addTagValue('d', versionToComment);
|
||||
// Add v tag for version (per NIP-22 guidance, not d tag)
|
||||
comment.event.addTagValue('v', versionToComment);
|
||||
|
||||
final signedComment = await comment.signWith(signer);
|
||||
|
||||
|
||||
@@ -473,11 +473,11 @@ class ZapAmountDialog extends HookConsumerWidget {
|
||||
try {
|
||||
final navigator = Navigator.of(context);
|
||||
|
||||
// Prepare signer (anonymous if needed)
|
||||
// Prepare signer (ephemeral if needed)
|
||||
var signer = ref.read(Signer.activeSignerProvider);
|
||||
if (signer == null) {
|
||||
signer = Bip340PrivateKeySigner(
|
||||
kAnonymousPrivateKey,
|
||||
Utils.generateRandomHex64(),
|
||||
ref.ref,
|
||||
);
|
||||
await signer.signIn(registerSigner: false);
|
||||
@@ -489,6 +489,7 @@ class ZapAmountDialog extends HookConsumerWidget {
|
||||
// Build zap request
|
||||
final latestMetadata = app.latestFileMetadata;
|
||||
final author = app.author.value;
|
||||
|
||||
if (latestMetadata == null || author == null) {
|
||||
throw Exception(
|
||||
'App or author not ready. Please try again.',
|
||||
@@ -521,17 +522,24 @@ class ZapAmountDialog extends HookConsumerWidget {
|
||||
|
||||
// Fire payment in background - errors shown via ScaffoldMessenger
|
||||
// ignore: unawaited_futures
|
||||
_executeZapPayment(signedZapRequest, nwcString, ref.ref)
|
||||
.catchError((Object e, StackTrace st) {
|
||||
debugPrint('Zap payment failed: $e\n$st');
|
||||
messenger?.showSnackBar(
|
||||
_executeZapPayment(
|
||||
signedZapRequest,
|
||||
nwcString,
|
||||
ref.ref,
|
||||
).then(
|
||||
(_) {},
|
||||
onError: (Object e, StackTrace st) {
|
||||
if (messenger != null) {
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Zap failed: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
duration: const Duration(seconds: 5),
|
||||
),
|
||||
);
|
||||
return Future<PayInvoiceResult>.error(e, st);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
final invoice = await signedZapRequest.getInvoice();
|
||||
await Clipboard.setData(ClipboardData(text: invoice));
|
||||
@@ -586,11 +594,14 @@ Future<PayInvoiceResult> _executeZapPayment(
|
||||
) async {
|
||||
final lightningInvoice = await signedZapRequest.getInvoice();
|
||||
final command = PayInvoiceCommand(invoice: lightningInvoice);
|
||||
return await command.execute(
|
||||
|
||||
final result = await command.execute(
|
||||
connectionUri: nwcString,
|
||||
ref: ref,
|
||||
timeout: const Duration(seconds: 30),
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Dialog for entering a custom zap amount
|
||||
|
||||
Reference in New Issue
Block a user