nowser add nesigner support

This commit is contained in:
DASHU
2025-05-06 21:05:15 +08:00
parent 605a56bae7
commit 586e76df5c
21 changed files with 486 additions and 27 deletions

9
.gitmodules vendored
View File

@@ -4,3 +4,12 @@
[submodule "packages/relay_sdk"]
path = packages/relay_sdk
url = git@github.com:haorendashu/relay_sdk.git
[submodule "packages/flutter_nesigner_sdk"]
path = packages/flutter_nesigner_sdk
url = git@github.com:haorendashu/flutter_nesigner_sdk.git
[submodule "packages/nesigner_adapter"]
path = packages/nesigner_adapter
url = git@github.com:haorendashu/nesigner_adapter.git
[submodule "packages/libusb_ffi"]
path = packages/libusb_ffi
url = git@github.com:haorendashu/libusb_ffi.git

View File

@@ -0,0 +1,229 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nostr_sdk/nip19/nip19.dart';
import 'package:nesigner_adapter/nesigner_adapter.dart';
import 'package:nostr_sdk/utils/hash_util.dart';
import 'package:nostr_sdk/utils/platform_util.dart';
import 'package:nostr_sdk/utils/string_util.dart';
import '../../const/base.dart';
import '../../generated/l10n.dart';
import '../../main.dart';
import '../../util/router_util.dart';
import '../../util/table_mode_util.dart';
import '../../util/theme_util.dart';
class NesignerLoginDialog extends StatefulWidget {
NesignerLoginDialog();
static Future<String?> show(BuildContext context) async {
return await showDialog<String>(
context: context,
useRootNavigator: false,
builder: (_context) {
return NesignerLoginDialog();
},
);
}
@override
State<StatefulWidget> createState() {
return _NesignerLoginDialog();
}
}
class _NesignerLoginDialog extends State<NesignerLoginDialog> {
TextEditingController controller = TextEditingController();
TextEditingController controller1 = TextEditingController();
@override
void initState() {
super.initState();
}
bool obscureText = true;
bool obscureText1 = true;
bool bingKey = false;
late S s;
@override
Widget build(BuildContext context) {
s = S.of(context);
var themeData = Theme.of(context);
Color cardColor = themeData.cardColor;
var mainColor = themeData.primaryColor;
var textColor = themeData.textTheme.bodyMedium!.color;
List<Widget> list = [];
var suffixIcon = GestureDetector(
onTap: () {
setState(() {
obscureText = !obscureText;
});
},
child: Icon(obscureText ? Icons.visibility : Icons.visibility_off),
);
list.add(Container(
margin: EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING,
top: Base.BASE_PADDING * 2,
),
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: "Please input Pin",
fillColor: Colors.white,
suffixIcon: suffixIcon,
),
obscureText: obscureText,
),
));
if (bingKey) {
var suffixIcon1 = GestureDetector(
onTap: () {
setState(() {
obscureText1 = !obscureText1;
});
},
child: Icon(obscureText1 ? Icons.visibility : Icons.visibility_off),
);
list.add(Container(
margin: EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING,
top: Base.BASE_PADDING_HALF,
),
child: TextField(
controller: controller1,
decoration: InputDecoration(
hintText: "Please input private key",
fillColor: Colors.white,
suffixIcon: suffixIcon1,
),
obscureText: obscureText1,
),
));
}
list.add(Container(
margin: const EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING,
top: Base.BASE_PADDING,
),
width: double.infinity,
child: FilledButton(
onPressed: doLogin,
child: Text(bingKey ? "Bind and Login" : "Login")),
));
list.add(Container(
margin: EdgeInsets.only(bottom: Base.BASE_PADDING),
child: GestureDetector(
onTap: switchBingKey,
child: Text(
bingKey ? "Direct Login" : "Bind Private Key",
style: TextStyle(
color: mainColor,
decoration: TextDecoration.underline,
decorationColor: mainColor,
),
),
),
));
var main = Container(
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15)),
color: cardColor,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: list,
),
);
if (PlatformUtil.isPC() || TableModeUtil.isTableMode()) {
main = Container(
width: mediaDataCache.size.width / 2,
child: main,
);
}
return Scaffold(
backgroundColor: ThemeUtil.getDialogCoverColor(themeData),
body: FocusScope(
// autofocus: true,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
RouterUtil.back(context);
},
child: Container(
width: double.infinity,
height: double.infinity,
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
),
alignment: Alignment.center,
child: GestureDetector(
onTap: () {},
child: main,
),
),
),
),
);
}
void switchBingKey() {
setState(() {
bingKey = !bingKey;
});
}
void doLogin() {
var pin = controller.text;
var privateKey = controller1.text;
if (StringUtil.isBlank(pin)) {
BotToast.showText(text: s.Input_can_not_be_null);
return;
}
var aesKey = HashUtil.md5(pin);
if (bingKey) {
if (StringUtil.isBlank(privateKey)) {
BotToast.showText(text: s.Input_can_not_be_null);
return;
}
if (Nip19.isPrivateKey(privateKey)) {
privateKey = Nip19.decode(privateKey);
}
return RouterUtil.back(context, "$aesKey:$privateKey");
}
return RouterUtil.back(context, aesKey);
}
}

