damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 87860a71516dd9bcb9617e85c33d86e5ab1e1cbe
parent ad75d8546c40ebabf0a23f3a745aaae66e1063fa
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Wed, 15 Nov 2023 18:09:28 -0800

Make NostrDB (and related) code build under the new extension target as well.

This change includes several source files related to NostrDB into the extension target as well, so that we can use it from that context (and thus enable more advanced push notification formatting and suppression)

To make this change possible, I had to split some source files as well as to move some functions to different files, to ensure we don't have to pull too much unnecessary code into the extension.

Testing
-------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Test steps:
1. Build DamusNotificationService. Should succeed. PASS
2. Build Damus (the app). PASS
3. Run app, scroll around some notes, go to a few different views, post a note. Should work as normal. PASS

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 174+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mdamus/Models/EventRef.swift | 1-
Mdamus/Models/Mentions.swift | 5-----
Adamus/Nostr/NostrEvent+.swift | 180+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Nostr/NostrEvent.swift | 214++-----------------------------------------------------------------------------
Mdamus/Types/Block.swift | 6++++++
Adamus/Types/MigratedTypes.swift | 11+++++++++++
Mdamus/Util/DisplayName.swift | 4++++
Mdamus/Views/DMChatView.swift | 5-----
Mdamus/Views/NoteContentView.swift | 13+++++++++++++
Mdamus/Views/PubkeyView.swift | 4----
Anostrdb/NdbNote+.swift | 30++++++++++++++++++++++++++++++
Mnostrdb/NdbNote.swift | 48+++++++++++++++++++-----------------------------
13 files changed, 438 insertions(+), 257 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -445,10 +445,89 @@ D7870BC12AC4750B0080BA88 /* MentionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7870BC02AC4750B0080BA88 /* MentionView.swift */; }; D7870BC32AC47EBC0080BA88 /* EventLoaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7870BC22AC47EBC0080BA88 /* EventLoaderView.swift */; }; D789D1202AFEFBF20083A7AB /* secp256k1 in Frameworks */ = {isa = PBXBuildFile; productRef = D789D11F2AFEFBF20083A7AB /* secp256k1 */; }; + D798D21A2B0856CC00234419 /* Mentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7FF7D42823313F009601DB /* Mentions.swift */; }; + D798D21B2B0856F200234419 /* NdbTagsIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDD1AE12A6B3074001CD4DF /* NdbTagsIterator.swift */; }; + D798D21C2B0857E400234419 /* Bech32Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABEF29857E9200D66079 /* Bech32Object.swift */; }; + D798D21E2B0858BB00234419 /* MigratedTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D21D2B0858BB00234419 /* MigratedTypes.swift */; }; + D798D21F2B0858D600234419 /* MigratedTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D21D2B0858BB00234419 /* MigratedTypes.swift */; }; + D798D2202B08592000234419 /* NdbTagIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9054882A6AED4700811EEC /* NdbTagIterator.swift */; }; + D798D2212B08594800234419 /* NdbTagElem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDD1ADF2A6B305F001CD4DF /* NdbTagElem.swift */; }; + D798D2222B08598A00234419 /* ReferencedId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C28A4112A6D03D200C1A7A5 /* ReferencedId.swift */; }; + D798D2232B0859B700234419 /* KeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C7F2A0220E1001AFC1D /* KeychainStorage.swift */; }; + D798D2242B0859C900234419 /* LocalizationUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3040F029A8FF97008A0F29 /* LocalizationUtil.swift */; }; + D798D2252B0859D700234419 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A93282704FA006E126D /* Post.swift */; }; + D798D2262B085C4200234419 /* Bech32.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90BD19283AA67F008EE7EF /* Bech32.swift */; }; + D798D2282B085CDA00234419 /* NdbNote+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D2272B085CDA00234419 /* NdbNote+.swift */; }; + D798D2292B08686C00234419 /* ContentParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4DD3DA2A6CA7E8005B4E85 /* ContentParsing.swift */; }; + D798D22C2B086C7400234419 /* NostrEvent+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D22B2B086C7400234419 /* NostrEvent+.swift */; }; + D798D22D2B086DC400234419 /* NostrEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB228049D640006080F /* NostrEvent.swift */; }; + D798D22E2B086E4800234419 /* NostrResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB028049D510006080F /* NostrResponse.swift */; }; D79C4C172AFEB061003A41B4 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79C4C162AFEB061003A41B4 /* NotificationService.swift */; }; D79C4C1B2AFEB061003A41B4 /* DamusNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D79C4C142AFEB061003A41B4 /* DamusNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; D7A343EE2AD0D77C00CED48B /* InlineSnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = D7A343ED2AD0D77C00CED48B /* InlineSnapshotTesting */; }; D7A343F02AD0D77C00CED48B /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = D7A343EF2AD0D77C00CED48B /* SnapshotTesting */; }; + D7CCFC072B05833200323D86 /* NdbNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90548A2A6AEDEE00811EEC /* NdbNote.swift */; }; + D7CCFC082B05834500323D86 /* NoteId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FF42A740BB7007AEB17 /* NoteId.swift */; }; + D7CCFC0B2B0585EA00323D86 /* nostrdb.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CE9FBB82A6B3B26007E485C /* nostrdb.c */; settings = {COMPILER_FLAGS = "-w"; }; }; + D7CCFC0E2B0587C300323D86 /* EventRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A9B282838B9006E126D /* EventRef.swift */; }; + D7CCFC0F2B0587F600323D86 /* Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8B28398BC6008A31F1 /* Keys.swift */; }; + D7CCFC102B05880F00323D86 /* Id.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C2B7BF12A71B6540049DEE7 /* Id.swift */; }; + D7CCFC112B05884E00323D86 /* AsciiCharacter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C5D5C9C2A6B2CB40024563C /* AsciiCharacter.swift */; }; + D7CCFC122B05886D00323D86 /* IdType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FEE2A73FCCB007AEB17 /* IdType.swift */; }; + D7CCFC132B05887C00323D86 /* ProofOfWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFBA2804A34C0006080F /* ProofOfWork.swift */; }; + D7CCFC152B05891000323D86 /* Referenced.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FF82A741939007AEB17 /* Referenced.swift */; }; + D7CCFC162B05894300323D86 /* Pubkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FF02A73FCDB007AEB17 /* Pubkey.swift */; }; + D7CCFC192B058A3F00323D86 /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7527271D2A93FF0100214108 /* Block.swift */; }; + D7CE1B182B0BDFDD002EDAD4 /* mdb.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4793002A993B9A00489948 /* mdb.c */; }; + D7CE1B192B0BE132002EDAD4 /* builder.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4792942A9939BD00489948 /* builder.c */; }; + D7CE1B1A2B0BE135002EDAD4 /* json_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4792C82A9939BD00489948 /* json_parser.c */; }; + D7CE1B1B2B0BE144002EDAD4 /* emitter.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4792CF2A9939BD00489948 /* emitter.c */; }; + D7CE1B1C2B0BE147002EDAD4 /* refmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4792D12A9939BD00489948 /* refmap.c */; }; + D7CE1B1D2B0BE14A002EDAD4 /* verifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4792D42A9939BD00489948 /* verifier.c */; }; + D7CE1B1E2B0BE190002EDAD4 /* midl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4793032A993DB900489948 /* midl.c */; }; + D7CE1B1F2B0BE1B8002EDAD4 /* damus.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670A28FDE64700038D2A /* damus.c */; }; + D7CE1B202B0BE1C8002EDAD4 /* error.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C9146FF2A2A891E00DDEA40 /* error.c */; }; + D7CE1B212B0BE1CB002EDAD4 /* wasm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CA9276E2A2A5D110098A105 /* wasm.c */; }; + D7CE1B222B0BE1EB002EDAD4 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670D28FDEAA000038D2A /* utf8.c */; }; + D7CE1B232B0BE1EE002EDAD4 /* bolt11.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA63C28FF52D600C48A62 /* bolt11.c */; }; + D7CE1B242B0BE1F1002EDAD4 /* hash_u5.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA64028FF553900C48A62 /* hash_u5.c */; }; + D7CE1B252B0BE1F4002EDAD4 /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA64328FF558100C48A62 /* sha256.c */; }; + D7CE1B262B0BE1F8002EDAD4 /* bech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA64828FF597700C48A62 /* bech32.c */; }; + D7CE1B272B0BE224002EDAD4 /* bech32_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA64B28FF59AC00C48A62 /* bech32_util.c */; }; + D7CE1B282B0BE226002EDAD4 /* tal.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA64E28FF59F200C48A62 /* tal.c */; }; + D7CE1B292B0BE239002EDAD4 /* node_id.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA65F28FF5E7700C48A62 /* node_id.c */; }; + D7CE1B2A2B0BE23E002EDAD4 /* mem.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA66428FF5F6800C48A62 /* mem.c */; }; + D7CE1B2B2B0BE243002EDAD4 /* hex.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA66728FF5F9900C48A62 /* hex.c */; }; + D7CE1B2C2B0BE24B002EDAD4 /* amount.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA66C28FF782800C48A62 /* amount.c */; }; + D7CE1B2D2B0BE250002EDAD4 /* take.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67428FF7A5A00C48A62 /* take.c */; }; + D7CE1B2E2B0BE25C002EDAD4 /* talstr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67628FF7A9800C48A62 /* talstr.c */; }; + D7CE1B2F2B0BE260002EDAD4 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67828FF7ABF00C48A62 /* list.c */; }; + D7CE1B302B0BE263002EDAD4 /* nostr_bech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00CE29E38B950036AF10 /* nostr_bech32.c */; }; + D7CE1B312B0BE69D002EDAD4 /* Ndb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C478E242A9932C100489948 /* Ndb.swift */; }; + D7CE1B322B0BE6C3002EDAD4 /* NdbTxn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3DCC752A9FC2030091E592 /* NdbTxn.swift */; }; + D7CE1B332B0BE6DE002EDAD4 /* Nostr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA527FF87A20006080F /* Nostr.swift */; }; + D7CE1B342B0BE6EE002EDAD4 /* NdbProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C478E2C2A9935D300489948 /* NdbProfile.swift */; }; + D7CE1B352B0BE6FA002EDAD4 /* ByteBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9402A9AD44700DC3548 /* ByteBuffer.swift */; }; + D7CE1B362B0BE702002EDAD4 /* FbConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9372A9AD44700DC3548 /* FbConstants.swift */; }; + D7CE1B372B0BE719002EDAD4 /* Verifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93E2A9AD44700DC3548 /* Verifier.swift */; }; + D7CE1B382B0BE719002EDAD4 /* VeriferOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9432A9AD44700DC3548 /* VeriferOptions.swift */; }; + D7CE1B392B0BE719002EDAD4 /* Table.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9442A9AD44700DC3548 /* Table.swift */; }; + D7CE1B3A2B0BE719002EDAD4 /* Struct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B94B2A9AD44700DC3548 /* Struct.swift */; }; + D7CE1B3B2B0BE719002EDAD4 /* Int+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93A2A9AD44700DC3548 /* Int+extension.swift */; }; + D7CE1B3C2B0BE719002EDAD4 /* TableVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9412A9AD44700DC3548 /* TableVerifier.swift */; }; + D7CE1B3D2B0BE719002EDAD4 /* Verifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9452A9AD44700DC3548 /* Verifiable.swift */; }; + D7CE1B3E2B0BE719002EDAD4 /* FlatbuffersErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93C2A9AD44700DC3548 /* FlatbuffersErrors.swift */; }; + D7CE1B3F2B0BE719002EDAD4 /* Enum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B94A2A9AD44700DC3548 /* Enum.swift */; }; + D7CE1B402B0BE719002EDAD4 /* FlatBufferObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9492A9AD44700DC3548 /* FlatBufferObject.swift */; }; + D7CE1B412B0BE719002EDAD4 /* FlatBuffersUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93F2A9AD44700DC3548 /* FlatBuffersUtils.swift */; }; + D7CE1B422B0BE719002EDAD4 /* Offset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9382A9AD44700DC3548 /* Offset.swift */; }; + D7CE1B432B0BE719002EDAD4 /* String+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9472A9AD44700DC3548 /* String+extension.swift */; }; + D7CE1B442B0BE719002EDAD4 /* Mutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9392A9AD44700DC3548 /* Mutable.swift */; }; + D7CE1B452B0BE719002EDAD4 /* Root.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9422A9AD44700DC3548 /* Root.swift */; }; + D7CE1B462B0BE719002EDAD4 /* FlatBufferBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93B2A9AD44700DC3548 /* FlatBufferBuilder.swift */; }; + D7CE1B472B0BE719002EDAD4 /* NativeObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9462A9AD44700DC3548 /* NativeObject.swift */; }; + D7CE1B482B0BE719002EDAD4 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93D2A9AD44700DC3548 /* Message.swift */; }; + D7CE1B492B0BE729002EDAD4 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; }; D7DBD41F2B02F15E002A6197 /* NostrKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD32819DE8F00B3DE84 /* NostrKind.swift */; }; D7DBD4202B0307C7002A6197 /* NostrEventInfoFromPushNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A3B182B02DD2D008BD568 /* NostrEventInfoFromPushNotification.swift */; }; D7DEEF2F2A8C021E00E0C99F /* NostrEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */; }; @@ -1173,6 +1252,9 @@ D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = "<group>"; }; D7870BC02AC4750B0080BA88 /* MentionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionView.swift; sourceTree = "<group>"; }; D7870BC22AC47EBC0080BA88 /* EventLoaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventLoaderView.swift; sourceTree = "<group>"; }; + D798D21D2B0858BB00234419 /* MigratedTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigratedTypes.swift; sourceTree = "<group>"; }; + D798D2272B085CDA00234419 /* NdbNote+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NdbNote+.swift"; sourceTree = "<group>"; }; + D798D22B2B086C7400234419 /* NostrEvent+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NostrEvent+.swift"; sourceTree = "<group>"; }; D79C4C142AFEB061003A41B4 /* DamusNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = DamusNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D79C4C162AFEB061003A41B4 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; }; D79C4C182AFEB061003A41B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; @@ -1797,6 +1879,7 @@ 4C28A4112A6D03D200C1A7A5 /* ReferencedId.swift */, 4C2B7BF12A71B6540049DEE7 /* Id.swift */, D7FF93FF2AC7AC5200FD969D /* RelayURL.swift */, + D798D22B2B086C7400234419 /* NostrEvent+.swift */, ); path = Nostr; sourceTree = "<group>"; @@ -1929,6 +2012,7 @@ 4C78EFD72A707C4D007E8197 /* secp256k1_schnorrsig.h */, 4C78EFDA2A707C67007E8197 /* secp256k1_extrakeys.h */, 4C78EFD92A707C4D007E8197 /* secp256k1.h */, + D798D2272B085CDA00234419 /* NdbNote+.swift */, ); path = nostrdb; sourceTree = "<group>"; @@ -2061,6 +2145,7 @@ children = ( 4CC14FED2A73FCBB007AEB17 /* Ids */, 7527271D2A93FF0100214108 /* Block.swift */, + D798D21D2B0858BB00234419 /* MigratedTypes.swift */, ); path = Types; sourceTree = "<group>"; @@ -2702,6 +2787,7 @@ 4C5C7E68284ED36500A22DF5 /* SearchHomeModel.swift in Sources */, 4C54AA0C29A5543C003E4487 /* ZapGroup.swift in Sources */, 4C190F202A535FC200027FD5 /* CustomizeZapModel.swift in Sources */, + D798D22C2B086C7400234419 /* NostrEvent+.swift in Sources */, 4C75EFB728049D990006080F /* RelayPool.swift in Sources */, F757933A29D7AECD007DEAC1 /* ImagePicker.swift in Sources */, 4CF0ABEE29844B5500D66079 /* AnyEncodable.swift in Sources */, @@ -2717,6 +2803,7 @@ D7870BC12AC4750B0080BA88 /* MentionView.swift in Sources */, 4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */, 4C363AA228296A7E006E126D /* SearchView.swift in Sources */, + D798D2282B085CDA00234419 /* NdbNote+.swift in Sources */, 4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */, 4C1253662A76D0FF0004F4B8 /* OnlyZapsNotify.swift in Sources */, 4CA927652A290F1A0098A105 /* TimeDot.swift in Sources */, @@ -2835,6 +2922,7 @@ D7315A2A2ACDF3B70036E30A /* DamusCacheManager.swift in Sources */, 4C7D09682A0AE9B200943473 /* NWCScannerView.swift in Sources */, 4CA352A42A76AFF3003BB08B /* UpdateStatsNotify.swift in Sources */, + D798D21E2B0858BB00234419 /* MigratedTypes.swift in Sources */, 4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */, 4C2B7BF22A71B6540049DEE7 /* Id.swift in Sources */, 7C95CAEE299DCEF1009DCB67 /* KFOptionSetter+.swift in Sources */, @@ -3126,10 +3214,86 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D798D21F2B0858D600234419 /* MigratedTypes.swift in Sources */, + D7CE1B472B0BE719002EDAD4 /* NativeObject.swift in Sources */, + D7CCFC0E2B0587C300323D86 /* EventRef.swift in Sources */, + D7CCFC192B058A3F00323D86 /* Block.swift in Sources */, + D7CCFC112B05884E00323D86 /* AsciiCharacter.swift in Sources */, + D798D2202B08592000234419 /* NdbTagIterator.swift in Sources */, + D7CE1B1D2B0BE14A002EDAD4 /* verifier.c in Sources */, + D7CE1B1F2B0BE1B8002EDAD4 /* damus.c in Sources */, + D7CE1B1B2B0BE144002EDAD4 /* emitter.c in Sources */, + D798D21C2B0857E400234419 /* Bech32Object.swift in Sources */, + D7CE1B402B0BE719002EDAD4 /* FlatBufferObject.swift in Sources */, + D7CE1B442B0BE719002EDAD4 /* Mutable.swift in Sources */, + D798D2212B08594800234419 /* NdbTagElem.swift in Sources */, + D7CE1B432B0BE719002EDAD4 /* String+extension.swift in Sources */, + D7CE1B1C2B0BE147002EDAD4 /* refmap.c in Sources */, + D7CE1B242B0BE1F1002EDAD4 /* hash_u5.c in Sources */, D79C4C172AFEB061003A41B4 /* NotificationService.swift in Sources */, + D7CE1B362B0BE702002EDAD4 /* FbConstants.swift in Sources */, + D7CE1B222B0BE1EB002EDAD4 /* utf8.c in Sources */, + D7CCFC072B05833200323D86 /* NdbNote.swift in Sources */, + D7CE1B3F2B0BE719002EDAD4 /* Enum.swift in Sources */, + D7CE1B422B0BE719002EDAD4 /* Offset.swift in Sources */, + D7CE1B232B0BE1EE002EDAD4 /* bolt11.c in Sources */, + D7CE1B182B0BDFDD002EDAD4 /* mdb.c in Sources */, + D7CCFC162B05894300323D86 /* Pubkey.swift in Sources */, + D7CE1B292B0BE239002EDAD4 /* node_id.c in Sources */, + D7CE1B2E2B0BE25C002EDAD4 /* talstr.c in Sources */, + D798D2292B08686C00234419 /* ContentParsing.swift in Sources */, D70A3B192B02DD2D008BD568 /* NostrEventInfoFromPushNotification.swift in Sources */, + D798D2242B0859C900234419 /* LocalizationUtil.swift in Sources */, + D7CE1B322B0BE6C3002EDAD4 /* NdbTxn.swift in Sources */, + D7CE1B372B0BE719002EDAD4 /* Verifier.swift in Sources */, + D798D21A2B0856CC00234419 /* Mentions.swift in Sources */, + D7CE1B212B0BE1CB002EDAD4 /* wasm.c in Sources */, + D7CE1B3B2B0BE719002EDAD4 /* Int+extension.swift in Sources */, + D7CCFC0B2B0585EA00323D86 /* nostrdb.c in Sources */, + D7CE1B252B0BE1F4002EDAD4 /* sha256.c in Sources */, + D7CE1B262B0BE1F8002EDAD4 /* bech32.c in Sources */, + D798D21B2B0856F200234419 /* NdbTagsIterator.swift in Sources */, + D7CE1B352B0BE6FA002EDAD4 /* ByteBuffer.swift in Sources */, + D7CE1B2F2B0BE260002EDAD4 /* list.c in Sources */, + D7CE1B342B0BE6EE002EDAD4 /* NdbProfile.swift in Sources */, D7DBD41F2B02F15E002A6197 /* NostrKind.swift in Sources */, + D7CE1B3C2B0BE719002EDAD4 /* TableVerifier.swift in Sources */, + D7CCFC082B05834500323D86 /* NoteId.swift in Sources */, + D7CE1B1A2B0BE135002EDAD4 /* json_parser.c in Sources */, + D798D2252B0859D700234419 /* Post.swift in Sources */, + D7CCFC0F2B0587F600323D86 /* Keys.swift in Sources */, + D798D2232B0859B700234419 /* KeychainStorage.swift in Sources */, + D7CE1B272B0BE224002EDAD4 /* bech32_util.c in Sources */, + D7CCFC102B05880F00323D86 /* Id.swift in Sources */, + D7CE1B2A2B0BE23E002EDAD4 /* mem.c in Sources */, + D7CE1B332B0BE6DE002EDAD4 /* Nostr.swift in Sources */, + D7CE1B3D2B0BE719002EDAD4 /* Verifiable.swift in Sources */, + D7CE1B382B0BE719002EDAD4 /* VeriferOptions.swift in Sources */, + D7CCFC152B05891000323D86 /* Referenced.swift in Sources */, + D7CE1B2B2B0BE243002EDAD4 /* hex.c in Sources */, + D798D2222B08598A00234419 /* ReferencedId.swift in Sources */, + D7CE1B492B0BE729002EDAD4 /* DisplayName.swift in Sources */, + D7CE1B192B0BE132002EDAD4 /* builder.c in Sources */, + D7CE1B282B0BE226002EDAD4 /* tal.c in Sources */, + D7CCFC122B05886D00323D86 /* IdType.swift in Sources */, + D7CE1B312B0BE69D002EDAD4 /* Ndb.swift in Sources */, + D7CE1B3A2B0BE719002EDAD4 /* Struct.swift in Sources */, D70A3B172B02DCE5008BD568 /* NotificationFormatter.swift in Sources */, + D7CE1B462B0BE719002EDAD4 /* FlatBufferBuilder.swift in Sources */, + D7CE1B3E2B0BE719002EDAD4 /* FlatbuffersErrors.swift in Sources */, + D7CE1B2C2B0BE24B002EDAD4 /* amount.c in Sources */, + D7CE1B202B0BE1C8002EDAD4 /* error.c in Sources */, + D798D22D2B086DC400234419 /* NostrEvent.swift in Sources */, + D798D22E2B086E4800234419 /* NostrResponse.swift in Sources */, + D7CE1B302B0BE263002EDAD4 /* nostr_bech32.c in Sources */, + D7CCFC132B05887C00323D86 /* ProofOfWork.swift in Sources */, + D7CE1B392B0BE719002EDAD4 /* Table.swift in Sources */, + D7CE1B452B0BE719002EDAD4 /* Root.swift in Sources */, + D7CE1B412B0BE719002EDAD4 /* FlatBuffersUtils.swift in Sources */, + D798D2262B085C4200234419 /* Bech32.swift in Sources */, + D7CE1B482B0BE719002EDAD4 /* Message.swift in Sources */, + D7CE1B1E2B0BE190002EDAD4 /* midl.c in Sources */, + D7CE1B2D2B0BE250002EDAD4 /* take.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3566,13 +3730,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CODE_SIGN_ENTITLEMENTS = DamusNotificationService/DamusNotificationService.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = XK7H4JAB3D; ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = DamusNotificationService/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = DamusNotificationService; @@ -3591,6 +3755,7 @@ SUPPORTS_MACCATALYST = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "damus-c/damus-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -3600,13 +3765,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CODE_SIGN_ENTITLEMENTS = DamusNotificationService/DamusNotificationService.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = XK7H4JAB3D; ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = DamusNotificationService/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = DamusNotificationService; @@ -3624,6 +3789,7 @@ SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = YES; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "damus-c/damus-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/damus/Models/EventRef.swift b/damus/Models/EventRef.swift @@ -145,4 +145,3 @@ func event_is_reply(_ refs: [EventRef]) -> Bool { return evref.is_reply != nil } } - diff --git a/damus/Models/Mentions.swift b/damus/Models/Mentions.swift @@ -123,11 +123,6 @@ struct LightningInvoice<T> { } } -struct Blocks: Equatable { - let words: Int - let blocks: [Block] -} - func maybe_pointee<T>(_ p: UnsafeMutablePointer<T>!) -> T? { guard p != nil else { return nil diff --git a/damus/Nostr/NostrEvent+.swift b/damus/Nostr/NostrEvent+.swift @@ -0,0 +1,180 @@ +// +// NostrEvent+.swift +// damus +// +// Created by Daniel D’Aquino on 2023-11-17. +// + +import Foundation + +func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? { + var tags = zap_target_to_tags(target) + var relay_tag = ["relays"] + relay_tag.append(contentsOf: relays.map { $0.url.id }) + tags.append(relay_tag) + + var kp = keypair + + let now = UInt32(Date().timeIntervalSince1970) + + var privzap_req: PrivateZapRequest? + + var message = content + switch zap_type { + case .pub: + break + case .non_zap: + break + case .anon: + tags.append(["anon"]) + kp = generate_new_keypair() + case .priv: + guard let priv_kp = generate_private_keypair(our_privkey: keypair.privkey, id: NoteId(target.id), created_at: now) else { + return nil + } + kp = priv_kp + guard let privreq = make_private_zap_request_event(identity: keypair, enc_key: kp, target: target, message: message) else { + return nil + } + tags.append(["anon", privreq.enc]) + message = "" + privzap_req = privreq + } + + guard let ev = NostrEvent(content: message, keypair: kp.to_keypair(), kind: 9734, tags: tags, createdAt: now) else { + return nil + } + let zapreq = ZapRequest(ev: ev) + if let privzap_req { + return .priv(zapreq, privzap_req) + } else { + return .normal(zapreq) + } +} + +func zap_target_to_tags(_ target: ZapTarget) -> [[String]] { + switch target { + case .profile(let pk): + return [["p", pk.hex()]] + case .note(let note_target): + return [["e", note_target.note_id.hex()], + ["p", note_target.author.hex()]] + } +} + +struct PrivateZapRequest { + let req: ZapRequest + let enc: String +} + +func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> PrivateZapRequest? { + // target tags must be the same as zap request target tags + let tags = zap_target_to_tags(target) + + guard let note = NostrEvent(content: message, keypair: identity.to_keypair(), kind: 9733, tags: tags), + let note_json = encode_json(note), + let enc = encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32) + else { + return nil + } + + return PrivateZapRequest(req: ZapRequest(ev: note), enc: enc) +} + +func decrypt_private_zap(our_privkey: Privkey, zapreq: NostrEvent, target: ZapTarget) -> NostrEvent? { + guard let anon_tag = zapreq.tags.first(where: { t in + t.count >= 2 && t[0].matches_str("anon") + }) else { + return nil + } + + let enc_note = anon_tag[1].string() + + var note = decrypt_note(our_privkey: our_privkey, their_pubkey: zapreq.pubkey, enc_note: enc_note, encoding: .bech32) + + // check to see if the private note was from us + if note == nil { + guard let our_private_keypair = generate_private_keypair(our_privkey: our_privkey, id: NoteId(target.id), created_at: zapreq.created_at) else { + return nil + } + // use our private keypair and their pubkey to get the shared secret + note = decrypt_note(our_privkey: our_private_keypair.privkey, their_pubkey: target.pubkey, enc_note: enc_note, encoding: .bech32) + } + + guard let note else { + return nil + } + + guard note.kind == 9733 else { + return nil + } + + let zr_etag = zapreq.referenced_ids.first + let note_etag = note.referenced_ids.first + + guard zr_etag == note_etag else { + return nil + } + + let zr_ptag = zapreq.referenced_pubkeys.first + let note_ptag = note.referenced_pubkeys.first + + guard let zr_ptag, let note_ptag, zr_ptag == note_ptag else { + return nil + } + + guard validate_event(ev: note) == .ok else { + return nil + } + + return note +} + +enum MakeZapRequest { + case priv(ZapRequest, PrivateZapRequest) + case normal(ZapRequest) + + var private_inner_request: ZapRequest { + switch self { + case .priv(_, let pzr): + return pzr.req + case .normal(let zr): + return zr + } + } + + var potentially_anon_outer_request: ZapRequest { + switch self { + case .priv(let zr, _): + return zr + case .normal(let zr): + return zr + } + } +} + +func make_first_contact_event(keypair: Keypair) -> NostrEvent? { + let bootstrap_relays = load_bootstrap_relays(pubkey: keypair.pubkey) + let rw_relay_info = RelayInfo(read: true, write: true) + var relays: [String: RelayInfo] = [:] + + for relay in bootstrap_relays { + relays[relay] = rw_relay_info + } + + let relay_json = encode_json(relays)! + let damus_pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681" + let tags = [ + ["p", damus_pubkey], + ["p", keypair.pubkey.hex()] // you're a friend of yourself! + ] + return NostrEvent(content: relay_json, keypair: keypair, kind: NostrKind.contacts.rawValue, tags: tags) +} + +func make_metadata_event(keypair: FullKeypair, metadata: Profile) -> NostrEvent? { + guard let metadata_json = encode_json(metadata) else { + return nil + } + return NostrEvent(content: metadata_json, keypair: keypair.to_keypair(), kind: NostrKind.metadata.rawValue, tags: []) + +} diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift @@ -20,17 +20,6 @@ enum ValidationResult: Decodable { case bad_sig } -typealias NostrEvent = NdbNote -typealias TagElem = NdbTagElem -typealias Tag = TagSequence -typealias Tags = TagsSequence -//typealias TagElem = String -//typealias Tag = [TagElem] -//typealias Tags = [Tag] -//typealias NostrEvent = NostrEventOld - -let MAX_NOTE_SIZE: Int = 2 << 18 - /* class NostrEventOld: Codable, Identifiable, CustomStringConvertible, Equatable, Hashable, Comparable { // TODO: memory mapped db events @@ -427,19 +416,6 @@ func hexchar(_ val: UInt8) -> UInt8 { return 0 } - -func hex_encode(_ data: Data) -> String { - var str = "" - for c in data { - let c1 = hexchar(c >> 4) - let c2 = hexchar(c & 0xF) - - str.append(Character(Unicode.Scalar(c1))) - str.append(Character(Unicode.Scalar(c2))) - } - return str -} - func random_bytes(count: Int) -> Data { var bytes = [Int8](repeating: 0, count: count) guard @@ -450,32 +426,6 @@ func random_bytes(count: Int) -> Data { return Data(bytes: bytes, count: count) } -func make_first_contact_event(keypair: Keypair) -> NostrEvent? { - let bootstrap_relays = load_bootstrap_relays(pubkey: keypair.pubkey) - let rw_relay_info = RelayInfo(read: true, write: true) - var relays: [String: RelayInfo] = [:] - - for relay in bootstrap_relays { - relays[relay] = rw_relay_info - } - - let relay_json = encode_json(relays)! - let damus_pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681" - let tags = [ - ["p", damus_pubkey], - ["p", keypair.pubkey.hex()] // you're a friend of yourself! - ] - return NostrEvent(content: relay_json, keypair: keypair, kind: NostrKind.contacts.rawValue, tags: tags) -} - -func make_metadata_event(keypair: FullKeypair, metadata: Profile) -> NostrEvent? { - guard let metadata_json = encode_json(metadata) else { - return nil - } - return NostrEvent(content: metadata_json, keypair: keypair.to_keypair(), kind: NostrKind.metadata.rawValue, tags: []) - -} - func make_boost_event(keypair: FullKeypair, boosted: NostrEvent) -> NostrEvent? { var tags = Array(boosted.referenced_pubkeys).map({ pk in pk.tag }) @@ -501,84 +451,6 @@ func make_like_event(keypair: FullKeypair, liked: NostrEvent, content: String = return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 7, tags: tags) } -func zap_target_to_tags(_ target: ZapTarget) -> [[String]] { - switch target { - case .profile(let pk): - return [["p", pk.hex()]] - case .note(let note_target): - return [["e", note_target.note_id.hex()], - ["p", note_target.author.hex()]] - } -} - -struct PrivateZapRequest { - let req: ZapRequest - let enc: String -} - -func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> PrivateZapRequest? { - // target tags must be the same as zap request target tags - let tags = zap_target_to_tags(target) - - guard let note = NostrEvent(content: message, keypair: identity.to_keypair(), kind: 9733, tags: tags), - let note_json = encode_json(note), - let enc = encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32) - else { - return nil - } - - return PrivateZapRequest(req: ZapRequest(ev: note), enc: enc) -} - -func decrypt_private_zap(our_privkey: Privkey, zapreq: NostrEvent, target: ZapTarget) -> NostrEvent? { - guard let anon_tag = zapreq.tags.first(where: { t in - t.count >= 2 && t[0].matches_str("anon") - }) else { - return nil - } - - let enc_note = anon_tag[1].string() - - var note = decrypt_note(our_privkey: our_privkey, their_pubkey: zapreq.pubkey, enc_note: enc_note, encoding: .bech32) - - // check to see if the private note was from us - if note == nil { - guard let our_private_keypair = generate_private_keypair(our_privkey: our_privkey, id: NoteId(target.id), created_at: zapreq.created_at) else { - return nil - } - // use our private keypair and their pubkey to get the shared secret - note = decrypt_note(our_privkey: our_private_keypair.privkey, their_pubkey: target.pubkey, enc_note: enc_note, encoding: .bech32) - } - - guard let note else { - return nil - } - - guard note.kind == 9733 else { - return nil - } - - let zr_etag = zapreq.referenced_ids.first - let note_etag = note.referenced_ids.first - - guard zr_etag == note_etag else { - return nil - } - - let zr_ptag = zapreq.referenced_pubkeys.first - let note_ptag = note.referenced_pubkeys.first - - guard let zr_ptag, let note_ptag, zr_ptag == note_ptag else { - return nil - } - - guard validate_event(ev: note) == .ok else { - return nil - } - - return note -} - func generate_private_keypair(our_privkey: Privkey, id: NoteId, created_at: UInt32) -> FullKeypair? { let to_hash = our_privkey.hex() + id.hex() + String(created_at) guard let dat = to_hash.data(using: .utf8) else { @@ -591,74 +463,6 @@ func generate_private_keypair(our_privkey: Privkey, id: NoteId, created_at: UInt return FullKeypair(pubkey: pubkey, privkey: privkey) } -enum MakeZapRequest { - case priv(ZapRequest, PrivateZapRequest) - case normal(ZapRequest) - - var private_inner_request: ZapRequest { - switch self { - case .priv(_, let pzr): - return pzr.req - case .normal(let zr): - return zr - } - } - - var potentially_anon_outer_request: ZapRequest { - switch self { - case .priv(let zr, _): - return zr - case .normal(let zr): - return zr - } - } -} - -func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? { - var tags = zap_target_to_tags(target) - var relay_tag = ["relays"] - relay_tag.append(contentsOf: relays.map { $0.url.id }) - tags.append(relay_tag) - - var kp = keypair - - let now = UInt32(Date().timeIntervalSince1970) - - var privzap_req: PrivateZapRequest? - - var message = content - switch zap_type { - case .pub: - break - case .non_zap: - break - case .anon: - tags.append(["anon"]) - kp = generate_new_keypair() - case .priv: - guard let priv_kp = generate_private_keypair(our_privkey: keypair.privkey, id: NoteId(target.id), created_at: now) else { - return nil - } - kp = priv_kp - guard let privreq = make_private_zap_request_event(identity: keypair, enc_key: kp, target: target, message: message) else { - return nil - } - tags.append(["anon", privreq.enc]) - message = "" - privzap_req = privreq - } - - guard let ev = NostrEvent(content: message, keypair: kp.to_keypair(), kind: 9734, tags: tags, createdAt: now) else { - return nil - } - let zapreq = ZapRequest(ev: ev) - if let privzap_req { - return .priv(zapreq, privzap_req) - } else { - return .normal(zapreq) - } -} - func uniq<T: Hashable>(_ xs: [T]) -> [T] { var s = Set<T>() var ys: [T] = [] @@ -777,6 +581,11 @@ func get_shared_secret(privkey: Privkey, pubkey: Pubkey) -> [UInt8]? { return shared_secret } +enum EncEncoding { + case base64 + case bech32 +} + struct DirectMessageBase64 { let content: [UInt8] let iv: [UInt8] @@ -949,19 +758,6 @@ func first_eref_mention(ev: NostrEvent, keypair: Keypair) -> Mention<NoteId>? { return nil } -func separate_images(ev: NostrEvent, keypair: Keypair) -> [MediaUrl]? { - let urlBlocks: [URL] = ev.blocks(keypair).blocks.reduce(into: []) { urls, block in - guard case .url(let url) = block else { - return - } - if classify_url(url).is_img != nil { - urls.append(url) - } - } - let mediaUrls = urlBlocks.map { MediaUrl.image($0) } - return mediaUrls.isEmpty ? nil : mediaUrls -} - func separate_invoices(ev: NostrEvent, keypair: Keypair) -> [Invoice]? { let invoiceBlocks: [Invoice] = ev.blocks(keypair).blocks.reduce(into: []) { invoices, block in guard case .invoice(let invoice) = block else { diff --git a/damus/Types/Block.swift b/damus/Types/Block.swift @@ -45,6 +45,12 @@ enum Block: Equatable { case invoice(Invoice) case relay(String) } + +struct Blocks: Equatable { + let words: Int + let blocks: [Block] +} + extension Block { /// Failable initializer for the C-backed type `block_t`. This initializer will inspect /// the underlying block type and build the appropriate enum value as needed. diff --git a/damus/Types/MigratedTypes.swift b/damus/Types/MigratedTypes.swift @@ -0,0 +1,11 @@ +// +// MigratedTypes.swift +// damus +// +// Created by Daniel D’Aquino on 2023-11-17. +// + +typealias NostrEvent = NdbNote +typealias TagElem = NdbTagElem +typealias Tag = TagSequence +typealias Tags = TagsSequence diff --git a/damus/Util/DisplayName.swift b/damus/Util/DisplayName.swift @@ -57,3 +57,7 @@ func parse_display_name(profile: Profile?, pubkey: Pubkey) -> DisplayName { func abbrev_bech32_pubkey(pubkey: Pubkey) -> String { return abbrev_pubkey(String(pubkey.npub.dropFirst(4))) } + +func abbrev_pubkey(_ pubkey: String, amount: Int = 8) -> String { + return pubkey.prefix(amount) + ":" + pubkey.suffix(amount) +} diff --git a/damus/Views/DMChatView.swift b/damus/Views/DMChatView.swift @@ -186,11 +186,6 @@ struct DMChatView_Previews: PreviewProvider { } } -enum EncEncoding { - case base64 - case bech32 -} - func encrypt_message(message: String, privkey: Privkey, to_pk: Pubkey, encoding: EncEncoding = .base64) -> String? { let iv = random_bytes(count: 16).bytes guard let shared_sec = get_shared_secret(privkey: privkey, pubkey: to_pk) else { diff --git a/damus/Views/NoteContentView.swift b/damus/Views/NoteContentView.swift @@ -669,3 +669,16 @@ func count_markdown_words(blocks: [BlockNode]) -> Int { } } +func separate_images(ev: NostrEvent, keypair: Keypair) -> [MediaUrl]? { + let urlBlocks: [URL] = ev.blocks(keypair).blocks.reduce(into: []) { urls, block in + guard case .url(let url) = block else { + return + } + if classify_url(url).is_img != nil { + urls.append(url) + } + } + let mediaUrls = urlBlocks.map { MediaUrl.image($0) } + return mediaUrls.isEmpty ? nil : mediaUrls +} + diff --git a/damus/Views/PubkeyView.swift b/damus/Views/PubkeyView.swift @@ -89,7 +89,3 @@ struct PubkeyView: View { #Preview { PubkeyView(pubkey: test_pubkey) } - -func abbrev_pubkey(_ pubkey: String, amount: Int = 8) -> String { - return pubkey.prefix(amount) + ":" + pubkey.suffix(amount) -} diff --git a/nostrdb/NdbNote+.swift b/nostrdb/NdbNote+.swift @@ -0,0 +1,30 @@ +// +// NdbNote+.swift +// damus +// +// Created by Daniel D’Aquino on 2023-11-17. +// + +import Foundation + +// Extension to make NdbNote compatible with NostrEvent's original API +extension NdbNote { + private var inner_event: NdbNote? { + get { + return NdbNote.owned_from_json_cstr(json: content_raw, json_len: content_len) + } + } + + func get_inner_event(cache: EventCache) -> NdbNote? { + guard self.known_kind == .boost else { + return nil + } + + if self.content_len == 0, let id = self.referenced_ids.first { + // TODO: raw id cache lookups + return cache.lookup(id) + } + + return self.inner_event + } +} diff --git a/nostrdb/NdbNote.swift b/nostrdb/NdbNote.swift @@ -7,7 +7,12 @@ import Foundation import NaturalLanguage +import CommonCrypto +import secp256k1 +import secp256k1_implementation +import CryptoKit +let MAX_NOTE_SIZE: Int = 2 << 18 struct NdbStr { let note: NdbNote @@ -42,12 +47,7 @@ class NdbNote: Encodable, Equatable, Hashable { let note: UnsafeMutablePointer<ndb_note> // cached stuff (TODO: remove these) - private var _event_refs: [EventRef]? = nil var decrypted_content: String? = nil - private var _blocks: Blocks? = nil - private lazy var inner_event: NdbNote? = { - return NdbNote.owned_from_json_cstr(json: content_raw, json_len: content_len) - }() init(note: UnsafeMutablePointer<ndb_note>, owned_size: Int?, key: NoteKey?) { self.note = note @@ -252,8 +252,7 @@ class NdbNote: Encodable, Equatable, Hashable { } } - -// NostrEvent compat +// Extension to make NdbNote compatible with NostrEvent's original API extension NdbNote { var is_textlike: Bool { return kind == 1 || kind == 42 || kind == 30023 @@ -275,19 +274,6 @@ extension NdbNote { return parse_note_content(content: .init(note: self, keypair: keypair)) } - func get_inner_event(cache: EventCache) -> NostrEvent? { - guard self.known_kind == .boost else { - return nil - } - - if self.content_len == 0, let id = self.referenced_ids.first { - // TODO: raw id cache lookups - return cache.lookup(id) - } - - return self.inner_event - } - // TODO: References iterator public var referenced_ids: References<NoteId> { References<NoteId>(tags: self.tags) @@ -322,11 +308,7 @@ extension NdbNote { } func event_refs(_ keypair: Keypair) -> [EventRef] { - if let rs = _event_refs { - return rs - } let refs = interpret_event_refs_ndb(blocks: self.blocks(keypair).blocks, tags: self.tags) - self._event_refs = refs return refs } @@ -339,11 +321,7 @@ extension NdbNote { } func blocks(_ keypair: Keypair) -> Blocks { - if let bs = _blocks { return bs } - - let blocks = get_blocks(keypair: keypair) - self._blocks = blocks - return blocks + return get_blocks(keypair: keypair) } // NDBTODO: switch this to operating on bytes not strings @@ -448,3 +426,15 @@ extension NdbNote { return Date.now.timeIntervalSince(event_date) } } + +func hex_encode(_ data: Data) -> String { + var str = "" + for c in data { + let c1 = hexchar(c >> 4) + let c2 = hexchar(c & 0xF) + + str.append(Character(Unicode.Scalar(c1))) + str.append(Character(Unicode.Scalar(c2))) + } + return str +}