GM! Verified that this approach works. This is where the fun begins.
3. Signer iOS action extension via Share Sheet ✅ View quoted note →
Login to reply
Replies (47)
So the UX is that when the app wants to sign something a share screen pops up, the user taps the signer and the app gets the signature?
I’ve had this idea for a while now, but I don’t know if it works or not.
3rd party keyboard signer.
GM Fren 🌞 have an amazing day today 🤗
Yes. For example:
1. User drafts a kind 1 note in their favorite Nostr client and taps “Post”.
2. Nostr client invokes the Share Sheet with parameters looking something like ["nostrsigner", "<nostr-client-name-plus-stable-uuid", "sign_event", "eventJSON"]
3. If the user has told the signer previously that it trusts the Nostr client to sign events of kind 1, then it’ll sign the event, not show any UI, and dismiss the share sheet.
4. If not, a UI will pop up asking the user to allow or deny the request, with an option to remember this preference for the future for this client.
4. Nostr client receives the completion callback with the signed event.
5. Nostr client publishes to relays.
This should work like an RPC call, and should work for other operations like get_pubkey, nip[04/44]_[encrypt/decrypt], and decrypt_zap_event.
I will be opening a PR to amend NIP-55 to support iOS signers soon once it’s a bit more fleshed out.
Oops, minor typos:
1. User drafts a kind 1 note in their favorite Nostr client and taps “Post”.
2. Nostr client invokes the Share Sheet with parameters looking something like ["nostrsigner", "<nostr-client-name-plus-stable-uuid", "sign_event", "eventJSON"]
3. User taps “Sign Event”.
4. If the user has told the signer previously that it trusts the Nostr client to sign events of kind 1, then it’ll sign the event, not show any UI, and dismiss the share sheet.
5. If not, a UI will pop up asking the user to allow or deny the request, with an option to remember this preference for the future for this client.
6. Nostr client receives the completion callback with the signed event.
7. Nostr client publishes to relays.
GM to you too. Keep going
"If the user has told the signer previously that it trusts the Nostr client to sign events of kind 1, then it’ll sign the event, not show any UI, and dismiss the share sheet."
This is MONEY 👌
Sounds like an interesting idea! I don’t know much about developing custom keyboards.
Someone should try it!

