Skip to content
Open
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ _Get Public Key_

Get the current user public key (npub). This request also allows to send permissions so the user can approve them forever. See the [Amber Docs](https://github.com/greenart7c3/Amber/blob/master/README.md) for the list of available permissions.

The ```Get Public Key``` function, like a connect function, can set permissions and get the package name of android signer. You should call it first when you use android signer.

```
final amber = Amberflutter();

Expand All @@ -45,6 +47,7 @@ amber.getPublicKey(
),
],
).then((value) {
print("package: ${value['package']}");
print("npub: ${value['signature']}");
});
```
Expand All @@ -67,6 +70,7 @@ final eventJson = jsonEncode({
amber.signEvent(
currentUser: "<your_npub_here>",
eventJson: eventJson,
package: "<android_signer's_package_name(optional)>",
).then((value) {
print("signed event: ${value['event']}");
});
Expand All @@ -81,6 +85,7 @@ amber.nip04Encrypt(
plaintext: "Hello from Amber Flutter, Nip 04!",
currentUser: "<your_npub_here>",
pubKey: "<hex_pubkey_to_encrypt>",
package: "<android_signer's_package_name(optional)>",
).then((value) {
print("ciphertext: ${value['signature']}")
});
Expand All @@ -93,6 +98,7 @@ amber.nip44Encrypt(
plaintext: "Hello from Amber Flutter, Nip 44!",
currentUser: "<your_npub_here>",
pubKey: "<hex_pubkey_to_encrypt>",
package: "<android_signer's_package_name(optional)>",
).then((value) {
print("ciphertext: ${value['signature']}")
});
Expand All @@ -107,6 +113,7 @@ amber.nip04Decrypt(
ciphertext: "<message_encrypted_with_nip04_here>",
currentUser: "<your_npub_here>",
pubKey: "<hex_pubkey_to_decrypt>",
package: "<android_signer's_package_name(optional)>",
).then((value) {
print("plaintext: ${value['signature']}")
});
Expand All @@ -121,6 +128,7 @@ amber.nip44Decrypt(
ciphertext: "<message_encrypted_with_nip44_here>",
currentUser: "<your_npub_here>",
pubKey: "<hex_pubkey_to_decrypt>",
package: "<android_signer's_package_name(optional)>",
).then((value) {
print("plaintext: ${value['signature']}")
});
Expand Down
6 changes: 5 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sebdeveloper6952.amberflutter.amberflutter">
<queries>
<package android:name="com.greenart7c3.nostrsigner"/>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="nostrsigner" />
</intent>
</queries>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
return context.packageManager.getInstalledApplications(0).find { info -> info.packageName == target } != null
}

fun isAndroidSignerInstalled(context: Context): Boolean {
val intent =
Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("nostrsigner:")
}
val infos = context.packageManager.queryIntentActivities(intent, 0)
return infos.size > 0
}

override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == nostrsignerUri) {
_result = MethodResultWrapper(result)
Expand All @@ -61,8 +71,18 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
val id = paramsMap[intentExtraKeyId] as? String ?: ""
val uriData = paramsMap[intentExtraKeyUriData] as? String ?: ""
val permissions = paramsMap[intentExtraKeyPermissions] as? String ?: ""
val packageName = (paramsMap[intentExtraKeyPackage] as? String)?.let { originalPackage ->
if (originalPackage.isNotEmpty()) {
originalPackage
} else if (requestType != "get_public_key") {
amberPackageName
} else {
""
}
} ?: if (requestType != "get_public_key") amberPackageName else ""

val data = getDataFromContentResolver(
packageName,
requestType.uppercase(),
arrayOf(uriData, pubKey, currentUser),
_context.contentResolver,
Expand All @@ -78,7 +98,11 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
Uri.parse(
"$nostrsignerUri:$uriData"
)
)
).apply {
if (!packageName.isNullOrEmpty()) {
setPackage(packageName)
}
}

intent.putExtra(intentExtraKeyType, requestType)
intent.putExtra(intentExtraKeyCurrentUser, currentUser)
Expand All @@ -102,6 +126,9 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
var packageName: String? = paramsMap["packageName"] as? String ?: return
val isInstalled: Boolean = isPackageInstalled(_context, packageName!!)
result.success(isInstalled);
} else if (call.method == "isAndroidSignerInstalled") {
val isInstalled: Boolean = isAndroidSignerInstalled(_context)
result.success(isInstalled);
} else {
result.notImplemented()
}
Expand All @@ -123,6 +150,10 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
val event = intent.getStringExtra(intentExtraKeyEvent)
dataMap[intentExtraKeyEvent] = event
}
if (intent.hasExtra(intentExtraKeyPackage)) {
val packageName = intent.getStringExtra(intentExtraKeyPackage)
dataMap[intentExtraKeyPackage] = packageName
}

_result.success(dataMap)

