upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/55.md
diff options
context:
space:
mode:
Diffstat (limited to '55.md')
-rw-r--r--55.md213
1 files changed, 149 insertions, 64 deletions
diff --git a/55.md b/55.md
index 4565e8c..afca0aa 100644
--- a/55.md
+++ b/55.md
@@ -1,6 +1,8 @@
1# NIP-55 1NIP-55
2======
2 3
3## Android Signer Application 4Android Signer Application
5--------------------------
4 6
5`draft` `optional` 7`draft` `optional`
6 8
@@ -51,8 +53,8 @@ val launcher = rememberLauncherForActivityResult(
51 Toast.LENGTH_SHORT 53 Toast.LENGTH_SHORT
52 ).show() 54 ).show()
53 } else { 55 } else {
54 val signature = activityResult.data?.getStringExtra("signature") 56 val result = activityResult.data?.getStringExtra("result")
55 // Do something with signature ... 57 // Do something with result ...
56 } 58 }
57 } 59 }
58) 60)
@@ -70,6 +72,35 @@ Set the Signer package name:
70intent.`package` = "com.example.signer" 72intent.`package` = "com.example.signer"
71``` 73```
72 74
75If you are sending multiple intents without awaiting you can add some intent flags to sign all events without opening multiple times the signer
76
77```kotlin
78intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
79```
80
81If you are developing a signer application them you need to add this to your AndroidManifest.xml so clients can use the intent flags above
82
83```kotlin
84android:launchMode="singleTop"
85```
86
87Signer MUST answer multiple permissions with an array of results
88
89```kotlin
90
91val results = listOf(
92 Result(
93 package = signerPackageName,
94 result = eventSignture,
95 id = intentId
96 )
97)
98
99val json = results.toJson()
100
101intent.putExtra("results", json)
102```
103
73Send the Intent: 104Send the Intent:
74 105
75```kotlin 106```kotlin
@@ -99,10 +130,10 @@ launcher.launch(intent)
99 context.startActivity(intent) 130 context.startActivity(intent)
100 ``` 131 ```
101 - result: 132 - result:
102 - If the user approved intent it will return the **npub** in the signature field 133 - If the user approved intent it will return the **pubkey** in the result field
103 134
104 ```kotlin 135 ```kotlin
105 val npub = intent.data?.getStringExtra("signature") 136 val pubkey = intent.data?.getStringExtra("result")
106 // The package name of the signer application 137 // The package name of the signer application
107 val packageName = intent.data?.getStringExtra("package") 138 val packageName = intent.data?.getStringExtra("package")
108 ``` 139 ```
@@ -116,16 +147,16 @@ launcher.launch(intent)
116 intent.putExtra("type", "sign_event") 147 intent.putExtra("type", "sign_event")
117 // To handle results when not waiting between intents 148 // To handle results when not waiting between intents
118 intent.putExtra("id", event.id) 149 intent.putExtra("id", event.id)
119 // Send the current logged in user npub 150 // Send the current logged in user pubkey
120 intent.putExtra("current_user", npub) 151 intent.putExtra("current_user", pubkey)
121 152
122 context.startActivity(intent) 153 context.startActivity(intent)
123 ``` 154 ```
124 - result: 155 - result:
125 - If the user approved intent it will return the **signature**, **id** and **event** fields 156 - If the user approved intent it will return the **result**, **id** and **event** fields
126 157
127 ```kotlin 158 ```kotlin
128 val signature = intent.data?.getStringExtra("signature") 159 val signature = intent.data?.getStringExtra("result")
129 // The id you sent 160 // The id you sent
130 val id = intent.data?.getStringExtra("id") 161 val id = intent.data?.getStringExtra("id")
131 val signedEventJson = intent.data?.getStringExtra("event") 162 val signedEventJson = intent.data?.getStringExtra("event")
@@ -140,18 +171,18 @@ launcher.launch(intent)
140 intent.putExtra("type", "nip04_encrypt") 171 intent.putExtra("type", "nip04_encrypt")
141 // to control the result in your application in case you are not waiting the result before sending another intent 172 // to control the result in your application in case you are not waiting the result before sending another intent
142 intent.putExtra("id", "some_id") 173 intent.putExtra("id", "some_id")
143 // Send the current logged in user npub 174 // Send the current logged in user pubkey
144 intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) 175 intent.putExtra("current_user", account.keyPair.pubkey)
145 // Send the hex pubKey that will be used for encrypting the data 176 // Send the hex pubkey that will be used for encrypting the data
146 intent.putExtra("pubKey", pubKey) 177 intent.putExtra("pubkey", pubkey)
147 178
148 context.startActivity(intent) 179 context.startActivity(intent)
149 ``` 180 ```
150 - result: 181 - result:
151 - If the user approved intent it will return the **signature** and **id** fields 182 - If the user approved intent it will return the **result** and **id** fields
152 183
153 ```kotlin 184 ```kotlin
154 val encryptedText = intent.data?.getStringExtra("signature") 185 val encryptedText = intent.data?.getStringExtra("result")
155 // the id you sent 186 // the id you sent
156 val id = intent.data?.getStringExtra("id") 187 val id = intent.data?.getStringExtra("id")
157 ``` 188 ```
@@ -165,10 +196,10 @@ launcher.launch(intent)
165 intent.putExtra("type", "nip44_encrypt") 196 intent.putExtra("type", "nip44_encrypt")
166 // to control the result in your application in case you are not waiting the result before sending another intent 197 // to control the result in your application in case you are not waiting the result before sending another intent
167 intent.putExtra("id", "some_id") 198 intent.putExtra("id", "some_id")
168 // Send the current logged in user npub 199 // Send the current logged in user pubkey
169 intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) 200 intent.putExtra("current_user", account.keyPair.pubkey)
170 // Send the hex pubKey that will be used for encrypting the data 201 // Send the hex pubkey that will be used for encrypting the data
171 intent.putExtra("pubKey", pubKey) 202 intent.putExtra("pubkey", pubkey)
172 203
173 context.startActivity(intent) 204 context.startActivity(intent)
174 ``` 205 ```
@@ -190,18 +221,18 @@ launcher.launch(intent)
190 intent.putExtra("type", "nip04_decrypt") 221 intent.putExtra("type", "nip04_decrypt")
191 // to control the result in your application in case you are not waiting the result before sending another intent 222 // to control the result in your application in case you are not waiting the result before sending another intent
192 intent.putExtra("id", "some_id") 223 intent.putExtra("id", "some_id")
193 // Send the current logged in user npub 224 // Send the current logged in user pubkey
194 intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) 225 intent.putExtra("current_user", account.keyPair.pubkey)
195 // Send the hex pubKey that will be used for decrypting the data 226 // Send the hex pubkey that will be used for decrypting the data
196 intent.putExtra("pubKey", pubKey) 227 intent.putExtra("pubkey", pubkey)
197 228
198 context.startActivity(intent) 229 context.startActivity(intent)
199 ``` 230 ```
200 - result: 231 - result:
201 - If the user approved intent it will return the **signature** and **id** fields 232 - If the user approved intent it will return the **result** and **id** fields
202 233
203 ```kotlin 234 ```kotlin
204 val plainText = intent.data?.getStringExtra("signature") 235 val plainText = intent.data?.getStringExtra("result")
205 // the id you sent 236 // the id you sent
206 val id = intent.data?.getStringExtra("id") 237 val id = intent.data?.getStringExtra("id")
207 ``` 238 ```
@@ -215,18 +246,41 @@ launcher.launch(intent)
215 intent.putExtra("type", "nip04_decrypt") 246 intent.putExtra("type", "nip04_decrypt")
216 // to control the result in your application in case you are not waiting the result before sending another intent 247 // to control the result in your application in case you are not waiting the result before sending another intent
217 intent.putExtra("id", "some_id") 248 intent.putExtra("id", "some_id")
218 // Send the current logged in user npub 249 // Send the current logged in user pubkey
219 intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) 250 intent.putExtra("current_user", account.keyPair.pubkey)
220 // Send the hex pubKey that will be used for decrypting the data 251 // Send the hex pubkey that will be used for decrypting the data
221 intent.putExtra("pubKey", pubKey) 252 intent.putExtra("pubkey", pubkey)
222 253
223 context.startActivity(intent) 254 context.startActivity(intent)
224 ``` 255 ```
225 - result: 256 - result:
226 - If the user approved intent it will return the **signature** and **id** fields 257 - If the user approved intent it will return the **result** and **id** fields
227 258
228 ```kotlin 259 ```kotlin
229 val plainText = intent.data?.getStringExtra("signature") 260 val plainText = intent.data?.getStringExtra("result")
261 // the id you sent
262 val id = intent.data?.getStringExtra("id")
263 ```
264
265- **get_relays**
266 - params:
267
268 ```kotlin
269 val intent = Intent(Intent.ACTION_VIEW, Uri.parse("nostrsigner:"))
270 intent.`package` = "com.example.signer"
271 intent.putExtra("type", "get_relays")
272 // to control the result in your application in case you are not waiting the result before sending another intent
273 intent.putExtra("id", "some_id")
274 // Send the current logged in user pubkey
275 intent.putExtra("current_user", account.keyPair.pubkey)
276
277 context.startActivity(intent)
278 ```
279 - result:
280 - If the user approved intent it will return the **result** and **id** fields
281
282 ```kotlin
283 val relayJsonText = intent.data?.getStringExtra("result")
230 // the id you sent 284 // the id you sent
231 val id = intent.data?.getStringExtra("id") 285 val id = intent.data?.getStringExtra("id")
232 ``` 286 ```
@@ -240,15 +294,15 @@ launcher.launch(intent)
240 intent.putExtra("type", "decrypt_zap_event") 294 intent.putExtra("type", "decrypt_zap_event")
241 // to control the result in your application in case you are not waiting the result before sending another intent 295 // to control the result in your application in case you are not waiting the result before sending another intent
242 intent.putExtra("id", "some_id") 296 intent.putExtra("id", "some_id")
243 // Send the current logged in user npub 297 // Send the current logged in user pubkey
244 intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) 298 intent.putExtra("current_user", account.keyPair.pubkey)
245 context.startActivity(intent) 299 context.startActivity(intent)
246 ``` 300 ```
247 - result: 301 - result:
248 - If the user approved intent it will return the **signature** and **id** fields 302 - If the user approved intent it will return the **result** and **id** fields
249 303
250 ```kotlin 304 ```kotlin
251 val eventJson = intent.data?.getStringExtra("signature") 305 val eventJson = intent.data?.getStringExtra("result")
252 // the id you sent 306 // the id you sent
253 val id = intent.data?.getStringExtra("id") 307 val id = intent.data?.getStringExtra("id")
254 ``` 308 ```
@@ -257,11 +311,11 @@ launcher.launch(intent)
257 311
258To get the result back from Signer Application you should use contentResolver.query in Kotlin. If you are using another framework check the documentation of your framework or a third party library to get the result. 312To get the result back from Signer Application you should use contentResolver.query in Kotlin. If you are using another framework check the documentation of your framework or a third party library to get the result.
259 313
260If the user did not check the "remember my choice" option, the npub is not in Signer Application or the signer type is not recognized the `contentResolver` will return null 314If the user did not check the "remember my choice" option, the pubkey is not in Signer Application or the signer type is not recognized the `contentResolver` will return null
261 315
262For the SIGN_EVENT type Signer Application returns two columns "signature" and "event". The column event is the signed event json 316For the SIGN_EVENT type Signer Application returns two columns "result" and "event". The column event is the signed event json
263 317
264For the other types Signer Application returns the column "signature" 318For the other types Signer Application returns the column "result"
265 319
266If the user chose to always reject the event, signer application will return the column "rejected" and you should not open signer application 320If the user chose to always reject the event, signer application will return the column "rejected" and you should not open signer application
267 321
@@ -280,15 +334,15 @@ If the user chose to always reject the event, signer application will return the
280 ) 334 )
281 ``` 335 ```
282 - result: 336 - result:
283 - Will return the **npub** in the signature column 337 - Will return the **pubkey** in the result column
284 338
285 ```kotlin 339 ```kotlin
286 if (result == null) return 340 if (result == null) return
287 341
288 if (result.moveToFirst()) { 342 if (result.moveToFirst()) {
289 val index = it.getColumnIndex("signature") 343 val index = it.getColumnIndex("result")
290 if (index < 0) return 344 if (index < 0) return
291 val npub = it.getString(index) 345 val pubkey = it.getString(index)
292 } 346 }
293 ``` 347 ```
294 348
@@ -298,20 +352,20 @@ If the user chose to always reject the event, signer application will return the
298 ```kotlin 352 ```kotlin
299 val result = context.contentResolver.query( 353 val result = context.contentResolver.query(
300 Uri.parse("content://com.example.signer.SIGN_EVENT"), 354 Uri.parse("content://com.example.signer.SIGN_EVENT"),
301 listOf("$eventJson", "", "${logged_in_user_npub}"), 355 listOf("$eventJson", "", "${logged_in_user_pubkey}"),
302 null, 356 null,
303 null, 357 null,
304 null 358 null
305 ) 359 )
306 ``` 360 ```
307 - result: 361 - result:
308 - Will return the **signature** and the **event** columns 362 - Will return the **result** and the **event** columns
309 363
310 ```kotlin 364 ```kotlin
311 if (result == null) return 365 if (result == null) return
312 366
313 if (result.moveToFirst()) { 367 if (result.moveToFirst()) {
314 val index = it.getColumnIndex("signature") 368 val index = it.getColumnIndex("result")
315 val indexJson = it.getColumnIndex("event") 369 val indexJson = it.getColumnIndex("event")
316 val signature = it.getString(index) 370 val signature = it.getString(index)
317 val eventJson = it.getString(indexJson) 371 val eventJson = it.getString(indexJson)
@@ -324,20 +378,20 @@ If the user chose to always reject the event, signer application will return the
324 ```kotlin 378 ```kotlin
325 val result = context.contentResolver.query( 379 val result = context.contentResolver.query(
326 Uri.parse("content://com.example.signer.NIP04_ENCRYPT"), 380 Uri.parse("content://com.example.signer.NIP04_ENCRYPT"),
327 listOf("$plainText", "${hex_pub_key}", "${logged_in_user_npub}"), 381 listOf("$plainText", "${hex_pub_key}", "${logged_in_user_pubkey}"),
328 null, 382 null,
329 null, 383 null,
330 null 384 null
331 ) 385 )
332 ``` 386 ```
333 - result: 387 - result:
334 - Will return the **signature** column 388 - Will return the **result** column
335 389
336 ```kotlin 390 ```kotlin
337 if (result == null) return 391 if (result == null) return
338 392
339 if (result.moveToFirst()) { 393 if (result.moveToFirst()) {
340 val index = it.getColumnIndex("signature") 394 val index = it.getColumnIndex("result")
341 val encryptedText = it.getString(index) 395 val encryptedText = it.getString(index)
342 } 396 }
343 ``` 397 ```
@@ -348,20 +402,20 @@ If the user chose to always reject the event, signer application will return the
348 ```kotlin 402 ```kotlin
349 val result = context.contentResolver.query( 403 val result = context.contentResolver.query(
350 Uri.parse("content://com.example.signer.NIP44_ENCRYPT"), 404 Uri.parse("content://com.example.signer.NIP44_ENCRYPT"),
351 listOf("$plainText", "${hex_pub_key}", "${logged_in_user_npub}"), 405 listOf("$plainText", "${hex_pub_key}", "${logged_in_user_pubkey}"),
352 null, 406 null,
353 null, 407 null,
354 null 408 null
355 ) 409 )
356 ``` 410 ```
357 - result: 411 - result:
358 - Will return the **signature** column 412 - Will return the **result** column
359 413
360 ```kotlin 414 ```kotlin
361 if (result == null) return 415 if (result == null) return
362 416
363 if (result.moveToFirst()) { 417 if (result.moveToFirst()) {
364 val index = it.getColumnIndex("signature") 418 val index = it.getColumnIndex("result")
365 val encryptedText = it.getString(index) 419 val encryptedText = it.getString(index)
366 } 420 }
367 ``` 421 ```
@@ -372,20 +426,20 @@ If the user chose to always reject the event, signer application will return the
372 ```kotlin 426 ```kotlin
373 val result = context.contentResolver.query( 427 val result = context.contentResolver.query(
374 Uri.parse("content://com.example.signer.NIP04_DECRYPT"), 428 Uri.parse("content://com.example.signer.NIP04_DECRYPT"),
375 listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_npub}"), 429 listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_pubkey}"),
376 null, 430 null,
377 null, 431 null,
378 null 432 null
379 ) 433 )
380 ``` 434 ```
381 - result: 435 - result:
382 - Will return the **signature** column 436 - Will return the **result** column
383 437
384 ```kotlin 438 ```kotlin
385 if (result == null) return 439 if (result == null) return
386 440
387 if (result.moveToFirst()) { 441 if (result.moveToFirst()) {
388 val index = it.getColumnIndex("signature") 442 val index = it.getColumnIndex("result")
389 val encryptedText = it.getString(index) 443 val encryptedText = it.getString(index)
390 } 444 }
391 ``` 445 ```
@@ -396,44 +450,68 @@ If the user chose to always reject the event, signer application will return the
396 ```kotlin 450 ```kotlin
397 val result = context.contentResolver.query( 451 val result = context.contentResolver.query(
398 Uri.parse("content://com.example.signer.NIP44_DECRYPT"), 452 Uri.parse("content://com.example.signer.NIP44_DECRYPT"),
399 listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_npub}"), 453 listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_pubkey}"),
400 null, 454 null,
401 null, 455 null,
402 null 456 null
403 ) 457 )
404 ``` 458 ```
405 - result: 459 - result:
406 - Will return the **signature** column 460 - Will return the **result** column
407 461
408 ```kotlin 462 ```kotlin
409 if (result == null) return 463 if (result == null) return
410 464
411 if (result.moveToFirst()) { 465 if (result.moveToFirst()) {
412 val index = it.getColumnIndex("signature") 466 val index = it.getColumnIndex("result")
413 val encryptedText = it.getString(index) 467 val encryptedText = it.getString(index)
414 } 468 }
415 ``` 469 ```
416 470
471- **get_relays**
472 - params:
473
474 ```kotlin
475 val result = context.contentResolver.query(
476 Uri.parse("content://com.example.signer.GET_RELAYS"),
477 listOf("${logged_in_user_pubkey}"),
478 null,
479 null,
480 null
481 )
482 ```
483 - result:
484 - Will return the **result** column
485
486 ```kotlin
487 if (result == null) return
488
489 if (result.moveToFirst()) {
490 val index = it.getColumnIndex("result")
491 val relayJsonText = it.getString(index)
492 }
493 ```
494
417- **decrypt_zap_event** 495- **decrypt_zap_event**
418 - params: 496 - params:
419 497
420 ```kotlin 498 ```kotlin
421 val result = context.contentResolver.query( 499 val result = context.contentResolver.query(
422 Uri.parse("content://com.example.signer.DECRYPT_ZAP_EVENT"), 500 Uri.parse("content://com.example.signer.DECRYPT_ZAP_EVENT"),
423 listOf("$eventJson", "", "${logged_in_user_npub}"), 501 listOf("$eventJson", "", "${logged_in_user_pubkey}"),
424 null, 502 null,
425 null, 503 null,
426 null 504 null
427 ) 505 )
428 ``` 506 ```
429 - result: 507 - result:
430 - Will return the **signature** column 508 - Will return the **result** column
431 509
432 ```kotlin 510 ```kotlin
433 if (result == null) return 511 if (result == null) return
434 512
435 if (result.moveToFirst()) { 513 if (result.moveToFirst()) {
436 val index = it.getColumnIndex("signature") 514 val index = it.getColumnIndex("result")
437 val eventJson = it.getString(index) 515 val eventJson = it.getString(index)
438 } 516 }
439 ``` 517 ```
@@ -470,28 +548,35 @@ Android intents and browser urls have limitations, so if you are using the `retu
470 - params: 548 - params:
471 549
472 ```js 550 ```js
473 window.href = `nostrsigner:${plainText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_encrypt&callbackUrl=https://example.com/?event=`; 551 window.href = `nostrsigner:${plainText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_encrypt&callbackUrl=https://example.com/?event=`;
474 ``` 552 ```
475 553
476- **nip44_encrypt** 554- **nip44_encrypt**
477 - params: 555 - params:
478 556
479 ```js 557 ```js
480 window.href = `nostrsigner:${plainText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_encrypt&callbackUrl=https://example.com/?event=`; 558 window.href = `nostrsigner:${plainText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_encrypt&callbackUrl=https://example.com/?event=`;
481 ``` 559 ```
482 560
483- **nip04_decrypt** 561- **nip04_decrypt**
484 - params: 562 - params:
485 563
486 ```js 564 ```js
487 window.href = `nostrsigner:${encryptedText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_decrypt&callbackUrl=https://example.com/?event=`; 565 window.href = `nostrsigner:${encryptedText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_decrypt&callbackUrl=https://example.com/?event=`;
488 ``` 566 ```
489 567
490- **nip44_decrypt** 568- **nip44_decrypt**
491 - params: 569 - params:
492 570
493 ```js 571 ```js
494 window.href = `nostrsigner:${encryptedText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_decrypt&callbackUrl=https://example.com/?event=`; 572 window.href = `nostrsigner:${encryptedText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_decrypt&callbackUrl=https://example.com/?event=`;
573 ```
574
575- **get_relays**
576 - params:
577
578 ```js
579 window.href = `nostrsigner:?compressionType=none&returnType=signature&type=get_relays&callbackUrl=https://example.com/?event=`;
495 ``` 580 ```
496 581
497- **decrypt_zap_event** 582- **decrypt_zap_event**