pakstr 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/android-template/app/build.gradle.kts +3 -0
  2. package/android-template/app/src/androidTest/java/com/pakstr/app/ExampleInstrumentedTest.kt +8 -3
  3. package/android-template/app/src/androidTest/java/com/pakstr/app/signer/NostrEventBuilderTest.kt +67 -0
  4. package/android-template/app/src/androidTest/java/com/pakstr/app/signer/NostrSignatureVerifierTest.kt +43 -0
  5. package/android-template/app/src/main/AndroidManifest.xml +15 -3
  6. package/android-template/app/src/main/assets/nip07.js +47 -7
  7. package/android-template/app/src/main/assets/www/index.html +220 -0
  8. package/android-template/app/src/main/java/com/pakstr/app/ApplicationClass.kt +2 -0
  9. package/android-template/app/src/main/java/com/pakstr/app/LocalServer.kt +35 -10
  10. package/android-template/app/src/main/java/com/pakstr/app/MainActivity.kt +102 -103
  11. package/android-template/app/src/main/java/com/pakstr/app/ShellRuntime.kt +5 -6
  12. package/android-template/app/src/main/java/com/pakstr/app/WebViewController.kt +65 -18
  13. package/android-template/app/src/main/java/com/pakstr/app/crypto/Bip340Verifier.kt +318 -0
  14. package/android-template/app/src/main/java/com/pakstr/app/crypto/CryptoInitializer.kt +34 -0
  15. package/android-template/app/src/main/java/com/pakstr/app/crypto/NostrEventHasher.kt +100 -0
  16. package/android-template/app/src/main/java/com/pakstr/app/crypto/NostrEventVerifier.kt +54 -0
  17. package/android-template/app/src/main/java/com/pakstr/app/crypto/NostrSignatureVerifier.kt +43 -0
  18. package/android-template/app/src/main/java/com/pakstr/app/crypto/Secp256k1.kt +63 -0
  19. package/android-template/app/src/main/java/com/pakstr/app/debug/AppDebugLogger.kt +21 -0
  20. package/android-template/app/src/main/java/com/pakstr/app/signer/AmberSigner.kt +142 -100
  21. package/android-template/app/src/main/java/com/pakstr/app/signer/NostrBridge.kt +115 -39
  22. package/android-template/app/src/main/java/com/pakstr/app/signer/NostrEventBuilder.kt +39 -0
  23. package/android-template/app/src/main/java/com/pakstr/app/signer/SignerManager.kt +83 -75
  24. package/android-template/app/src/main/java/com/pakstr/app/signer/SignerType.kt +0 -1
  25. package/android-template/app/src/main/java/com/pakstr/app/signer/exceptions/SignerUnavailableException.kt +5 -0
  26. package/android-template/app/src/main/res/values/strings.xml +1 -1
  27. package/package.json +1 -1
@@ -1,148 +1,156 @@
1
1
  package com.pakstr.app.signer
2
2
 
3
3
  import android.content.Context
4
+ import android.content.Intent
4
5
  import androidx.activity.result.ActivityResult
6
+ import androidx.activity.result.ActivityResultLauncher
5
7
  import com.pakstr.app.signer.interfaces.NostrSigner
