Oddbean new post about | logout

Notes by The Fishcake🐶🐾 | export

 Anything that has no “Lite” in the name, anything! 😂😂😂🫂 
 😂😂😂 
 Booooooo! Show yourself out of the classroom 😂😂😂 
 I am more of a Larger, and Ale type of dog! Beer is a very personal thing, no man likes one and the same way! 🫂😂🫡🍻🍺 
 GM!😂🫂🖕🏻 
 GA🫡☕️ 
 Hey 👋🏻☕️ 
 GM☕️🫡 
 Are you a bot? You’ve already said that. 
 “How’s it going?” Is usually used hypothetically, and does not require a direct answer. Me stating “All good” doesn’t really give you much info, so I dropped it. 🫂😂 
 I don’t know yet, my day has just started 😂 
 Too long 😂 
 I know I GNed already, but I forgot to mention one thing. 

I get stressed and irritated —> I open Damus —> I read some funny shit —> I de-stress —> I go back to do stressful things —> cycle repeats!
😂😂😂🖕🏻🫂🖕🏻GFY! 
 iPhone is not stressing me, life and work and responsibilities are. I wish it was that simple 😂😭😭😭 
 I sleep on the floor, GFY! 😂😂😂 
 Interestingly, 3 years ago, I gave two of my nephews 250,000 BTC each. They were older, so I gave... 
 Did you mean to say 250K sats and not BTC by any chance 😂🫂 
 GM nostr. 
 GM☕️🫡 
 I’ve been thinking of making my own iOS NIP07 and 44/04 signer/encryptor/decryptor extension for a while. Time is the only obstacle. 😭😭😭 https://i.nostr.build/Y15yIlr3Eh5HXP8U.gif  
 Lacking time to work on it, too busy with nostr.build work and fiat mines and family life 😂🫂😭🙏🏻 
 Is Nostore ded ☠️ again?

I updated in flightest but nothing (iOS)

#asknostr 
 Use AppStore version, it is updated now 
 What iOS version are you on? 
 💯 you need 18 for it to work now 
 Update that I made and submitted PR did break it for older versions. I didn’t have anything to check and the original maintainer doesn’t want to maintain it anymore so the “broken” version went out as is 😭😭😭🙏🏻🙇‍♂️🙇‍♂️🙇‍♂️ 
 When you forget that you changes your own PFP a few months ago, and try to see who’s post is this. 😂😂😂🤔🐶🐾 https://i.nostr.build/zrryyjPsa7bUnaSO.gif  
 lol! I was confused about my own notes! “Way with words” da fuck “words” mean? 🤣😂🤣🤔🤔🤔🤔🤡 
 Doesn’t work with GIFs apparently 😭 
 I just copied my NOSTR Private Key and pasted it directly into another nostr APP.

How safe is th... 
 On the phone, then you are likely OK if the app is reputable and uses keys storage 
 GM🫡☕️ 
 GM🫂☕️ 
 GM☕️🙏🏻 
 GM🫂☕️ 
 GM🫡☕️ 
 GM🫂☕️ 
 An interesting revelation I had when talking to nostr:nprofile1qqsglv2qkn5dmmuhee9cy8fywfu2rfp4xd... 
 I’ve added NIP40 expiration to the wrapper event but it doesn’t seem to be respected by the relay or server. Would be cool if all relays supported nip40 for all of the event kinds. 
 Yeah, get rid of that shit 04 😂😂😂🤣🫂(“Why are we disliking nip04 so much” - me a day ago) 
 nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z nostr:npub1jlrs53pkdfjnts29... 
 I needed to construct one in TS and send it off, so probably wouldn’t help. I’ll donate some code example which I posted here earlier, to the nip repo 
 It would have been yesterday 😂🤣🫂 
 GN.🫂💤 
 Maybe send a PR with some of this code to nostr-tools?  
 It works! :)  
 Good idea! 🫂 
 PSA: Nostr.build is now additionally sending Gift Wrapped DMs for OTP and reminders. If your client supports both (17 and 04 nips) you may see duplicates. Cannot reliably discriminate between the clients, so must duplicate 😭🫂🙇‍♂️ 
 Not in my case, I am not running a permanently connected client, I need reliability (fetch from what relay? All of them? How long will it take?) 
 I still won't buy a apple product even though this is super cool 😂 sorry nostr:nprofile1qqsral... 
 Google slave! 😂😂😂🤣🫂 
 Nostr devs: Wouldn't it be very useful for caching if relays sent their timestamp next to events?... 
 What timestamp do you need? Current time? 🤔 
 Take current time and in 99.99999999999999% of cases it’s the same as the server. Servers don’t usually drift unless something is very broken, at which point it doesn’t really matter 
 It’ll be in ISO or Unix epoch, you can take it from there since TZ is either explicit or UTC by default 
 NIP04 is great for OTP uses, be a lot cooler if we kept support of both. There is no single solution for all problems.🫡 
 Any good examples on how I can reach a single person with the message without knowing anything about them but their npub only? And not being able to query any relays and just broadcast it as wide as possible? 
 So it means now I have to send two DMs, one with 04 and one with 17 😭😭😭 
 Looking at nip17, I still have no idea how I can use nostr-tools and create a correct DM. One part of being secure is having less ways to shoot yourself into a foot, and I see a lot of landmines that will reap my legs off when I read it. I asked for a good example using nostr-tools and failed to find even one yet. 😭😭😭😭 
 Can’t ask normal users to jump through the hoops, if they are on Damus or any other client that yet to support it, I’ll have a long list of people complaining about broken OTP 😭 
 Thanks! This will help ! 🫂🙏🏻🫡 
 async function createNip17Wraps(message, senderPubkey, receiverPubkey)

