feat: add profile and contacts fetching from pubky#476
feat: add profile and contacts fetching from pubky#476ben-kaufman wants to merge 19 commits intomasterfrom
Conversation
ovitrif
left a comment
There was a problem hiding this comment.
LGTM with some nit comments.
all tests worked great, tested:
- open profile from topbar + drawer
- 2x auth successes
- button to download ring
- share pk button(s)
- signout button
This comment has been minimized.
This comment has been minimized.
ovitrif
left a comment
There was a problem hiding this comment.
tAck
Functionality-wise the new feature(s) work without any issues encountered while testing on my side.
I am approving the PR despite the conflicts, as you won't be able to merge before resolving them, thus to signal this perhaps still needs a review of the code by Philipp or Joao.
|
Looks pretty good for a first version, UI needs some polish and I think I saw some edge cases with not being authed for contacts despite it working for profile. Didn't look too deep yet, I'll continue review after conflicts are resolved, and I'll probably polish UI while at it. What are the plans for landing this, 2.2 is correct? |
| OnboardingView( | ||
| navTitle: t("slashtags__profile"), | ||
| title: t("slashtags__onboarding_profile1_header"), | ||
| description: t("slashtags__onboarding_profile1_text"), | ||
| imageName: "crown", | ||
| buttonText: t("common__continue"), | ||
| onButtonPress: { | ||
| app.hasSeenProfileIntro = true | ||
| navigation.navigate(.profile) | ||
| }, | ||
| imagePosition: .center, | ||
| testID: "ProfileIntro" | ||
| ) |
There was a problem hiding this comment.
What's the reason for not using OnboardingView? Looks like this screen has the standard layout and can use it.
| "slashtags__auth_depricated_title" = "Deprecated"; | ||
| "slashtags__auth_depricated_msg" = "Slashauth is deprecated. Please use Bitkit Beta."; | ||
| "profile__nav_title" = "Profile"; | ||
| "profile__intro_title" = "Portable\n<accent>pubky profile</accent>"; |
There was a problem hiding this comment.
| "profile__intro_title" = "Portable\n<accent>pubky profile</accent>"; | |
| "profile__intro_title" = "Portable\n<accent>pubky\nprofile</accent>"; |
| throw PubkyServiceError.invalidAuthUrl | ||
| } | ||
|
|
||
| let canOpen = await UIApplication.shared.canOpenURL(url) |
There was a problem hiding this comment.
unnecessary await
| let canOpen = await UIApplication.shared.canOpenURL(url) | |
| let canOpen = UIApplication.shared.canOpenURL(url) |
| CustomButton(title: t("profile__ring_download"), variant: .secondary) { | ||
| if let url = URL(string: pubkyRingAppStoreUrl) { | ||
| await UIApplication.shared.open(url) | ||
| } | ||
| } | ||
| .accessibilityIdentifier("PubkyRingDownload") | ||
|
|
||
| CustomButton( | ||
| title: t("profile__ring_authorize"), | ||
| isLoading: isAuthenticating | ||
| ) { | ||
| await authenticate() | ||
| } | ||
| .accessibilityIdentifier("PubkyRingAuthorize") |
There was a problem hiding this comment.
Could probably use UIApplication.shared.canOpenURL() to determine if Pubky Ring is installed and only show the relevant button.
| OnboardingView( | ||
| navTitle: t("slashtags__contacts"), | ||
| title: t("slashtags__onboarding_header"), | ||
| description: t("slashtags__onboarding_text"), | ||
| imageName: "group", | ||
| buttonText: t("slashtags__onboarding_button"), | ||
| onButtonPress: { | ||
| app.hasSeenContactsIntro = true | ||
| navigation.navigate(.contacts) | ||
| }, | ||
| imagePosition: .center, | ||
| testID: "ContactsIntro" | ||
| ) |
There was a problem hiding this comment.
Same here, why not use OnboardingView?
ef5107e to
82bbf45
Compare
|
Some observations (on version before force-push, as the current is not building):
Screen.Recording.2026-03-16.at.12.37.15.mov
|
Summary
Integrates Pubky decentralized identity into Bitkit, allowing users to connect their Pubky profile via Pubky Ring authentication. Once connected, the user's profile name and avatar appear on the home screen header, a full profile page shows their bio, links, and shareable QR code, and a contacts section lists people they follow on the Pubky network.
What's included
pubkyauth://) with relay-based session exchange, session persistence in Keychain, and automatic restoration on app launchPubkyService— service layer wrappingpaykit-ffi(profile/contacts/payments) andbitkit-core(auth relay, PKDNS file fetching)PubkyProfileManager— manages auth state, session lifecycle, and profile data with all FFI/Keychain/disk operations offloaded to background threadsContactsManager— fetches contacts in parallel viawithTaskGroup, groups them alphabetically, and resets on sign-outPubkyImagecomponent for loadingpubky://URIs with two-tier (memory + disk) cachingNew dependencies
paykit-rs(SPM, pinned revision) — Pubky SDK for profile, contacts, and payment operationsCoreBluetoothframework (linker flag, required by paykit-rs)New files
Services/PubkyService.swiftManagers/PubkyProfileManager.swiftManagers/ContactsManager.swiftModels/PubkyProfile.swiftComponents/PubkyImage.swiftpubky://image loader with disk+memory cacheViews/Profile/ProfileView.swiftViews/Profile/PubkyRingAuthView.swiftViews/Contacts/ContactsIntroView.swiftViews/Contacts/ContactsListView.swiftViews/Contacts/ContactDetailView.swiftModified files
AppScene.swiftPubkyProfileManagerandContactsManager, initialize Paykit early, eager-load contacts on authMainNavView.swiftHeader.swiftSuggestions.swiftQR.swift.task(id:)Info.plistLSApplicationQueriesSchemesforpubkyauth, ATS configKeychain.swiftpaykitSessionentry typeNavigationViewModel.swift.pubkyRingAuth,.contactsIntro,.contactDetail(publicKey:)routesProfileIntro.swiftColors.swiftpubkyBrandcolorLocalizable.stringsTest plan
ScreenRecording_03-04-2026.23-49-21_1.MP4