6
-
8
+ import androidx.core.content.edit
9
+ import com.pakstr.app.signer.exceptions.SignerUnavailableException
10
+
11
+ /**
12
+ * Manages Nostr signer selection and lifecycle.
13
+ *
14
+ * Provides a single access point for obtaining the active NostrSigner
15
+ * implementation used by the application.
16
+ *
17
+ * Supported signer types:
18
+ *
19
+ * - Amber
20
+ * External Android signer app using the nostrsigner URI scheme.
21
+ *
22
+ * - Fake
23
+ * Test signer used for development and testing.
24
+ *
25
+ * - Bunker
26
+ * Reserved for NIP-46 remote signer implementation.
27
+ *
28
+ * The selected signer type is persisted using SharedPreferences.
29
+ * The signer instance is cached and recreated only when the user
30
+ * changes the active signer.
31
+ */
7
32
  class SignerManager(
8
- private val context: Context,
9
- private val launchAmber: (android.content.Intent) -> Unit
33
+ context: Context,
34
+ private val amberLauncher: ActivityResultLauncher<Intent>
10
35
  ) {
36
+ private val context =
37
+ context.applicationContext
11
38
 
12
39
  private val prefs =
13
- context.getSharedPreferences(
40
+ this.context.getSharedPreferences(
14
41
  "signer",
15
42
  Context.MODE_PRIVATE
16
43
  )
17
44
 
18
-
19
45
  private var activeSigner: NostrSigner? = null
20
46
 
21
-
22
47
  fun getActiveType(): SignerType? {
23
48
 
24
- return prefs.getString(
25
- "type",
26
- null
27
- )?.let {
49
+ val value =
50
+ prefs.getString(
51
+ "type",
52
+ SignerType.AMBER.name
53
+ )
28
54
 
29
- SignerType.valueOf(it)
55
+ return try {
56
+ SignerType.valueOf(value.toString())
30
57
 
58
+ } catch (_: IllegalArgumentException) {
59
+ SignerType.AMBER
31
60
  }
32
-
33
61
  }
34
62
 
63
+ fun setActiveType(
64
+ type: SignerType
65
+ ) {
35
66
 
36
- fun setActiveType(type: SignerType) {
37
-
38
- prefs.edit()
39
- .putString(
67
+ prefs.edit {
68
+ putString(
40
69
  "type",
41
70
  type.name
42
71
  )
43
- .apply()
44
-
72
+ }
45
73
 
46
74
  activeSigner = null
47
-
48
75
  }
49
76
 
50
-
77
+ /**
78
+ * Returns the currently selected signer implementation.
79
+ *
80
+ * Creates the signer lazily on first request and reuses the same
81
+ * instance until the signer type changes.
82
+ */
51
83
  fun getSigner(): NostrSigner {
52
84
 
53
-
54
- if (activeSigner != null) {
55
- return activeSigner!!
85
+ activeSigner?.let {
86
+ return it
56
87
  }
57
88
 
58
-
59
- activeSigner =
60
-
61
- when(getActiveType()) {
89
+ val signer =
90
+ when (getActiveType()) {
62
91
 
63
92
  SignerType.AMBER -> {
64
93
 
65
94
  if (!isAmberInstalled()) {
66
-
95
+ throw SignerUnavailableException(
96
+ "Amber signer application is not installed"
97
+ )
67
98
  }
68
99
 
69
100
  AmberSigner(
70
-
71
- context,
72
-
73
- launchAmber
74
-
101
+ amberLauncher
75
102
  )
76
-
77
103
  }
78
104
 
79
105
  SignerType.BUNKER -> {
106
+ throw SignerUnavailableException(
107
+ "Bunker signer is not implemented"
108
+ )
109
+ }
80
110
 
111
+ SignerType.FAKE -> {
81
112
  FakeSigner()
82
-
83
113
  }
84
114
 
85
115
  null -> {
86
116
 
87
117
  throw IllegalStateException(
88
-
89
118
  "No signer selected"
90
-
91
119
  )
92
-
93
120
  }
94
-
95
- else -> {
96
-
97
- FakeSigner()
98
-
99
- }
100
-
101
121
  }
102
122
 
123
+ activeSigner = signer
103
124
 
104
- return activeSigner!!
105
-
106
- }
107
-
108
-
109
-
110
- fun handleAmberResult(
111
- result: ActivityResult
112
- ) {
113
-
114
- val signer =
115
- activeSigner
116
-
117
-
118
- if (signer is AmberSigner) {
119
-
120
- signer.handleResult(result)
121
-
122
- }
123
-
125
+ return signer
124
126
  }
125
127
 
126
128
  private fun isAmberInstalled(): Boolean {
127
129
 
128
130
  return try {
129
131
 
130
- context.packageManager.getPackageInfo(
131
-
132
- "com.greenart7c3.nostrsigner",
133
-
134
- 0
135
-
136
- )
132
+ context.packageManager
133
+ .getPackageInfo(
134
+ "com.greenart7c3.nostrsigner",
135
+ 0
136
+ )
137
137
 
138
138
  true
139
139
 
140
- } catch (e: Exception) {
140
+ } catch (_: Exception) {
141
141
 
142
142
  false
143
-
144
143
  }
145
-
146
144
  }
147
145
 
146
+ /**
147
+ * Forwards Android Activity results back to the active Amber signer.
148
+ *
149
+ * Required because Amber communication is based on the Android
150
+ * Activity Result API.
151
+ */
152
+ fun handleAmberResult(result: ActivityResult) {
153
+ (activeSigner as? AmberSigner)
154
+ ?.onResult(result)
155
+ }
148
156
  }
@@ -2,7 +2,6 @@ package com.pakstr.app.signer
2
2
 
3
3
  enum class SignerType {
4
4
  AMBER,
5
-
6
5
  BUNKER,
7
6
  FAKE
8
7
 
@@ -0,0 +1,5 @@
1
+ package com.pakstr.app.signer.exceptions
2
+
3
+ class SignerUnavailableException(
4
+ message: String
5
+ ) : Exception(message)
@@ -1,3 +1,3 @@
1
1
  <resources>
2
- <string name="app_name">NostrAppShell</string>
2
+ <string name="app_name">Pakstr</string>
3
3
  </resources>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pakstr",
3
- "version": "0.0.3",
3
+ "version": "0.1.0",
4
4
  "description": "CLI for packaging Nostr web apps into Android APKs",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",