Expand Down Expand Up @@ -159,13 +190,14 @@ class AmberflutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Plugi
Code taken from: https://github.com/0xchat-app/nostr-dart/blob/main/android/src/main/kotlin/com/oxchat/nostrcore/ChatcorePlugin.kt
*/
private fun getDataFromContentResolver(
packageName: String,
type: String,
uriData: Array<out String>,
resolver: ContentResolver,
): HashMap<String, String?>? {
try {
resolver.query(
Uri.parse("content://${amberPackageName}.$type"),
Uri.parse("content://${packageName}.$type"),
uriData,
null,
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ const val intentExtraKeyId = "id"
const val intentExtraKeyEvent = "event"
const val intentExtraKeyPubKey = "pubKey"
const val intentExtraKeyPermissions = "permissions"
const val intentExtraKeyUriData = "uri_data"
const val intentExtraKeyUriData = "uri_data"
const val intentExtraKeyPackage = "package"
17 changes: 17 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MyHomePage extends StatefulWidget {

class _MyHomePageState extends State<MyHomePage> {
final amber = Amberflutter();
String _package = '';
String _npub = '';
String _pubkeyHex = '';
String _text = '';
Expand All @@ -48,6 +49,16 @@ class _MyHomePageState extends State<MyHomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FilledButton(
onPressed: () {
amber.isAndroidSignerInstalled().then((value) {
setState(() {
_text = 'isAndroidSignerInstalled? $value';
});
});
},
child: const Text('IsAndroidSignerInstall ?'),
),
FilledButton(
onPressed: () {
amber.getPublicKey(
Expand All @@ -60,6 +71,7 @@ class _MyHomePageState extends State<MyHomePage> {
),
],
).then((value) {
_package = value['package'] ?? '';
_npub = value['signature'] ?? '';
_pubkeyHex = Nip19.decodePubkey(_npub);
setState(() {
Expand All @@ -86,6 +98,7 @@ class _MyHomePageState extends State<MyHomePage> {
.signEvent(
currentUser: _npub,
eventJson: eventJson,
package: _package,
)
.then((value) {
setState(() {
Expand All @@ -102,6 +115,7 @@ class _MyHomePageState extends State<MyHomePage> {
plaintext: "Hello from Amber Flutter, Nip 04!",
currentUser: _npub,
pubKey: _pubkeyHex,
package: _package,
)
.then((value) {
_cipherText = value['signature'] ?? '';
Expand All @@ -119,6 +133,7 @@ class _MyHomePageState extends State<MyHomePage> {
ciphertext: _cipherText,
currentUser: _npub,
pubKey: _pubkeyHex,
package: _package,
)
.then((value) {
setState(() {
Expand All @@ -135,6 +150,7 @@ class _MyHomePageState extends State<MyHomePage> {
plaintext: "Hello from Amber Flutter, Nip 44!",
currentUser: _npub,
pubKey: _pubkeyHex,
package: _package,
)
.then((value) {
_cipherText = value['signature'] ?? '';
Expand All @@ -152,6 +168,7 @@ class _MyHomePageState extends State<MyHomePage> {
ciphertext: _cipherText,
currentUser: _npub,
pubKey: _pubkeyHex,
package: _package,
)
.then((value) {
setState(() {
Expand Down
16 changes: 16 additions & 0 deletions lib/amberflutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ class Amberflutter {
return AmberflutterPlatform.instance.isAppInstalled();
}

Future<bool> isAndroidSignerInstalled() {
return AmberflutterPlatform.instance.isAndroidSignerInstalled();
}

Future<Map<dynamic, dynamic>> signEvent({
required String currentUser,
required String eventJson,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.signEvent(
currentUser,
eventJson,
id,
package: package ?? "",
);
}

Expand All @@ -33,12 +39,14 @@ class Amberflutter {
required String currentUser,
required String pubKey,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.nip04Encrypt(
plaintext,
currentUser,
pubKey,
id,
package: package ?? "",
);
}

Expand All @@ -47,12 +55,14 @@ class Amberflutter {
required String currentUser,
required String pubKey,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.nip04Decrypt(
ciphertext,
currentUser,
pubKey,
id,
package: package ?? "",
);
}

Expand All @@ -61,12 +71,14 @@ class Amberflutter {
required String currentUser,
required String pubKey,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.nip44Encrypt(
plaintext,
currentUser,
pubKey,
id,
package: package ?? "",
);
}

Expand All @@ -75,24 +87,28 @@ class Amberflutter {
required String currentUser,
required String pubKey,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.nip44Decrypt(
ciphertext,
currentUser,
pubKey,
id,
package: package ?? "",
);
}

Future<Map<dynamic, dynamic>> decryptZapEvent({
required String eventJson,
required String currentUser,
String? id,
String? package,
}) {
return AmberflutterPlatform.instance.decryptZapEvent(
eventJson,
currentUser,
id,
package: package ?? "",
);
}
}
Loading