-
Notifications
You must be signed in to change notification settings - Fork 210
SELF-1754: Implement selective disclosure on Proving Screen #1549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
transphorm
merged 45 commits into
dev
from
justin/self-1754-proving-screen-selective-disclosure
Jan 9, 2026
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
f43a22c
add document selector test screen
transphorm bbe4aa5
clean up mock docs
transphorm 4ad10e6
update selection options
transphorm 1e3386f
Merge branch 'dev' into justin/self-1754-proving-screen-selective-dis…
transphorm a63f3ad
Merge branch 'dev' into justin/self-1754-proving-screen-selective-dis…
transphorm d28cf5a
Add DocumentSelectorForProving screen and route proof flows through i…
transphorm a6d4548
remove not accepted state
transphorm 191acca
save wip design
transphorm 3e7d6c6
formatting
transphorm b5ef1fd
update design
transphorm 4b45e2a
update layout
transphorm a54374a
Update proving flow tests (#1559)
transphorm 99d200e
Refactor ProveScreen to ProofRequestCard layout and preserve scroll p…
transphorm edac83b
wip fix tests
transphorm 8ea959d
fix tests
transphorm bacd36b
formatting
transphorm 69e7523
agent feedback
transphorm fccb65c
fix tests
transphorm 128b4fa
Merge branch 'dev' into justin/self-1754-proving-screen-selective-dis…
transphorm e54ba03
save wip
transphorm e7f8411
remove text
transphorm 2324023
fix types
transphorm 69c65e3
save working header update
transphorm 0fadd1f
no transition
transphorm 5fd9c5f
cache document load for proving flow
transphorm 75d1c7d
save fixes
transphorm f8b3c65
small fixes
transphorm 7f6d809
match disclosure text
transphorm cddd454
design updates
transphorm 9128ca0
fix approve flow
transphorm 256fcd8
fix document type flash
transphorm a472865
add min height so text doesn't jump
transphorm 9c37e85
update lock
transphorm 1cc7951
formatting
transphorm 0d4da72
save refactor wip
transphorm 6cd9d7a
don't enable euclid yet
transphorm 5cf025a
fix tests
transphorm 921c60e
fix staleness check
transphorm e559aca
fix select box description
transphorm c387940
remove id selector screen
transphorm e03508d
vertically center
transphorm 97698a0
button updates
transphorm 0953717
Remove proving document cache (#1567)
transphorm be9452f
Merge branch 'dev' into justin/self-1754-proving-screen-selective-dis…
transphorm 2526ac2
formatting
transphorm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| // SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. | ||
| // SPDX-License-Identifier: BUSL-1.1 | ||
| // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. | ||
|
|
||
| import { Pressable } from 'react-native'; | ||
| import { Separator, Text, View, XStack, YStack } from 'tamagui'; | ||
| import { Check, Circle } from '@tamagui/lucide-icons'; | ||
|
|
||
| import { | ||
| black, | ||
| slate300, | ||
| slate500, | ||
| } from '@selfxyz/mobile-sdk-alpha/constants/colors'; | ||
| import { dinot } from '@selfxyz/mobile-sdk-alpha/constants/fonts'; | ||
|
|
||
| export interface IDSelectorItemProps { | ||
| documentName: string; | ||
| state: IDSelectorState; | ||
| onPress?: () => void; | ||
| disabled?: boolean; | ||
| testID?: string; | ||
| } | ||
|
|
||
| export type IDSelectorState = | ||
| | 'active' | ||
| | 'verified' | ||
| | 'not_accepted' | ||
| | 'expired'; | ||
|
|
||
| const green500 = '#22C55E'; | ||
| const red500 = '#EF4444'; | ||
|
|
||
| function getSubtitleText(state: IDSelectorState): string { | ||
| switch (state) { | ||
| case 'active': | ||
| return 'Currently active'; | ||
| case 'verified': | ||
| return 'Verified ID'; | ||
| case 'not_accepted': | ||
| return 'Not accepted'; | ||
| case 'expired': | ||
| return 'Expired'; | ||
| } | ||
| } | ||
|
|
||
| function getSubtitleColor(state: IDSelectorState): string { | ||
| switch (state) { | ||
| case 'active': | ||
| return green500; | ||
| case 'verified': | ||
| return slate500; | ||
| case 'not_accepted': | ||
| return slate500; | ||
| case 'expired': | ||
| return red500; | ||
| } | ||
| } | ||
|
|
||
| function isDisabledState(state: IDSelectorState): boolean { | ||
| return state === 'not_accepted' || state === 'expired'; | ||
| } | ||
|
|
||
| export const IDSelectorItem: React.FC<IDSelectorItemProps> = ({ | ||
| documentName, | ||
| state, | ||
| onPress, | ||
| disabled, | ||
| testID, | ||
| }) => { | ||
| const isDisabled = disabled || isDisabledState(state); | ||
| const isActive = state === 'active'; | ||
| const subtitleText = getSubtitleText(state); | ||
| const subtitleColor = getSubtitleColor(state); | ||
| const textColor = isDisabled ? slate500 : black; | ||
|
|
||
| return ( | ||
| <> | ||
| <Pressable | ||
| onPress={isDisabled ? undefined : onPress} | ||
| disabled={isDisabled} | ||
| testID={testID} | ||
| > | ||
| <XStack | ||
| paddingVertical={16} | ||
| paddingHorizontal={8} | ||
| alignItems="center" | ||
| gap={12} | ||
| opacity={isDisabled ? 0.6 : 1} | ||
| > | ||
| {/* Radio button indicator */} | ||
| <View | ||
| width={24} | ||
| height={24} | ||
| borderRadius={12} | ||
| borderWidth={isActive ? 0 : 2} | ||
| borderColor={slate300} | ||
| backgroundColor={isActive ? green500 : 'transparent'} | ||
| alignItems="center" | ||
| justifyContent="center" | ||
| > | ||
| {isActive && <Check size={16} color="white" strokeWidth={3} />} | ||
| {!isActive && !isDisabled && ( | ||
| <Circle size={20} color={slate300} strokeWidth={0} /> | ||
| )} | ||
| </View> | ||
|
|
||
| {/* Document info */} | ||
| <YStack flex={1} gap={2}> | ||
| <Text | ||
| fontFamily={dinot} | ||
| fontSize={16} | ||
| fontWeight="500" | ||
| color={textColor} | ||
| > | ||
| {documentName} | ||
| </Text> | ||
| <Text fontFamily={dinot} fontSize={14} color={subtitleColor}> | ||
| {subtitleText} | ||
| </Text> | ||
| </YStack> | ||
| </XStack> | ||
| </Pressable> | ||
| <Separator borderColor={slate300} /> | ||
| </> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| // SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. | ||
| // SPDX-License-Identifier: BUSL-1.1 | ||
| // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. | ||
|
|
||
| import { | ||
| Button, | ||
| ScrollView, | ||
| Separator, | ||
| Sheet, | ||
| Text, | ||
| XStack, | ||
| YStack, | ||
| } from 'tamagui'; | ||
| import { X } from '@tamagui/lucide-icons'; | ||
|
|
||
| import { | ||
| black, | ||
| blue600, | ||
| slate300, | ||
| slate500, | ||
| white, | ||
| } from '@selfxyz/mobile-sdk-alpha/constants/colors'; | ||
| import { dinot } from '@selfxyz/mobile-sdk-alpha/constants/fonts'; | ||
|
|
||
| import type { IDSelectorState } from '@/components/documents/IDSelectorItem'; | ||
| import { IDSelectorItem } from '@/components/documents/IDSelectorItem'; | ||
|
|
||
| export interface IDSelectorDocument { | ||
| id: string; | ||
| name: string; | ||
| state: IDSelectorState; | ||
| } | ||
|
|
||
| export interface IDSelectorSheetProps { | ||
| open: boolean; | ||
| onOpenChange: (open: boolean) => void; | ||
| documents: IDSelectorDocument[]; | ||
| selectedId?: string; | ||
| onSelect: (documentId: string) => void; | ||
| onDismiss: () => void; | ||
| onApprove: () => void; | ||
| testID?: string; | ||
| } | ||
|
|
||
| export const IDSelectorSheet: React.FC<IDSelectorSheetProps> = ({ | ||
| open, | ||
| onOpenChange, | ||
| documents, | ||
| selectedId, | ||
| onSelect, | ||
| onDismiss, | ||
| onApprove, | ||
| testID = 'id-selector-sheet', | ||
| }) => { | ||
| return ( | ||
| <Sheet | ||
| modal | ||
| open={open} | ||
| onOpenChange={onOpenChange} | ||
| snapPoints={[55]} | ||
| animation="medium" | ||
| dismissOnSnapToBottom | ||
| > | ||
| <Sheet.Overlay | ||
| backgroundColor="rgba(0, 0, 0, 0.5)" | ||
| animation="lazy" | ||
| enterStyle={{ opacity: 0 }} | ||
| exitStyle={{ opacity: 0 }} | ||
| /> | ||
| <Sheet.Frame | ||
| backgroundColor={white} | ||
| borderTopLeftRadius="$9" | ||
| borderTopRightRadius="$9" | ||
| testID={testID} | ||
| > | ||
| <YStack padding="$4" flex={1}> | ||
| {/* Header */} | ||
| <XStack | ||
| alignItems="center" | ||
| justifyContent="space-between" | ||
| marginBottom="$4" | ||
| > | ||
| <Text | ||
| fontSize={20} | ||
| fontFamily={dinot} | ||
| fontWeight="600" | ||
| color={black} | ||
| > | ||
| Select an ID | ||
| </Text> | ||
| <XStack | ||
| onPress={onDismiss} | ||
| padding="$2" | ||
| hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} | ||
| testID={`${testID}-close-button`} | ||
| > | ||
| <X color={slate500} size={24} /> | ||
| </XStack> | ||
| </XStack> | ||
|
|
||
| <Separator borderColor={slate300} marginBottom="$2" /> | ||
|
|
||
| {/* Document List */} | ||
| <ScrollView | ||
| flex={1} | ||
| showsVerticalScrollIndicator={false} | ||
| testID={`${testID}-list`} | ||
| > | ||
| {documents.map(doc => { | ||
| const isSelected = doc.id === selectedId; | ||
| const itemState: IDSelectorState = isSelected | ||
| ? 'active' | ||
| : doc.state; | ||
|
|
||
| return ( | ||
| <IDSelectorItem | ||
| key={doc.id} | ||
| documentName={doc.name} | ||
| state={itemState} | ||
| onPress={() => onSelect(doc.id)} | ||
| testID={`${testID}-item-${doc.id}`} | ||
| /> | ||
| ); | ||
| })} | ||
| </ScrollView> | ||
|
|
||
| {/* Footer Buttons */} | ||
| <XStack gap={12} marginTop="$4" paddingBottom="$2"> | ||
| <Button | ||
| flex={1} | ||
| backgroundColor={white} | ||
| borderWidth={1} | ||
| borderColor={slate300} | ||
| borderRadius={8} | ||
| paddingVertical={16} | ||
| onPress={onDismiss} | ||
| testID={`${testID}-dismiss-button`} | ||
| > | ||
| <Text | ||
| fontFamily={dinot} | ||
| fontSize={16} | ||
| fontWeight="500" | ||
| color={black} | ||
| > | ||
| Dismiss | ||
| </Text> | ||
| </Button> | ||
| <Button | ||
| flex={1} | ||
| backgroundColor={blue600} | ||
| borderRadius={8} | ||
| paddingVertical={16} | ||
| onPress={onApprove} | ||
| testID={`${testID}-approve-button`} | ||
| > | ||
| <Text | ||
| fontFamily={dinot} | ||
| fontSize={16} | ||
| fontWeight="500" | ||
| color={white} | ||
| > | ||
| Approve | ||
| </Text> | ||
| </Button> | ||
| </XStack> | ||
| </YStack> | ||
| </Sheet.Frame> | ||
| </Sheet> | ||
| ); | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. | ||
| // SPDX-License-Identifier: BUSL-1.1 | ||
| // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. | ||
|
|
||
| export type { | ||
| IDSelectorDocument, | ||
| IDSelectorSheetProps, | ||
| } from '@/components/documents/IDSelectorSheet'; | ||
|
|
||
| export type { | ||
| IDSelectorItemProps, | ||
| IDSelectorState, | ||
| } from '@/components/documents/IDSelectorItem'; | ||
| export { IDSelectorItem } from '@/components/documents/IDSelectorItem'; | ||
| export { IDSelectorSheet } from '@/components/documents/IDSelectorSheet'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.