Apple Developer Documentation
Creating a custom keyboard | Apple Developer Documentation
Add an extension to your Xcode project to provide systemwide customized text input.
Wait so the share screen doesn’t even open? Do you have a screencap of this?
The share sheet has to open, and the user needs to tap “Sign Nostr Event”. But depending on their signer preferences, they may or may not be prompted to take action on an additional screen. Here’s a screencap of a trusted signer action that doesn’t require additional action.
@rabble @Matt Lorentz @jb55 @Fabian @Pavle @miljan @PABLOF7z ^ Let me know what you think of this proof of concept UX screencap for a native iOS Nostr signer and if you’d be open to adding it in your clients once I get it production ready. I think this is the best possible UX given that the Nostr client stays in the foreground.
The alternatives were:
1. Ask the user to install a shortcut (non-intuitive) + invoke the shortcut (Action Button on iPhone 15+, accessibility back tap < iPhone 15, non-intuitive) + clipboard hacks (inefficient, error prone).
2. Use nostrsigner:// deeplinks to switch to the signer (forces app switching twice).
Doing this for every action such as liking things is going to be a ux nightmare
Is it going to have to pop up the sheet for every event that needs signing?
I’m not opposed to accepting a PR to support it but the only people asking for this are Nostr devs who don’t want to trust the code of other Nostr devs. I don’t think anyone who isn’t already self-custodying their crypto will use it.
We’ve never had a user come to us and say they won’t use @nos because we store the keys in Apple’s keychain.
Would it be nice to have an option for an Amber like solution for iOS, sure. But I doubt it’ll get much use. Kind of like how it’s great Signal is open source, but there isn’t much anyone can or does do with the source.
Yes. For frequent actions like reactions, I agree. But for security sensitive folks who don’t fully trust pasting in their private keys into clients, this could be a reasonable, albeit slightly painful, compromise.
Yes, unfortunately it has to show the sheet each time with this approach. I don’t disagree with you. Developers and security conscious people would be the target audience for this approach. I would not say that the UX is close to good enough to be the primary way of signing events. However, as Nostr scales over time, there are bound to be clients that are malicious or have bugs that lead to bad data being signed. The native signer could be a reasonable compromise for those who care.
Maybe there could be a way to batch sign events. Add unsigned events to a queue, and then batch sign them all at once after a queue limit or time limit has been reached.
Would be better
It would also require client rewrites to support it :( having unsigned events everywhere
This is probably the best local UX given iOS limitations, still horrible (not your fault), but I’m open to adding it in Nostur
It’s really not though. A good UX would be to oauth to a server that does signing or which provides an expiring sharded key which works for the session.
Users don’t want to approve actions for nostr keys the way they handle wallet signatures because it’s a thousands of times a day thing and not a dozen times a week thing
I agree, I meant there is no better way without getting a server involved because iOS…
I hope iOS users will be able to use this instead of rawdogging the nsec into every client.
GM! Verified that this approach works. This is where the fun begins.
3. Signer iOS action extension via Share Sheet ✅ View quoted note →
View quoted note →
I agree. How does NIP-46 remote signing rank with what you described?
I’ve got a draft of a post asking questions about nip-46. When i provide an app the bunker url they’re able to then sign content on my behalf with the bunker without my ability to revoke access. I don’t see where bunker’s provide an audit log of which apps are using the bunker, lettting me see what they’ve done and revoke them. I can do this when i use oauth to authorize apps on github or twitter.
There doesn’t appear to be a round trip process for authorizing requests. I think nsec.app does but as far as i can tell the new nstart.njump.me stuff just kind of has you jump through all of these hoops with random nsecrypto strings which aren’t explained, FROST servers, etc… only to give you a bunker url to copy around, which provides no more security for a normal user than asking them to share their nsec…..
I just don’t get it. What’s the point of all this security and layers of confusion. I mean to a user, what’s the difference between pasting around an nsec string and bunker:// string? Both provide irrevocable permanent access to everything you’ve got on nostr and to do anything on your behalf.
With your thing @Terry Yiu it kind of goes the other way, make the user jump through a whole series of 2fa auth steps for each and every action they want to do on Nostr. Are either of these better than an auth server provided by google/microsoft/okta/apple where you oauth in to apps?
If you ask users too many security questions, they just hit the ok button until the popups go away. If you make a system that has unrevokable access then that’s in every way worse than a custodial auth system. I don’t see how the bunker system is better than a server that holds nostr keys, lets the client apps login via normal web login using oauth, and then lets the user see what apps are authorized so they can track which actions were done by what app and remove the authorization token.
That’s not my understanding of how NIP-46 remote signing works. Revocation is supported. All that needs to happen is for the user to tell the bunker to revoke access to the client-pubkey.
Bunkers can and do keep an audit log. It’s not mentioned in the spec but there’s no reason why it can’t.
The bunker can also refuse to respond to requests from the client depending on the user’s permission settings.
Passing nsecs around and passing connection strings around are not equivalent. Connection strings are single use as the secret is single use.
I think remote-signers do effectively solve security concerns around misuse of user-keypairs as long as the user trusts the remote-signer. My criticism of them is the required server round trips leading to increased latency, and increased difficulty in onboarding and UX. nsec.app and Amber seem to work decently under the circumstances, though.
I will look into adding NIP-46 integration into my signer, but I’ll have to be creative because iOS makes it difficult due to sandboxing, limiting seamless cross-app communication.
FROST signer just doesn't have proper permission management yet. Nsec.app does, and has a log of access, and list of permissions that can be revoked.
Is there a doc to read more about FROST on Nostr?
what’s wrong with the nsec.app PWA for iOS?
Nothing is wrong with nsec.app, but it’s suboptimal. It requires a server. iOS is sandboxed and only one app can be in the foreground at a time, so push notifications are needed when a signer request comes in to be able to switch to the signer each time to approve it. It requires nsec.app to be up all the time to be able to sign your events, unless you self-host. One benefit is that you can use nsec.app to approve signer requests that didn’t originate from that same device. @brugeman Please let me know if I interpreted how nsec.app works incorrectly.
My proposal is to have my signer be operational offline, and not need you to switch from your Nostr app to the signer. Everything can be done through the signer action extension in the sheet while the Nostr app is in the foreground the entire time. This would work only for same-device signer requests. It’s a non-optimal UX to do this for each action, but I would also argue that the nsec.app approach is also non-optimal in slightly different ways.
Anyway, iOS makes it difficult to have an on-device signer if you want it to work on the same device as your Nostr app, regardless of approach.
Appreciate your detailed response.
Yes you interpreted nsec.app's architecture right, it depends on a server that detects unanswered requests and sends push notifications to wake up. iOS is actually broken with a PWA, the issue is that PWAs don't receive push messages on time after the last iOS update, which makes nsec.app basically unable to work in the background.
Offline signer like Amber using native inter-app comms is obviously a much better approach, but it doesn't work on iOS or across devices, so if you're using desktop you'll still need something like nsec.app. Confirming every action is a UX nightmare for active daily use - people complain very hard here every time Alby popup shows up without much necessity. I think it's inevitable for iOS to come up with inter-app comms API someday, so maybe all we need is just wait a bit.
It's great that you're exploring options on iOS and I bet there will be useful building blocks created as a result, so please keep doing it and sharing your learnings!
Apple treats remote push notifications as low priority and doesn’t guarantee delivery. It also seems like they will throttle if the app or device exceed limits.
> The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour.


Apple Developer Documentation
Pushing background updates to your App | Apple Developer Documentation
Deliver notifications that wake your app and update it in the background.
We're not using background notifications, we are PWA and are required by browser standards to show the visible notification, which we do. We're not getting _any_ notifications delivered until the PWA is manually launched, at least we didn't the last time we investigated this several months ago. Things worked before the last iOS update (web push was experimental and had to be enabled in iOS settings, but when done - it worked).
Oh weird. Hope Apple fixes it.
I had the issues you describe with nsec.app on iphone 12 mini but on iphone 16 it feels like it works well
You mean it's PWA and working well in the background? Does it show you push notifications?
Yes, the push notifications are how i know its working. With iphone 12 i often had to bring the app to the foreground to get the app to sign
Can you please check which exact iOS version you're running where push are working? Thanks!
I'm on the latest iOS 18.3.
Thanks, will check again!
I think im wrong... the notification appears but the action doesnt happen until i open nsec.app 😔
Hm... that's interesting!
Are you still working on this? There’s definitely still a need
It’s tough out on these iOS streets 😄
I am! I haven’t forgotten about it but I was sidelined with several other non-Nostr priorities for quite a bit of time. Trying to get back on it.
Thank you, sir 🙏
Doing the Lord’s work
No pressure, but the future of the entire nostr protocol hinges on this