Where do I stick my SK into? And what do I do with the returned values that are in non-event format? 
 Always has been the case, people just make a blank statement “<thing> is bad” and have 0 regard for all that came before or relies on it. Plus “bad” is only based on use case, and nothing more than that. 
 Already have that, but not all people have or can have an extension 
 Ok, I’ll take a look again and see if I can implement it. I assume that I do not need to send the “sender” part since it is OTP and nobody needs to check it as a sender 
 I implemented it for the nostr.build just now but not sure if it even works. I still send 04 and now 17 as well. I have no way to verify it 😅 
 I had some other issues, and didn’t have the messages actually sent anywhere, now they are but none of the clients see them only 04. Hence my point, if it is complex and close to impossible to implement even with examples, it will not be used or will be misused or misimplemented 😭😭😭 
 😅 the code that does the sending is a complete mess and has a non-public info in it. I’ll try to clean it up and open the source for it. Need to parameterize some of the non-public (but not a high value secret or anything) info. 
 I am blasting the DMs, and they go out but none of them are seen by the client. My conclusion is that nip17 sucks ass, and only focuses on solving c2c but not s2c problem. I cannot have DMs sent to a specific relay, I don’t know who is using what and when, I need for DMs to reach the recipient and for me to do not need to know about their nprofile or anything else besides their npub, I cannot rely on any relay to have any info about any npub, I need to send it fast and with no WS fuss that is client oriented shit. So many complaints 😭😭😭😅 
 This took me way longer than I would have liked, but here is the working Typescript code that makes those god damn GW DMs.

// Create DM event
export async function creatNIP17DMEvent(
  fromSk: string,
  toNpub: string,
  dm: string[],
): Promise<Array<Event>> {
  const skBuff = hexToBytes(fromSk)
  const events: Array<Event> = []

  while (dm.length > 0) {
    const msg = dm.shift()
    if (msg)
      events.push(createNip17Wraps(msg, toNpub, skBuff))
  }

  return events
}

function getNow(): number {
  return Math.floor(Date.now() / 1000)
}

function getRandomNow(): number {
  return getNow() - Math.floor(Math.random() * 172800)
}

function nip44Encrypt(rumor: Rumor, privateKey: Uint8Array, publicKey: string): string {
  const key = nip44.v2.utils.getConversationKey(privateKey, publicKey)
  return nip44.v2.encrypt(JSON.stringify(rumor), key)
}

function createWrap(event: Event, recipientPublicKey: string): Event {
  // Get random secret key to wrap the event
  const randomSK = generateSecretKey()
  return finalizeEvent({
    kind: 1059, // Gift wrapped event
    content: nip44Encrypt(event, randomSK, recipientPublicKey),
    created_at: getRandomNow(),
    tags: [["p", recipientPublicKey]]
  }, randomSK) as Event
}

function createSeal(event: Rumor, privateKey: Uint8Array, recipientPublicKey: string): Event {
  return finalizeEvent({
    kind: 13, // Seal
    content: nip44Encrypt(event, privateKey, recipientPublicKey),
    created_at: getRandomNow(),
    tags: []
  }, privateKey)
}

function createRumor(message: string, senderPubkey: string, receiverPubkey: string): Rumor {
  const rumor = {
    kind: 14, // As per specs, should be Kind 14 event
    content: message,
    pubkey: senderPubkey,
    created_at: getNow(),
    tags: [["p", receiverPubkey]],
  } as Rumor
  rumor.id = getEventHash(rumor)
  return rumor
}

function createNip17Wraps(message: string, recipientPublicKey: string, senderSk: Uint8Array): Event {
  const senderPubkey = getPublicKey(senderSk)
  return createWrap(
    createSeal(
      createRumor(message, senderPubkey, recipientPublicKey),
      senderSk, recipientPublicKey),
    recipientPublicKey)
} 
 One fix for types:

function nip44Encrypt(rumor: Rumor | VerifiedEvent, privateKey: Uint8Array, publicKey: string): string {
  const key = nip44.v2.utils.getConversationKey(privateKey, publicKey)
  return nip44.v2.encrypt(JSON.stringify(rumor), key)
}


It does not have any impact, just cosmetics 
 Yeah! I do suggest to make a clear documentation about how it should be done, I will contribute if needed. It is super confusing now and no single NIP to look at 🫂😭 
 I should add nip40 expiration to the wrap too I think, if the event is OTP 
 GM🫡☕️☕️☕️ 
 GM! 🫂☕️🙏🏻 
 GM🫂☕️🙏🏻 
 💡 What is the NEXT feature would you like to see in our products?


-------------
#AlbyHub
#Al... 
 Wen? 😂🤣🙏🏻🫂