mirror of
https://github.com/haorendashu/nowser.git
synced 2025-12-17 09:54:19 +01:00
remote add nostrconnect url login
This commit is contained in:
83
lib/data/nostrconnect_remote_signing_info.dart
Normal file
83
lib/data/nostrconnect_remote_signing_info.dart
Normal file
@@ -0,0 +1,83 @@
|
||||
import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/data/remote_signing_info.dart';
|
||||
|
||||
class NostrconnectRemoteSigningInfo extends RemoteSigningInfo {
|
||||
String? perms;
|
||||
|
||||
String? name;
|
||||
|
||||
String? url;
|
||||
|
||||
String? image;
|
||||
|
||||
NostrconnectRemoteSigningInfo({
|
||||
super.id,
|
||||
super.appId,
|
||||
super.localPubkey,
|
||||
super.remotePubkey,
|
||||
super.remoteSignerKey,
|
||||
super.relays,
|
||||
super.secret,
|
||||
super.createdAt,
|
||||
super.updatedAt,
|
||||
this.perms,
|
||||
this.name,
|
||||
this.url,
|
||||
this.image,
|
||||
});
|
||||
|
||||
NostrconnectRemoteSigningInfo.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
appId = json['app_id'];
|
||||
localPubkey = json['local_pubkey'];
|
||||
remotePubkey = json['remote_pubkey'];
|
||||
remoteSignerKey = json['remote_signer_key'];
|
||||
relays = json['relays'];
|
||||
secret = json['secret'];
|
||||
createdAt = json['created_at'];
|
||||
updatedAt = json['updated_at'];
|
||||
perms = json['perms'];
|
||||
name = json['name'];
|
||||
url = json['url'];
|
||||
image = json['image'];
|
||||
}
|
||||
|
||||
// don't implement toJson method and when saving data it only save the super.toJson data.
|
||||
// @override
|
||||
// Map<String, dynamic> toJson() {
|
||||
// final data = super.toJson();
|
||||
// data['perms'] = perms;
|
||||
// data['name'] = name;
|
||||
// data['url'] = url;
|
||||
// data['image'] = image;
|
||||
// return data;
|
||||
// }
|
||||
|
||||
static NostrconnectRemoteSigningInfo? parseNostrConnectUrl(
|
||||
String nostrconnectUrlText) {
|
||||
var uri = Uri.parse(nostrconnectUrlText);
|
||||
var parsList = uri.queryParametersAll;
|
||||
var pars = uri.queryParameters;
|
||||
var localPubkey = uri.host;
|
||||
|
||||
var relays = parsList['relay'];
|
||||
var secret = pars['secret'];
|
||||
var perms = pars['perms'];
|
||||
var name = pars['name'];
|
||||
var url = pars['url'];
|
||||
var image = pars['image'];
|
||||
if (relays == null || relays.isEmpty || StringUtil.isBlank(secret)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NostrconnectRemoteSigningInfo(
|
||||
localPubkey: localPubkey,
|
||||
relays: relays.join(","),
|
||||
secret: secret,
|
||||
perms: perms,
|
||||
name: name,
|
||||
url: url,
|
||||
image: image,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -45,20 +45,4 @@ class RemoteSigningInfo {
|
||||
data['updated_at'] = this.updatedAt;
|
||||
return data;
|
||||
}
|
||||
|
||||
static RemoteSigningInfo? parseNostrConnectUrl(String nostrconnectUrlText) {
|
||||
var uri = Uri.parse(nostrconnectUrlText);
|
||||
var pars = uri.queryParametersAll;
|
||||
var localPubkey = uri.host;
|
||||
|
||||
var relays = pars["relay"];
|
||||
if (relays == null || relays.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return RemoteSigningInfo(
|
||||
localPubkey: localPubkey,
|
||||
relays: relays.join(","),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:nostr_sdk/client_utils/keys.dart';
|
||||
@@ -9,6 +10,7 @@ import 'package:nostr_sdk/event_kind.dart';
|
||||
import 'package:nostr_sdk/filter.dart';
|
||||
import 'package:nostr_sdk/nip46/nostr_remote_request.dart';
|
||||
import 'package:nostr_sdk/nip46/nostr_remote_response.dart';
|
||||
import 'package:nostr_sdk/relay/client_connected.dart';
|
||||
import 'package:nostr_sdk/relay/relay.dart';
|
||||
import 'package:nostr_sdk/relay/relay_isolate.dart';
|
||||
import 'package:nostr_sdk/relay/relay_status.dart';
|
||||
@@ -19,6 +21,7 @@ import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/const/app_type.dart';
|
||||
import 'package:nowser/const/auth_type.dart';
|
||||
import 'package:nowser/data/app.dart';
|
||||
import 'package:nowser/data/nostrconnect_remote_signing_info.dart';
|
||||
import 'package:nowser/provider/permission_check_mixin.dart';
|
||||
import 'package:relay_sdk/network/memory/mem_relay_client.dart';
|
||||
|
||||
@@ -77,7 +80,7 @@ class RemoteSigningProvider extends ChangeNotifier with PermissionCheckMixin {
|
||||
return str!;
|
||||
}
|
||||
|
||||
Future<void> addRemoteApp(App remoteApp, String encryptKey) async {
|
||||
Future<List<Relay>?> addRemoteApp(App remoteApp, String encryptKey) async {
|
||||
var remoteSigningInfo =
|
||||
await RemoteSigningInfoDB.getByAppId(remoteApp.id!, encryptKey);
|
||||
if (remoteSigningInfo != null &&
|
||||
@@ -91,6 +94,8 @@ class RemoteSigningProvider extends ChangeNotifier with PermissionCheckMixin {
|
||||
remoteSigningInfoMap[remoteSignerPubkey] = remoteSigningInfo;
|
||||
appMap[remoteSignerPubkey] = remoteApp;
|
||||
relayMap[remoteSignerPubkey] = relays;
|
||||
|
||||
return relays;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +318,12 @@ class RemoteSigningProvider extends ChangeNotifier with PermissionCheckMixin {
|
||||
|
||||
if (event != null) {
|
||||
for (var relay in relays) {
|
||||
relay.send(["EVENT", event.toJson()]);
|
||||
if (relay.relayStatus.connected == ClientConneccted.CONNECTED) {
|
||||
relay.send(["EVENT", event.toJson()]);
|
||||
} else {
|
||||
relay.pendingAuthedMessages.add(["EVENT", event.toJson()]);
|
||||
relay.pendingMessages.add(["EVENT", event.toJson()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,11 +410,49 @@ class RemoteSigningProvider extends ChangeNotifier with PermissionCheckMixin {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addNostrconnectRemoteSigningInfo(
|
||||
NostrconnectRemoteSigningInfo remoteSigningInfo) async {
|
||||
NostrSigner signerSigner =
|
||||
LocalNostrSigner(remoteSigningInfo.remoteSignerKey!);
|
||||
var remoteSignerPubkey = getPublicKey(remoteSigningInfo.remoteSignerKey!);
|
||||
var appType = AppType.REMOTE;
|
||||
var code = remoteSignerPubkey;
|
||||
|
||||
App? app = await getApp(appType, code);
|
||||
app.name = remoteSigningInfo.name;
|
||||
if (StringUtil.isBlank(app.name)) {
|
||||
app.name = remoteSigningInfo.url;
|
||||
}
|
||||
app.pubkey = remoteSigningInfo.remotePubkey;
|
||||
app.image = remoteSigningInfo.image;
|
||||
await AuthAppConnectDialog.show(context!, app);
|
||||
app = appProvider.getApp(appType, code);
|
||||
if (app == null) {
|
||||
BotToast.showText(text: "Remote App connect fail.");
|
||||
return false;
|
||||
}
|
||||
|
||||
remoteSigningInfo.appId = app.id;
|
||||
remoteSigningInfo.updatedAt = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
|
||||
await RemoteSigningInfoDB.insert(remoteSigningInfo, encryptKey);
|
||||
|
||||
var relays = await addRemoteApp(app, encryptKey);
|
||||
if (relays != null) {
|
||||
var response = NostrRemoteResponse(
|
||||
StringUtil.rndNameStr(12), remoteSigningInfo.secret!);
|
||||
await sendResponse(relays, response, signerSigner,
|
||||
remoteSigningInfo.localPubkey!, remoteSignerPubkey);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
List<RemoteSigningInfo> _penddingRemoteApps = [];
|
||||
|
||||
List<RemoteSigningInfo> get penddingRemoteApps => _penddingRemoteApps;
|
||||
|
||||
Future<void> saveRemoteSigningInfo(
|
||||
Future<void> saveBunkerRemoteSigningInfo(
|
||||
RemoteSigningInfo remoteSigningInfo) async {
|
||||
await RemoteSigningInfoDB.insert(remoteSigningInfo, encryptKey);
|
||||
await reloadPenddingRemoteApps();
|
||||
|
||||
@@ -4,11 +4,13 @@ import 'package:flutter/services.dart';
|
||||
import 'package:nostr_sdk/client_utils/keys.dart';
|
||||
import 'package:nostr_sdk/nip19/nip19.dart';
|
||||
import 'package:nostr_sdk/nip46/nostr_remote_signer_info.dart';
|
||||
import 'package:nostr_sdk/utils/platform_util.dart';
|
||||
import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/component/cust_state.dart';
|
||||
import 'package:nowser/component/qrscanner.dart';
|
||||
import 'package:nowser/component/simple_qrcode_dialog.dart';
|
||||
import 'package:nowser/component/user/user_name_component.dart';
|
||||
import 'package:nowser/data/nostrconnect_remote_signing_info.dart';
|
||||
import 'package:nowser/data/remote_signing_info.dart';
|
||||
import 'package:nowser/data/remote_signing_info_db.dart';
|
||||
import 'package:nowser/main.dart';
|
||||
@@ -205,14 +207,9 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
|
||||
unselectedLabelColor: textColor,
|
||||
indicatorColor: mainColor,
|
||||
tabs: [
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
"${s.Connect_by}\nnostrconnect:// url",
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
onTap: () {
|
||||
BotToast.showText(text: s.Comming_soon);
|
||||
},
|
||||
Text(
|
||||
"${s.Connect_by}\nnostrconnect:// url",
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
Text(
|
||||
"${s.Connect_by}\nbunker:// url",
|
||||
@@ -246,12 +243,14 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
scanNostrConnectQRCode();
|
||||
},
|
||||
icon: const Icon(Icons.qr_code_scanner),
|
||||
),
|
||||
PlatformUtil.isAndroid() || PlatformUtil.isIOS()
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
scanNostrConnectQRCode();
|
||||
},
|
||||
icon: const Icon(Icons.qr_code_scanner),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -259,9 +258,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
|
||||
margin: const EdgeInsets.only(top: Base.BASE_PADDING),
|
||||
width: double.infinity,
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
BotToast.showText(text: s.Comming_soon);
|
||||
},
|
||||
onPressed: confirmNostrConnect,
|
||||
child: Text(s.Confirm),
|
||||
),
|
||||
),
|
||||
@@ -347,19 +344,27 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
|
||||
|
||||
String remoteSignerKey = generatePrivateKey();
|
||||
|
||||
void confirmNostrConnect() {
|
||||
var remoteSigningInfo =
|
||||
RemoteSigningInfo.parseNostrConnectUrl(nostrconnectConn.text);
|
||||
Future<void> confirmNostrConnect() async {
|
||||
var remoteSigningInfo = NostrconnectRemoteSigningInfo.parseNostrConnectUrl(
|
||||
nostrconnectConn.text.trim());
|
||||
if (remoteSigningInfo == null) {
|
||||
// TODO
|
||||
BotToast.showText(text: 'Invalid nostrconnect url');
|
||||
return;
|
||||
}
|
||||
|
||||
remoteSigningInfo.remotePubkey = pubkey;
|
||||
remoteSigningInfo.remoteSignerKey = remoteSignerKey;
|
||||
remoteSigningInfo.createdAt = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
remoteSigningInfo.updatedAt = remoteSigningInfo.createdAt;
|
||||
|
||||
// TODO
|
||||
var result = await remoteSigningProvider
|
||||
.addNostrconnectRemoteSigningInfo(remoteSigningInfo);
|
||||
if (result) {
|
||||
BotToast.showText(text: 'Add remote app success');
|
||||
RouterUtil.back(context);
|
||||
} else {
|
||||
BotToast.showText(text: 'Add remote app fail');
|
||||
}
|
||||
}
|
||||
|
||||
TextEditingController relayAddrController = TextEditingController();
|
||||
@@ -412,7 +417,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
|
||||
);
|
||||
remoteSigningInfo.updatedAt = remoteSigningInfo.createdAt;
|
||||
|
||||
remoteSigningProvider.saveRemoteSigningInfo(remoteSigningInfo);
|
||||
remoteSigningProvider.saveBunkerRemoteSigningInfo(remoteSigningInfo);
|
||||
RouterUtil.back(context);
|
||||
}
|
||||
|
||||
|
||||
Submodule packages/nostr_sdk updated: af5304d08a...a900fb91d4
Reference in New Issue
Block a user