View File

@@ -1,12 +1,19 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nostr_sdk/client_utils/keys.dart';
import 'package:nostr_sdk/nip19/nip19.dart';
import 'package:nostr_sdk/utils/platform_util.dart';
import 'package:nostr_sdk/utils/string_util.dart';
import 'package:nowser/main.dart';
import 'package:nowser/util/router_util.dart';
import 'package:nesigner_adapter/nesigner_adapter.dart';
import 'package:hex/hex.dart';
import '../../const/base.dart';
import '../../generated/l10n.dart';
import '../cust_state.dart';
import 'nesigner_login_dialog.dart';
class UserLoginDialog extends StatefulWidget {
static Future<void> show(BuildContext context) async {
@@ -23,15 +30,39 @@ class UserLoginDialog extends StatefulWidget {
}
}
class _UserLoginDialog extends State<UserLoginDialog> {
class _UserLoginDialog extends CustState<UserLoginDialog> {
bool obscureText = true;
TextEditingController controller = TextEditingController();
late S s;
bool existNesigner = false;
@override
Widget build(BuildContext context) {
Future<void> onReady(BuildContext context) async {
if (PlatformUtil.isPC()) {
WidgetsBinding.instance.addPostFrameCallback((_) {
checkNesigner();
});
}
}
void checkNesigner() {
try {
var exist = NesignerUtil.checkNesignerExist();
if (exist != existNesigner) {
setState(() {
existNesigner = exist;
});
}
} catch (e) {
print("checkNesigner error $e");
}
}
@override
Widget doBuild(BuildContext context) {
var themeData = Theme.of(context);
s = S.of(context);
@@ -96,6 +127,24 @@ class _UserLoginDialog extends State<UserLoginDialog> {
),
));
if (existNesigner) {
list.add(Container(
child: Text(s.or),
));
list.add(GestureDetector(
onTap: loginWithNesigner,
child: Container(
child: Text(
s.Login_with_Nesigner,
style: TextStyle(
decoration: TextDecoration.underline,
),
),
),
));
}
var main = Column(
mainAxisSize: MainAxisSize.min,
children: list,
@@ -109,6 +158,56 @@ class _UserLoginDialog extends State<UserLoginDialog> {
);
}
Future<void> loginWithNesigner() async {
var nesignerInputStr = await NesignerLoginDialog.show(context);
if (nesignerInputStr == null) {
return;
}
var strs = nesignerInputStr.split(":");
var aesKey = strs[0];
var cancelFunc = BotToast.showLoading();
var nesigner = Nesigner(aesKey);
try {
if (!(await nesigner.start())) {
BotToast.showText(text: "Connect to nesigner fail.");
return;
}
if (strs.length > 1) {
var privateKey = strs[1];
var aesKeyBin = HEX.decode(aesKey);
var updateResult =
await nesigner.updateKey(Uint8List.fromList(aesKeyBin), privateKey);
print("update result $updateResult");
}
var pubkey = await nesigner.getPublicKey();
if (StringUtil.isBlank(pubkey)) {
try {
// login fail, should close the signer.
nesigner.close();
} catch (e) {
print("getPublicKey error $e");
}
BotToast.showText(text: s.Login_fail);
return;
}
var keyStr = Nesigner.genKey(aesKey, pubkey: pubkey);
keyProvider.addKey(keyStr);
} finally {
try {
nesigner.close();
} catch (e) {}
cancelFunc.call();
}
RouterUtil.back(context);
}
void confirm() {
var pk = controller.text;
try {

View File

@@ -100,6 +100,10 @@ class MessageLookup extends MessageLookupByLibrary {
"Light": MessageLookupByLibrary.simpleMessage("Light"),
"Local_Relay": MessageLookupByLibrary.simpleMessage("Local Relay"),
"Login": MessageLookupByLibrary.simpleMessage("Login"),
"Login_fail": MessageLookupByLibrary.simpleMessage("Login_fail"),
"Login_with_Nesigner": MessageLookupByLibrary.simpleMessage(
"Login with Nesigner",
),
"Name": MessageLookupByLibrary.simpleMessage("Name"),
"Open_backgroundly": MessageLookupByLibrary.simpleMessage(
"Open backgroundly",
@@ -145,6 +149,7 @@ class MessageLookup extends MessageLookupByLibrary {
"event": MessageLookupByLibrary.simpleMessage("event"),
"no_apps_now": MessageLookupByLibrary.simpleMessage("no apps now"),
"no_logs_now": MessageLookupByLibrary.simpleMessage("no logs now"),
"or": MessageLookupByLibrary.simpleMessage("or"),
"sign": MessageLookupByLibrary.simpleMessage("sign"),
"to": MessageLookupByLibrary.simpleMessage("to"),
};

View File

@@ -82,6 +82,10 @@ class MessageLookup extends MessageLookupByLibrary {
"Light": MessageLookupByLibrary.simpleMessage("浅色"),
"Local_Relay": MessageLookupByLibrary.simpleMessage("本地中继"),
"Login": MessageLookupByLibrary.simpleMessage("登录"),
"Login_fail": MessageLookupByLibrary.simpleMessage("登录失败"),
"Login_with_Nesigner": MessageLookupByLibrary.simpleMessage(
"使用 Nesigner 登录",
),
"Name": MessageLookupByLibrary.simpleMessage("名称"),
"Open_backgroundly": MessageLookupByLibrary.simpleMessage("后台打开"),
"Open_image_in_a_New_Tab": MessageLookupByLibrary.simpleMessage("新标签打开图片"),
@@ -115,6 +119,7 @@ class MessageLookup extends MessageLookupByLibrary {
"event": MessageLookupByLibrary.simpleMessage("事件"),
"no_apps_now": MessageLookupByLibrary.simpleMessage("目前没有应用"),
"no_logs_now": MessageLookupByLibrary.simpleMessage("目前没有日志"),
"or": MessageLookupByLibrary.simpleMessage("或者"),
"sign": MessageLookupByLibrary.simpleMessage("签名"),
"to": MessageLookupByLibrary.simpleMessage(""),
};

View File

@@ -704,6 +704,26 @@ class S {
args: [],
);
}
/// `or`
String get or {
return Intl.message('or', name: 'or', desc: '', args: []);
}
/// `Login with Nesigner`
String get Login_with_Nesigner {
return Intl.message(
'Login with Nesigner',
name: 'Login_with_Nesigner',
desc: '',
args: [],
);
}
/// `Login_fail`
String get Login_fail {
return Intl.message('Login_fail', name: 'Login_fail', desc: '', args: []);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -91,5 +91,8 @@
"Open_with_Incognito_Mode": "Open with Incognito Mode",
"Open_backgroundly": "Open backgroundly",
"Open_image_in_a_New_Tab": "Open image in a new tab",
"Download_image": "Download image"
"Download_image": "Download image",
"or": "or",
"Login_with_Nesigner": "Login with Nesigner",
"Login_fail": "Login_fail"
}

View File

@@ -91,5 +91,8 @@
"Open_with_Incognito_Mode": "无痕模式打开",
"Open_backgroundly": "后台打开",
"Open_image_in_a_New_Tab": "新标签打开图片",
"Download_image": "下载图片"
"Download_image": "下载图片",
"or": "或者",
"Login_with_Nesigner": "使用 Nesigner 登录",
"Login_fail": "登录失败"
}

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:nesigner_adapter/nesigner.dart';
import 'package:nostr_sdk/client_utils/keys.dart';
import 'package:nostr_sdk/signer/local_nostr_signer.dart';
import 'package:nostr_sdk/signer/nostr_signer.dart';
@@ -16,10 +17,20 @@ class KeyProvider extends ChangeNotifier {
Map<String, String> keysMap = {};
Map<String, Nesigner> _nesignerMap = {};
Future<void> init() async {
await reload();
}
String? _getPubkeyFromKeyStr(String keyStr) {
if (Nesigner.isNesignerKey(keyStr)) {
return Nesigner.getPubkeyFromKey(keyStr);
}
return getPublicKey(keyStr);
}
Future<void> reload() async {
keys.clear();
keysMap = {};
@@ -33,9 +44,11 @@ class KeyProvider extends ChangeNotifier {
for (var jsonObjItem in jsonObj) {
if (jsonObjItem is String) {
keys.add(jsonObjItem);
var pubkey = getPublicKey(jsonObjItem);
keysMap[pubkey] = jsonObjItem;
pubkeys.add(pubkey);
var pubkey = _getPubkeyFromKeyStr(jsonObjItem);
if (StringUtil.isNotBlank(pubkey)) {
keysMap[pubkey!] = jsonObjItem;
pubkeys.add(pubkey);
}
}
}
}
@@ -49,9 +62,11 @@ class KeyProvider extends ChangeNotifier {
pubkeys = [];
for (var key in keys) {
var pubkey = getPublicKey(key);
keysMap[pubkey] = key;
pubkeys.add(pubkey);
var pubkey = _getPubkeyFromKeyStr(key);
if (StringUtil.isNotBlank(pubkey)) {
keysMap[pubkey!] = key;
pubkeys.add(pubkey);
}
}
}
@@ -76,14 +91,18 @@ class KeyProvider extends ChangeNotifier {
await storage.write(key: KEY_NAME, value: jsonStr);
}
void addKey(String privateKey) {
if (exist(privateKey)) {
void addKey(String keyStr) {
if (exist(keyStr)) {
return;
}
keys.add(privateKey);
var pubkey = getPublicKey(privateKey);
keysMap[pubkey] = privateKey;
var pubkey = _getPubkeyFromKeyStr(keyStr);
if (StringUtil.isBlank(pubkey)) {
return;
}
keys.add(keyStr);
keysMap[pubkey!] = keyStr;
pubkeys.add(pubkey);
_saveKey();
@@ -92,11 +111,11 @@ class KeyProvider extends ChangeNotifier {
}
void removeKey(String pubkey) {
var privateKey = keysMap.remove(pubkey);
if (StringUtil.isNotBlank(privateKey)) {
keys.remove(privateKey);
pubkeys.remove(pubkey);
var keyStr = keysMap.remove(pubkey);
if (StringUtil.isNotBlank(keyStr)) {
keys.remove(keyStr);
}
pubkeys.remove(pubkey);
_saveKey();
_regenMemKeys();
@@ -107,10 +126,27 @@ class KeyProvider extends ChangeNotifier {
return keys.contains(privateKey);
}
NostrSigner? getSigner(String pubkey) {
Future<NostrSigner?> getSigner(String pubkey) async {
var nesigner = _nesignerMap[pubkey];
if (nesigner != null) {
return nesigner;
}
var key = keysMap[pubkey];
if (StringUtil.isNotBlank(key)) {
return LocalNostrSigner(key!);
if (Nesigner.isNesignerKey(key!)) {
var aesKey = Nesigner.getAesKeyFromKey(key);
if (StringUtil.isBlank(aesKey)) {
return null;
}
nesigner = Nesigner(aesKey, pubkey: pubkey);
await nesigner.start();
_nesignerMap[pubkey] = nesigner;
return nesigner;
}
return LocalNostrSigner(key);
}
return null;

View File

@@ -42,7 +42,7 @@ mixin PermissionCheckMixin {
return;
}
var signer = getSigner(app.pubkey!);
var signer = await getSigner(app.pubkey!);
if (signer == null) {
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(app);
@@ -124,7 +124,7 @@ mixin PermissionCheckMixin {
return App(appType: appType, code: code);
}
NostrSigner? getSigner(String pubkey) {
Future<NostrSigner?> getSigner(String pubkey) {
return keyProvider.getSigner(pubkey);
}
}

View File

@@ -311,7 +311,7 @@ class RemoteSigningProvider extends ChangeNotifier with PermissionCheckMixin {
return;
}
var remoteSigner = LocalNostrSigner(remoteSigningInfo.remoteSignerKey!);
var signer = keyProvider.getSigner(remoteSigningInfo.remotePubkey!);
var signer = await keyProvider.getSigner(remoteSigningInfo.remotePubkey!);
if (signer == null) {
return;
}

View File

@@ -6,14 +6,22 @@
#include "generated_plugin_registrant.h"
#include <flutter_nesigner_sdk/flutter_nesigner_sdk_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <nesigner_adapter/nesigner_adapter_plugin.h>
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <window_manager/window_manager_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_nesigner_sdk_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterNesignerSdkPlugin");
flutter_nesigner_sdk_plugin_register_with_registrar(flutter_nesigner_sdk_registrar);
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) nesigner_adapter_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "NesignerAdapterPlugin");
nesigner_adapter_plugin_register_with_registrar(nesigner_adapter_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);

View File

@@ -3,7 +3,9 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
flutter_nesigner_sdk
flutter_secure_storage_linux
nesigner_adapter
screen_retriever_linux
window_manager
)

View File

@@ -8,7 +8,9 @@ import Foundation
import cryptography_flutter
import device_info_plus
import flutter_inappwebview_macos
import flutter_nesigner_sdk
import flutter_secure_storage_macos
import nesigner_adapter
import path_provider_foundation
import screen_retriever_macos
import shared_preferences_foundation
@@ -19,7 +21,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
CryptographyFlutterPlugin.register(with: registry.registrar(forPlugin: "CryptographyFlutterPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterNesignerSdkPlugin.register(with: registry.registrar(forPlugin: "FlutterNesignerSdkPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
NesignerAdapterPlugin.register(with: registry.registrar(forPlugin: "NesignerAdapterPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

1
packages/libusb_ffi Submodule

Submodule packages/libusb_ffi added at d32db6a7a5

View File

@@ -157,10 +157,10 @@ packages:
dependency: transitive
description:
name: crypto
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
cryptography:
dependency: transitive
description:
@@ -380,6 +380,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_nesigner_sdk:
dependency: "direct main"
description:
path: "packages/flutter_nesigner_sdk"
relative: true
source: path
version: "0.0.1"
flutter_pinned_shortcut_plus:
dependency: "direct main"
description:
@@ -558,6 +565,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
libusb:
dependency: transitive
description:
path: "packages/libusb_ffi"
relative: true
source: path
version: "0.4.23-dev.1+1"
lints:
dependency: transitive
description:
@@ -598,6 +612,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
nesigner_adapter:
dependency: "direct main"
description:
path: "packages/nesigner_adapter"
relative: true
source: path
version: "0.0.1"
nested:
dependency: transitive
description:
@@ -1186,5 +1207,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.5.3 <4.0.0"
dart: ">=3.5.4 <4.0.0"
flutter: ">=3.27.0"

View File

@@ -37,6 +37,10 @@ dependencies:
path: packages/nostr_sdk
relay_sdk:
path: packages/relay_sdk
flutter_nesigner_sdk:
path: packages/flutter_nesigner_sdk
nesigner_adapter:
path: packages/nesigner_adapter
receive_intent: ^0.2.5
provider: ^6.1.2

View File

@@ -7,15 +7,21 @@
#include "generated_plugin_registrant.h"
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
#include <flutter_nesigner_sdk/flutter_nesigner_sdk_plugin_c_api.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <nesigner_adapter/nesigner_adapter_plugin_c_api.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <window_manager/window_manager_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
FlutterNesignerSdkPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterNesignerSdkPluginCApi"));
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
NesignerAdapterPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("NesignerAdapterPluginCApi"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
WindowManagerPluginRegisterWithRegistrar(

View File

@@ -4,7 +4,9 @@
list(APPEND FLUTTER_PLUGIN_LIST
flutter_inappwebview_windows
flutter_nesigner_sdk
flutter_secure_storage_windows
nesigner_adapter
screen_retriever_windows
window_manager
)