mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
VC binding initial commit
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
buildToolsVersion = "29.0.3"
|
buildToolsVersion = "29.0.3"
|
||||||
minSdkVersion = 21
|
minSdkVersion = 23
|
||||||
compileSdkVersion = 30
|
compileSdkVersion = 30
|
||||||
targetSdkVersion = 30
|
targetSdkVersion = 30
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,9 @@
|
|||||||
"id": "Id",
|
"id": "Id",
|
||||||
"nationalCard": "National Card",
|
"nationalCard": "National Card",
|
||||||
"uin": "UIN",
|
"uin": "UIN",
|
||||||
|
"enableVerification": "Enable Verification",
|
||||||
|
"profileAuthenticated": "Profile is authenticated!",
|
||||||
|
"offlineAuthDisabledHeader": "Offline Authentication disabled!",
|
||||||
|
"offlineAuthDisabledMessage": "Click 'Enable Authentication' to enable this credentials to be used for offline authentication.",
|
||||||
"vid": "VID"
|
"vid": "VID"
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,10 @@ import { formatDistanceToNow } from 'date-fns';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as DateFnsLocale from '../lib/date-fns/locale';
|
import * as DateFnsLocale from '../lib/date-fns/locale';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Image, ImageBackground } from 'react-native';
|
import { Image, ImageBackground, View } from 'react-native';
|
||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
import { VC, CredentialSubject, LocalizedField } from '../types/vc';
|
import { VC, CredentialSubject, LocalizedField } from '../types/vc';
|
||||||
import { Column, Row, Text } from './ui';
|
import { Button, Column, Row, Text } from './ui';
|
||||||
import { Theme } from './ui/styleUtils';
|
import { Theme } from './ui/styleUtils';
|
||||||
import { TextItem } from './ui/TextItem';
|
import { TextItem } from './ui/TextItem';
|
||||||
import { VcItemTags } from './VcItemTags';
|
import { VcItemTags } from './VcItemTags';
|
||||||
@@ -271,12 +271,43 @@ export const VcDetails: React.FC<VcDetailsProps> = (props) => {
|
|||||||
text={reason.message}
|
text={reason.message}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{props.isBindingPending && (
|
||||||
|
<ImageBackground
|
||||||
|
borderRadius={10}
|
||||||
|
style={Theme.Styles.openCardBgContainer}
|
||||||
|
source={Theme.OpenCard}>
|
||||||
|
<Column>
|
||||||
|
<Icon name="lightbulb" color={'#e8a94f'} size={40} />
|
||||||
|
<Text
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
weight="semibold"
|
||||||
|
size="small"
|
||||||
|
color={Theme.Colors.Details}
|
||||||
|
align="left">
|
||||||
|
{t('offlineAuthDisabledHeader')}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
weight="regular"
|
||||||
|
size="small"
|
||||||
|
color={Theme.Colors.Details}
|
||||||
|
align="left">
|
||||||
|
{t('offlineAuthDisabledMessage')}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button title={t('enableVerification')} onPress={props.onBinding} />
|
||||||
|
</Column>
|
||||||
|
</ImageBackground>
|
||||||
|
)}
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface VcDetailsProps {
|
interface VcDetailsProps {
|
||||||
vc: VC;
|
vc: VC;
|
||||||
|
isBindingPending: boolean;
|
||||||
|
onBinding?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFullAddress(credential: CredentialSubject) {
|
function getFullAddress(credential: CredentialSubject) {
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import React, { useContext, useRef } from 'react';
|
import React, { useContext, useRef } from 'react';
|
||||||
import { useInterpret, useSelector } from '@xstate/react';
|
import { useInterpret, useSelector } from '@xstate/react';
|
||||||
import { Pressable, Image, ImageBackground } from 'react-native';
|
import {
|
||||||
|
Pressable,
|
||||||
|
Image,
|
||||||
|
ImageBackground,
|
||||||
|
TouchableHighlight,
|
||||||
|
View,
|
||||||
|
} from 'react-native';
|
||||||
import { CheckBox, Icon } from 'react-native-elements';
|
import { CheckBox, Icon } from 'react-native-elements';
|
||||||
import { ActorRefFrom } from 'xstate';
|
import { ActorRefFrom } from 'xstate';
|
||||||
import {
|
import {
|
||||||
@@ -10,6 +16,8 @@ import {
|
|||||||
vcItemMachine,
|
vcItemMachine,
|
||||||
selectContext,
|
selectContext,
|
||||||
selectTag,
|
selectTag,
|
||||||
|
selectWalletBindingId,
|
||||||
|
selectEmptyWalletBindingId,
|
||||||
} from '../machines/vcItem';
|
} from '../machines/vcItem';
|
||||||
import { Column, Row, Text } from './ui';
|
import { Column, Row, Text } from './ui';
|
||||||
import { Theme } from './ui/styleUtils';
|
import { Theme } from './ui/styleUtils';
|
||||||
@@ -85,6 +93,28 @@ const getDetails = (arg1, arg2, verifiableCredential) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WalletVerified: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name="verified-user"
|
||||||
|
color={'green'}
|
||||||
|
size={28}
|
||||||
|
containerStyle={{ marginStart: 4, bottom: 1 }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const WalletUnverified: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name="lightbulb"
|
||||||
|
color={'#e8a94f'}
|
||||||
|
size={28}
|
||||||
|
containerStyle={{ marginStart: 4, bottom: 1 }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const VcItem: React.FC<VcItemProps> = (props) => {
|
export const VcItem: React.FC<VcItemProps> = (props) => {
|
||||||
const { appService } = useContext(GlobalContext);
|
const { appService } = useContext(GlobalContext);
|
||||||
const { t } = useTranslation('VcDetails');
|
const { t } = useTranslation('VcDetails');
|
||||||
@@ -98,6 +128,7 @@ export const VcItem: React.FC<VcItemProps> = (props) => {
|
|||||||
const service = useInterpret(machine.current, { devTools: __DEV__ });
|
const service = useInterpret(machine.current, { devTools: __DEV__ });
|
||||||
const context = useSelector(service, selectContext);
|
const context = useSelector(service, selectContext);
|
||||||
const verifiableCredential = useSelector(service, selectVerifiableCredential);
|
const verifiableCredential = useSelector(service, selectVerifiableCredential);
|
||||||
|
const emptyWalletBindingId = useSelector(service, selectEmptyWalletBindingId);
|
||||||
|
|
||||||
//Assigning the UIN and VID from the VC details to display the idtype label
|
//Assigning the UIN and VID from the VC details to display the idtype label
|
||||||
const uin = verifiableCredential?.credentialSubject.UIN;
|
const uin = verifiableCredential?.credentialSubject.UIN;
|
||||||
@@ -197,6 +228,41 @@ export const VcItem: React.FC<VcItemProps> = (props) => {
|
|||||||
<RotatingIcon name="sync" color={Theme.Colors.rotatingIcon} />
|
<RotatingIcon name="sync" color={Theme.Colors.rotatingIcon} />
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row>
|
||||||
|
{emptyWalletBindingId ? (
|
||||||
|
<Row>
|
||||||
|
<WalletUnverified />
|
||||||
|
<Text
|
||||||
|
numLines={1}
|
||||||
|
color={Theme.Colors.Details}
|
||||||
|
weight="bold"
|
||||||
|
size="smaller"
|
||||||
|
margin="10 10 10 10"
|
||||||
|
style={
|
||||||
|
!verifiableCredential
|
||||||
|
? Theme.Styles.loadingTitle
|
||||||
|
: Theme.Styles.subtitle
|
||||||
|
}
|
||||||
|
children={t('offlineAuthDisabledHeader')}></Text>
|
||||||
|
</Row>
|
||||||
|
) : (
|
||||||
|
<Row>
|
||||||
|
<WalletVerified />
|
||||||
|
<Text
|
||||||
|
numLines={1}
|
||||||
|
color={Theme.Colors.Details}
|
||||||
|
weight="bold"
|
||||||
|
size="smaller"
|
||||||
|
margin="10 10 10 10"
|
||||||
|
style={
|
||||||
|
!verifiableCredential
|
||||||
|
? Theme.Styles.loadingTitle
|
||||||
|
: Theme.Styles.subtitle
|
||||||
|
}
|
||||||
|
children={t('profileAuthenticated')}></Text>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
<VcItemTags tag={tag} />
|
<VcItemTags tag={tag} />
|
||||||
</ImageBackground>
|
</ImageBackground>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
"phoneNumber": "رقم الهاتف",
|
"phoneNumber": "رقم الهاتف",
|
||||||
"email": "البريد الإلكتروني",
|
"email": "البريد الإلكتروني",
|
||||||
"address": "عنوان",
|
"address": "عنوان",
|
||||||
"reasonForSharing": "سبب المشاركة"
|
"reasonForSharing": "سبب المشاركة",
|
||||||
|
"enableVerification": "تمكين التحقق",
|
||||||
|
"offlineAuthDisabledHeader": "تم تعطيل المصادقة دون اتصال!",
|
||||||
|
"offlineAuthDisabledMessage": "انقر فوق تمكين المصادقة لتمكين استخدام بيانات الاعتماد هذه للمصادقة دون اتصال.",
|
||||||
|
"profileAuthenticated": "تمت مصادقة الملف الشخصي!"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
"header": "هل ترغب في استخدام المقاييس الحيوية لفتح التطبيق؟",
|
"header": "هل ترغب في استخدام المقاييس الحيوية لفتح التطبيق؟",
|
||||||
|
|||||||
@@ -46,6 +46,10 @@
|
|||||||
"id": "Id",
|
"id": "Id",
|
||||||
"nationalCard": "National Card",
|
"nationalCard": "National Card",
|
||||||
"uin": "UIN",
|
"uin": "UIN",
|
||||||
|
"enableVerification": "Enable Verification",
|
||||||
|
"offlineAuthDisabledHeader": "Offline Authentication disabled!",
|
||||||
|
"offlineAuthDisabledMessage": "Click 'Enable Authentication' to enable this credentials to be used for offline authentication.",
|
||||||
|
"profileAuthenticated": "Profile is authenticated!",
|
||||||
"vid": "VID"
|
"vid": "VID"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
|
|||||||
@@ -32,7 +32,11 @@
|
|||||||
"reasonForSharing": "Dahilan ng pagbabahagi",
|
"reasonForSharing": "Dahilan ng pagbabahagi",
|
||||||
"idType": "Uri ng ID",
|
"idType": "Uri ng ID",
|
||||||
"nationalCard": "Pambansang Kard",
|
"nationalCard": "Pambansang Kard",
|
||||||
"uin": "UIN"
|
"uin": "UIN",
|
||||||
|
"enableVerification": "Paganahin ang Pag-verify",
|
||||||
|
"offlineAuthDisabledHeader": "Na-disable ang Offline Authentication!",
|
||||||
|
"offlineAuthDisabledMessage": "I-click ang 'Paganahin ang Authentication' upang paganahin ang mga kredensyal na ito na magamit para sa offline na pagpapatotoo.",
|
||||||
|
"profileAuthenticated": "Na-authenticate ang profile!"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
"header": "Gusto mo bang gumamit ng biometrics upang i-unlock ang aplikasyon?",
|
"header": "Gusto mo bang gumamit ng biometrics upang i-unlock ang aplikasyon?",
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
"phoneNumber": "फ़ोन नंबर",
|
"phoneNumber": "फ़ोन नंबर",
|
||||||
"email": "ईमेल",
|
"email": "ईमेल",
|
||||||
"address": "पता",
|
"address": "पता",
|
||||||
"reasonForSharing": "साझा करने का कारण"
|
"reasonForSharing": "साझा करने का कारण",
|
||||||
|
"enableVerification": "सत्यापन सक्षम करें",
|
||||||
|
"offlineAuthDisabledHeader": "ऑफ़लाइन प्रमाणीकरण अक्षम!",
|
||||||
|
"offlineAuthDisabledMessage": "ऑफ़लाइन प्रमाणीकरण के लिए उपयोग किए जाने वाले इन क्रेडेंशियल्स को सक्षम करने के लिए 'प्रमाणीकरण सक्षम करें' पर क्लिक करें।",
|
||||||
|
"profileAuthenticated": "प्रोफ़ाइल प्रमाणित है!"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
"header": "क्या आप एप्लिकेशन को अनलॉक करने के लिए बायोमेट्रिक्स का उपयोग करना चाहेंगे?",
|
"header": "क्या आप एप्लिकेशन को अनलॉक करने के लिए बायोमेट्रिक्स का उपयोग करना चाहेंगे?",
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
"phoneNumber": "ಫೋನ್ ಸಂಖ್ಯೆ",
|
"phoneNumber": "ಫೋನ್ ಸಂಖ್ಯೆ",
|
||||||
"email": "ಇಮೇಲ್",
|
"email": "ಇಮೇಲ್",
|
||||||
"address": "ವಿಳಾಸ",
|
"address": "ವಿಳಾಸ",
|
||||||
"reasonForSharing": "ಹಂಚಿಕೆಗೆ ಕಾರಣ"
|
"reasonForSharing": "ಹಂಚಿಕೆಗೆ ಕಾರಣ",
|
||||||
|
"enableVerification": "ಪರಿಶೀಲನೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ",
|
||||||
|
"offlineAuthDisabledHeader": "ಆಫ್ಲೈನ್ ದೃಢೀಕರಣವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ!",
|
||||||
|
"offlineAuthDisabledMessage": "ಆಫ್ಲೈನ್ ದೃಢೀಕರಣಕ್ಕಾಗಿ ಬಳಸಲು ಈ ರುಜುವಾತುಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು 'ದೃಢೀಕರಣವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ' ಕ್ಲಿಕ್ ಮಾಡಿ.",
|
||||||
|
"profileAuthenticated": "ಪ್ರೊಫೈಲ್ ಅನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ!"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
"header": "ಅಪ್ಲಿಕೇಶನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಬಳಸಲು ನೀವು ಬಯಸುವಿರಾ?",
|
"header": "ಅಪ್ಲಿಕೇಶನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಬಳಸಲು ನೀವು ಬಯಸುವಿರಾ?",
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
"phoneNumber": "தொலைபேசி எண்",
|
"phoneNumber": "தொலைபேசி எண்",
|
||||||
"email": "மின்னஞ்சல்",
|
"email": "மின்னஞ்சல்",
|
||||||
"address": "முகவரி",
|
"address": "முகவரி",
|
||||||
"reasonForSharing": "பகிர்வதற்கான காரணம்"
|
"reasonForSharing": "பகிர்வதற்கான காரணம்",
|
||||||
|
"enableVerification": "சரிபார்ப்பை இயக்கு",
|
||||||
|
"offlineAuthDisabledHeader": "ஆஃப்லைன் அங்கீகாரம் முடக்கப்பட்டது!",
|
||||||
|
"offlineAuthDisabledMessage": "இந்த நற்சான்றிதழ்களை ஆஃப்லைன் அங்கீகாரத்திற்காகப் பயன்படுத்துவதற்கு 'அங்கீகாரத்தை இயக்கு' என்பதைக் கிளிக் செய்யவும்.",
|
||||||
|
"profileAuthenticated": "சுயவிவரம் அங்கீகரிக்கப்பட்டது!"
|
||||||
},
|
},
|
||||||
"AuthScreen": {
|
"AuthScreen": {
|
||||||
"header": "பயன்பாட்டைத் திறக்க பயோமெட்ரிக்ஸைப் பயன்படுத்த விரும்புகிறீர்களா?",
|
"header": "பயன்பாட்டைத் திறக்க பயோமெட்ரிக்ஸைப் பயன்படுத்த விரும்புகிறீர்களா?",
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ import { StoreEvents } from './store';
|
|||||||
import { ActivityLogEvents } from './activityLog';
|
import { ActivityLogEvents } from './activityLog';
|
||||||
import { verifyCredential } from '../shared/vcjs/verifyCredential';
|
import { verifyCredential } from '../shared/vcjs/verifyCredential';
|
||||||
import { log } from 'xstate/lib/actions';
|
import { log } from 'xstate/lib/actions';
|
||||||
|
import { generateKeys } from '../shared/rsakeypair/rsaKeypair';
|
||||||
|
import { KeyPair } from 'react-native-rsa-native';
|
||||||
|
import {
|
||||||
|
getPrivateKey,
|
||||||
|
savePrivateKey,
|
||||||
|
} from '../shared/keystore/SecureKeystore';
|
||||||
|
import { localAssets } from 'expo-updates';
|
||||||
|
|
||||||
const model = createModel(
|
const model = createModel(
|
||||||
{
|
{
|
||||||
@@ -32,9 +39,14 @@ const model = createModel(
|
|||||||
idError: '',
|
idError: '',
|
||||||
transactionId: '',
|
transactionId: '',
|
||||||
revoked: false,
|
revoked: false,
|
||||||
|
walletBindingId: '',
|
||||||
|
walletBindingError: '',
|
||||||
|
publicKey: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
events: {
|
events: {
|
||||||
|
KEY_RECEIVED: (key: string) => ({ key }),
|
||||||
|
KEY_ERROR: (error: Error) => ({ error }),
|
||||||
EDIT_TAG: () => ({}),
|
EDIT_TAG: () => ({}),
|
||||||
SAVE_TAG: (tag: string) => ({ tag }),
|
SAVE_TAG: (tag: string) => ({ tag }),
|
||||||
STORE_READY: () => ({}),
|
STORE_READY: () => ({}),
|
||||||
@@ -49,6 +61,8 @@ const model = createModel(
|
|||||||
INPUT_OTP: (otp: string) => ({ otp }),
|
INPUT_OTP: (otp: string) => ({ otp }),
|
||||||
REFRESH: () => ({}),
|
REFRESH: () => ({}),
|
||||||
REVOKE_VC: () => ({}),
|
REVOKE_VC: () => ({}),
|
||||||
|
ADD_WALLET_BINDING_ID: () => ({}),
|
||||||
|
BINDING_DONE: () => ({}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -56,7 +70,7 @@ const model = createModel(
|
|||||||
export const VcItemEvents = model.events;
|
export const VcItemEvents = model.events;
|
||||||
|
|
||||||
export const vcItemMachine =
|
export const vcItemMachine =
|
||||||
/** @xstate-layout N4IgpgJg5mDOIC5QDcDGBaAlgFzAWwDpUALMVAa0wDsoA1VAYgHEBRAFQH1aBhDgJRYBlAAoB5AHKCWiUAAcA9rByZ5VGSAAeiAIwAWAAwFtANgAcAdl0BmAJwAmOxd0BWADQgAnoivHDpx6aBzubGwc6mAL4R7mhYuIQkZJQ0gtjyAE5gDIJsogL8QmKS0kggCkrYKmqlWgh6hiYWDnba4aFW7l4I5qbOBPohvdoW2jbDUTEYOPhEpBTUUIJg6cjLACIAhtgbs0kLqVsArrAMYgAyZ+rlyqrqtdrm2gRWds521vqmusZ2Nr2dOlGugIAXMb1+dn0NnCExAsWmCTmyUWy1W6U22128xS22wxwYa1EAHVxGdRABBNYFSkATSuihu1VAtQMfSsPlCumhVlGjwBdSsumBdh5Vmc1jGznszlh8PiWORSxW6y2Owg8gA7lQADbyDYQBbcTIQMBUSobbWnUQXekVKp3RA-YWtcz6YzQ4y6OzGfnaIEgwJghz2KEw6JwqbyxLYlHK9GqgjqrW6-WG42m82W7gCNYscRsACS5LOHEJJLJlJYa1tjIdCF0pmMz3Mrucgu+7R9nkQjb6Fh87Z5LcCssjM0wEG1WSrBc4bHJTBrlVuNR0bqeNk9A2Mrv0+mc4X5f3MBF0PRFPP8-kso7i48nWVoLD4BYAYnTStdl0zND3nA0rEbUx930OwQlCflTEAggbHMDkwKdfRtFvBECAnKcGDJbgAGkuG4Jd7VXOo2z6T5fDMHwbCQnpIOg2CfCgkJBjFFD5XQrIAFVSVEHC8IIldmR0axTCMYxRhsXRhmsd47H5QZ+mGHdQNGYxKNYmZIGUGg2A2KACQLQQAFkDMEfif3uYYT09XxGx6dk91k7sEGPU9z1CJD-HZKx1MITTKm03TsnJJ8OHnRdPwZb86z9VpTyosZ3TMAxHK6P1HiML1Xi9YwxIGSJwzlGZYDSdIFh0vScjyFgChECQpDM6LXjsAhTAk-RALguCrHMX1tBFAhLGGXoWj+drdB8gg0UwAAzDw00gDNMAtBh1SoMA0KoZB5HIdbCsIKbZvmk0zSW7UEGoLbUC2KoAG19AAXQaojtH0AwCClcxXihb0TAPfkXEMJDhl5d0eiFcaCrHfblhmuaaCNBaTuW5Z0gyAhZG1LZpoyfaocmmHDvh9MkbOi75Cu787seiK7QE39nNeFrnE9GxAJcSFvX5H5mvsb4+u0WxgNeibo2RWgCcwCmqgOPETiewS6hep4rDdaFglAz6eqc14myvQJ+YGfd2Qmi6LQnBgC3EYQOM4UQ2GEeX6chT1m0eA9wZVqDev-GDKJ3ST3SFfLJjvQhTe1c21gM4zBFMmna2el4bHe0xWm+F5PUA-k2yeAw7Mk8UWnMGwJsyABHQ44H8qBRGwWQVtUdayZ2ya8fLyvioWWvZHOzbyeu1Qqcd+5U6sfoHBykwQjeLWukSmCzxFODHHeCxS7ACuq67uuGBRtGMaxnHW9Dgh263mhu97y6B6oIf46i57U+BN5AlU75nF+3Rs-sAgxLBFWJKWFgnYCaGxUCoDALIau3cCxUFkIcbAFsrY2w4HbB299CIKweFyd6YEP6OHBO1NwTlYLJ3sIKewrR-zeUhifMBECoHb1kLA+BiCo5GRMsPHQ-5gQ-DFLYewcF7CmCPC0OKvwfBSihE4dem9O40DOOTcgDc1obS2i3Pap8N4d2rooigV9+6UwelwuowFk6NmsnuaEF4RFOT6rBd61gXo9FbIKWROiFh6OUXvdI6NMbYGxukXGJ8z7yKgF4gxUtB7GIwXTEeVEBrkNZAhbqX8SHFxgiKQuUppQPAmrqGM9Bsi5HyAIWqxQTGtG6kYcIfUWyhEcNCXqm4akSR+i2cUxtYRUHkCaeApRNGiwWPQExZhf6pIkl6GwYwvQdDsS2Iwe4hQ9GmQYawEMQ6oSGTiDIYATHQhBE6KigQeSTLmXPAY-RTk2WkcBYwIskT7FRCqTE2zFi4mOPsp4jwvjehcMzVSwxfQ8maiKAW0zegDA-sHCMJ83lKjRBiNUmodR6gNETRGmYTHhBEueAWrpPrBDSalFWhgwUclCEAv4Dy9gpGefGbYoyTw-Oyv8nKl5fRujHqCCiIQXAbNhahdilSHgbgPBRdODhLByUCDBOCOV9xfAlDCzRfkyq6UqVCYEm4pSOE+i0P0nLZWeRaDuRwKtzATWKhkdVUBKmQj6KpMwPQYoCy7KlX4hg2xeihMXWCXwZS0NQgdOGUAEbHSxbE8yiB6m-yJb0A8eq2z-Ryu9P0UF8VQh8CAoNUZHk0HFqVaaksb4y0+VGusHxnh6Fqf4RwZriWOndBlFsfUuR-H8CXXN45NpmwgAQeQdcTHOyeE-HoqlFWCmzn1X+fxWh7lTmJIUJte0R37QAIzATtKgEBh1G3epuV6rNMrEK6G0IwDwSLemAi9Ltmy2KronHu34B7fBckFA4U9iAJSztToEKC-DPjuPPjXIdFbnrfDIX8cUDZ-xukbN-ZqXpvgB03MMFooDwGQOgXXFhCDKnFyeJ6cCjw-SvTdHJaZ704NUR+DuJ1wGwleIIwk34TExRu0sF+xW0FrCg1ePwrJ+SlHDNQJUmeLVbCAU+LYAwoxfQEP6E4z4WVPpfB8iY6wA0pJ-PFYC2xc8TwvVen89c3wwRRCiEAA */
|
/** @xstate-layout N4IgpgJg5mDOIC5QDcDGBaAlgFzAWwGIAlAUQDFSBlACQG0AGAXUVAAcB7WHTdgOxZAAPRABYATABoQAT0QBGMQA4ArADpFATnEB2AGwBmMcrEjFAXzNS0WXHlWoAFmFQBrTLygA1VAQDiJABUAfU8AYSCqAAUAeQA5ShIGZiQQDi5sHn4U4QQROX1VXRFlDTlNXV1tPX0pWQQ5YzFVekU5PW0NXXzFDosrDBx8eydXdy8ff2CwiJJKGPjEuWS2Tm4+ARy8gqKSss7K6tr5EXpdQpFxVoV9RX19ZT6Qa0G7R2c3D0psdgAnMAJKAFoqQZnM4gkkgI0mssqAcopJDJRHINIpVPcxLorroxBoNGJHs9bMN3mMvr9-oDgSRQfMIUsoasMutsvJ6CJtKoOm08WI7hplPQakj6ko1Kd6FpcaVSg9LE8BsS3qNPmAfsg1QARACG2G1JJVUC+uoArrACDEADKWyEpaHM2FCRBiNqqIzGFEqHGYipHBD6UpNOT0TFGfHaejaRQiQmKobKj5GtUan46vUGxPG7Bmgia6IAdViluiAEFNTMywBNW0rdKZDbIjSqYPiModJTsjR+k76M4SjQB0oh0y6WM2eMjTPJrW6-UQdgAd14ABt2NqIGNQn8IGBeBltcuLdFrTXUkz66yEFV6KoLkojDpWgi-QGxJyyspNJKhUotGOXhmZLTqms6qPOS6ruum7bru+6HqEpCaiQsQBAAkiWlpBHmhbFmWJCaqe9oXnCbLKCIzb3IKqINLoAovqiaLaG+ZHaPo4ghnIMbykSQyYBAy7-PhqHBAEJa+IR54siR9Qok2ygeqibEGJGL7cs2ii6EKmh4oYQr-sSfECQQngkEQqFkNWTCMnWUlOggYgOWcPTGCIOIDrRcjdm+ciqMoKI3DcGiSmxcr9OOdiGf8xahAA0iEoQSTZjo5N56J3AFYhCuyyjCnUulNBGlTRnymmVKFCrhaokXECQnjRDFNJhIlMINqKfoKPpvH8f8ZblvmGGWoEQQAEKobEmpjb4QSoQRVl2pJyXOliBRsScwZ4iGLoviiZxdK5rQGPiLqdXYkDcB4ATalAuaoZQACyt2UM1DqtXIsm+QptyufoKkir2Ea3vceKfoKBzlTxp0bhkF1XQCJYmUEoniXNtYtZeb2aB9LqKd9v15YK5EOdU9A7b2A4naosDfD8YyXddVIglE4KJCjZ5Ja9gpokK+RMYKbQKNoL4E26b7KaTtH6BTKaYAAZtI0GQLBmAHgQ868GAVW8Mg7AuBrEOqNLcsKzue7K8uCDuNrqC6pkSTPcRdkOXITnaC5blk55Io9k0WIlNoewGFUUtqrL8seFuiumyrao-L8qisMuuoy78dj64bYdQBHJtwRbWvsNbDp26zRG2SljnqK7Jjux53ZtGiyiacDGj+-o2hcWFAEJmMnghzLmAF5kWY5vbpfyK0TaKF6lTBfJWL0Zx6klPibFRqYBLcXGryTt3vf9zbfBD+atAMvN7Po+P6hTxGA6z4oXk5ecIj6GUwYk50FOWwefEEGNkQAKrBGiAESII9Fr2X9mlO4txMo-WKLlRAP1ey3lRMUPy9AG58g-lrL+EAbr3UeqA1qqV0oZSynAl8AU3SnCjPJAUD5Rwb0qn8AAjiaOA0MoDRGwKwVWfANaWx1nrTeqgWFsKpmMLhrBc5W33rwIuyw2Zo2kiYTkWgOiTxaJiVoNw-RBTRJxC4rEBSGE5hTUR7CJHcIIDHOOCck4pwNsI8x4iPCSOkfnWR8jrJKMdsoVRHIGKaKxJxdqKIgwhgjNGXmtwKbalQKgMArAOGSNQrwVgJpsA-1iP-QBwDCGXnuDeIoXRW5aF7FRXQfolA9EKHyC40Zm64juLE+JiTkncNSekzJE18GUCesXBarU2JFNcjzMpugKlVMqE0EwtwmLsn9sdRhAE4kJKSWMIgYBta606RkrJOSghAJAQMs+yiVDnBKOyFEkoXRvj9K7JsbcVCfjaCcepLS1kcM2dssAuzum3Qen0-JZy1A7CCnkIK+IBYvg5FyIKHF8QaVKBUMxYBWEWI8JafOLheHq01j8xxTC0ViI4Vi1w7iB58C8afHxOQ24FGdrRIo6DIxNKqaULmT4Qp5HbKi9FLioBkpxTYn48dE7YGTj8VOTjiUYsFdiilnimDArsoU84JSOhPwmZKSpIo3xaEKNqzSfiqiGG0BTVchpvAAiBIzWYdIWYKJLmAt6ztbzO00K3b8Qp4H2QHE2Z+koOT0BDD0SWyziTOK+VswRuL+F511oSgCUaNkxt1oqwuyqTm0sQL7LkuIThkWDDiKofoKgBvWi0eS0Yijrw7pG2VArvmxpFWK+xUqk0Nv5dGn5GbbZZqdYMy8eamJaHQXkU4b5BYiijIxUWnF5J+Kfqi7Z3cfAMxpEzBYKqcg-TUIKENeQcStzuByKp8kmjFAqCoDkvY8gWvYFAKAqafl4MBf0wdpy7IRgKJGH6fJkVdD5Oe4wt4G6+1vcy9uFVk2No4cNdwG5XFWLVvGgl+sU0eAQ7wJDnDuF9qpQO7xL10ZwMKFUCFR1qnTrqGEm8-Ya0-Vds7PlJKxjYdw5I6xPxY6irsRKhxGG4PscQ5YqRAjKVyKIzSkj0lnxexuDeDoIbjHaIch8tpImcNif2QAw5eTs2ybssYJsuIygtBuGUcQyg-TGBvE-S5KI+b8g0+srDonkM8J6e+nd8hDBVJDGoO4bQ-E4j8m9cGwj1wQBimAaQkRtSYB+HG-FgjO1DGi7F+LiWfgEak4wXz-oShck0iIcMYbMRaCqTcJoeIEQug0n5DQsSIAxbiwlpL3HeNtoEx2-WmX2s5by9S1GRnd3Fb0J2N8FXaIiCqZxTkTyLhdHkkxZpEaMutbGPmA8AlsAcbGKhXBqHUuJv61tjwO3lx7YOx4I7w3pOjYdvCTKvkcTXsjD6rseqbjkTfsFCzRQWMbbsNF7bu2wD7Y81AI7XXbHisldKyqYPLsQ6h9pu7EAHsFcM89xACIbwYI+z+gMVTfz5tdgYPIOVPUU1gA4Rct2jR6mzOaUa41JpYTiI64jePRRP3dbRE1Qp1E0edE-HyhUsTUMFPJLi8peDsB3PAFIENeejwQOgXsfp0AKHoyGkmLcSboIbhTLuHhvDq7AeIdqI43s3IaDlKMbEzfb0+NTMAVvWqsQKAe04vY2KOTmyKfIsKG6Sh6LKYobRXeklVOqGceoveXjbqpTShQQxYlohtcN9aJxx6TAnkC6ZzfM9NCrp7GuFCIjqGtX9jdOilMabHw0lBgJpjnIuFca5cNZyVgeZP0kcRojYgFZuBwoXdlDc2O8JSG5lFzzBgy3VB+OwuH94tqITD8jaNtdPe1WLXyqDtCmZ0OF01XzkYMZEKLyQjzROif1nfonWlvsrzd0F0+prTK6l+-NKGbAW2fjel7EzyFiFFUAFEqCCgDDHwYTz1Tl7gzj7yjmXD-3qC3y5GuRKE9SqDuS9gchHzKXC1chNxb0TB7hpj7kk0PnQPyDfEvgvRMHxCvWD1r0yiaFaElFYjKEUG4KwWQBwXQIgRsz+j3TAyKhgNcmMEi0qk-mXD4lUHYG4ToJRF8goXxEgIbmU1gNuHfhB3xRwVUAACM4ldYcM6CHIYU-IJCOg8Qhxr9WM5VJF0CbcQ9nZFtqFJ5eDV460l8MtWk3M8NWA-k6C8ZnQegfJfZAw24ItzUDDVlNMPBm0dk0kMlXCa9EAmJyJgD8gSg-Jt8-ChNu0xghV0Cco1AHItAAkAwPVRC6gzMzhA18QDhZkY8DDLUKDUB0D8QmwLMl4ugKhXl2U3VmjMQ8DTB2iECRFhNki01PcZM+dXImg7MUE2hJQyhMirxzl3IQDOIBwAkV0dY11VCxd7ITMJDPwb1n4MQH0n0X1BFyj0Fmhn4lAMRMQn52Rz03Ur0KhxB8pZDYMSj3MMdgj0CmkzhURUR-ZV5xA2CEE2htgF0okWh-Z5JXN4NocXDFiNcxQLlwVrkoV8C6hhYytbghj-Vm5XYWs2tssktLCzi+Q+CqFplspI9l0EiLsoArsbtocjtyiAYD1r9Q1URwj7IAxyIr0yIcYVBF99Z6dGdodaCcSXV2Q0RSt-iNVjBfVCiWTpcyoTd5czAgA */
|
||||||
model.createMachine(
|
model.createMachine(
|
||||||
{
|
{
|
||||||
tsTypes: {} as import('./vcItem.typegen').Typegen0,
|
tsTypes: {} as import('./vcItem.typegen').Typegen0,
|
||||||
@@ -162,6 +176,9 @@ export const vcItemMachine =
|
|||||||
REVOKE_VC: {
|
REVOKE_VC: {
|
||||||
target: 'acceptingRevokeInput',
|
target: 'acceptingRevokeInput',
|
||||||
},
|
},
|
||||||
|
ADD_WALLET_BINDING_ID: {
|
||||||
|
target: 'requestingBindingOtp',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
editingTag: {
|
editingTag: {
|
||||||
@@ -320,7 +337,10 @@ export const vcItemMachine =
|
|||||||
],
|
],
|
||||||
onError: [
|
onError: [
|
||||||
{
|
{
|
||||||
actions: [log('OTP error'), 'setOtpError'],
|
actions: [
|
||||||
|
log((_, event) => (event.data as Error).message),
|
||||||
|
'setOtpError',
|
||||||
|
],
|
||||||
target: 'acceptingOtpInput',
|
target: 'acceptingOtpInput',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -342,10 +362,115 @@ export const vcItemMachine =
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requestingBindingOtp: {
|
||||||
|
invoke: {
|
||||||
|
src: 'requestBindingOtp',
|
||||||
|
onDone: [
|
||||||
|
{
|
||||||
|
target: 'acceptingBindingOtp',
|
||||||
|
actions: log('accepting OTP'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onError: [
|
||||||
|
{
|
||||||
|
target: '#vc-item.invalid.backend',
|
||||||
|
actions: log((_, event) => (event.data as Error).message),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
acceptingBindingOtp: {
|
||||||
|
entry: ['clearOtp', 'setTransactionId'],
|
||||||
|
on: {
|
||||||
|
INPUT_OTP: {
|
||||||
|
target: 'addKeyPair',
|
||||||
|
actions: [
|
||||||
|
log('calling addKeyPair'),
|
||||||
|
'setTransactionId',
|
||||||
|
'setOtp',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
DISMISS: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: ['clearOtp', 'clearTransactionId'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addKeyPair: {
|
||||||
|
invoke: {
|
||||||
|
src: 'generateKeyPair',
|
||||||
|
onDone: {
|
||||||
|
target: 'addingWalletBindingId',
|
||||||
|
actions: ['setPublicKey'],
|
||||||
|
},
|
||||||
|
onError: [
|
||||||
|
{
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'setWalletBindingError',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addingWalletBindingId: {
|
||||||
|
invoke: {
|
||||||
|
src: 'addWalletBindnigId',
|
||||||
|
onDone: [
|
||||||
|
{
|
||||||
|
target: 'showBindingStatus',
|
||||||
|
actions: [
|
||||||
|
'setWalletBindingId',
|
||||||
|
'storeContext',
|
||||||
|
log(
|
||||||
|
(_context, event) =>
|
||||||
|
'Received walletBindingId : ' + _context.walletBindingId
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onError: [
|
||||||
|
{
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'setWalletBindingError',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// storePrivateKey: {
|
||||||
|
// invoke: {
|
||||||
|
// src: 'storePrivateKeyToKeystore',
|
||||||
|
// onDone: {
|
||||||
|
// target: 'showBindingStatus',
|
||||||
|
// },
|
||||||
|
// onError: {
|
||||||
|
// actions: 'setWalletBindingError',
|
||||||
|
// target: 'showBindingStatus',
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
// },
|
||||||
|
showBindingStatus: {
|
||||||
|
on: {
|
||||||
|
BINDING_DONE: {
|
||||||
|
target: 'idle',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
actions: {
|
actions: {
|
||||||
|
setWalletBindingError: assign({
|
||||||
|
walletBindingError: (context, event) => (event.data as Error).message,
|
||||||
|
}),
|
||||||
|
|
||||||
|
setPublicKey: assign({
|
||||||
|
publicKey: (context, event) => (event.data as KeyPair).public,
|
||||||
|
}),
|
||||||
|
|
||||||
|
setWalletBindingId: assign({
|
||||||
|
walletBindingId: (context, event) => event.data as string,
|
||||||
|
}),
|
||||||
|
|
||||||
updateVc: send(
|
updateVc: send(
|
||||||
(context) => {
|
(context) => {
|
||||||
const { serviceRefs, ...vc } = context;
|
const { serviceRefs, ...vc } = context;
|
||||||
@@ -486,6 +611,49 @@ export const vcItemMachine =
|
|||||||
},
|
},
|
||||||
|
|
||||||
services: {
|
services: {
|
||||||
|
addWalletBindnigId: async (context) => {
|
||||||
|
let response = null;
|
||||||
|
try {
|
||||||
|
response = await request('POST', '/binding-credential-request', {
|
||||||
|
individualId: context.id,
|
||||||
|
otp: context.otp,
|
||||||
|
transactionID: context.transactionId,
|
||||||
|
publicKey: context.publicKey,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return response.response.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
generateKeyPair: async (context) => {
|
||||||
|
let keyPair: KeyPair = await generateKeys();
|
||||||
|
|
||||||
|
const hasSetPrivateKey: boolean = await savePrivateKey(
|
||||||
|
context.verifiableCredential.id,
|
||||||
|
keyPair.private
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasSetPrivateKey) {
|
||||||
|
throw new Error('Could not store private key in keystore.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyPair;
|
||||||
|
},
|
||||||
|
|
||||||
|
requestBindingOtp: async (context) => {
|
||||||
|
try {
|
||||||
|
return request('POST', '/binding-otp', {
|
||||||
|
individualId: context.id,
|
||||||
|
individualIdType: context.idType,
|
||||||
|
otpChannel: ['EMAIL', 'PHONE'],
|
||||||
|
transactionID: context.transactionId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
checkStatus: (context) => (callback, onReceive) => {
|
checkStatus: (context) => (callback, onReceive) => {
|
||||||
const pollInterval = setInterval(
|
const pollInterval = setInterval(
|
||||||
() => callback(model.events.POLL()),
|
() => callback(model.events.POLL()),
|
||||||
@@ -541,6 +709,7 @@ export const vcItemMachine =
|
|||||||
isVerified: false,
|
isVerified: false,
|
||||||
lastVerifiedOn: null,
|
lastVerifiedOn: null,
|
||||||
locked: context.locked,
|
locked: context.locked,
|
||||||
|
walletBindingId: context.walletBindingId,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -703,3 +872,28 @@ export function selectIsAcceptingRevokeInput(state: State) {
|
|||||||
export function selectIsRequestingOtp(state: State) {
|
export function selectIsRequestingOtp(state: State) {
|
||||||
return state.matches('requestingOtp');
|
return state.matches('requestingOtp');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectIsRequestBindingOtp(state: State) {
|
||||||
|
return state.matches('requestingBindingOtp');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectWalletBindingId(state: State) {
|
||||||
|
return state.context.walletBindingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectEmptyWalletBindingId(state: State) {
|
||||||
|
var val = state.context.walletBindingId;
|
||||||
|
return val === undefined || val == null || val.length <= 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectWalletBindingError(state: State) {
|
||||||
|
return state.context.walletBindingError;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectAcceptingBindingOtp(state: State) {
|
||||||
|
return state.matches('acceptingBindingOtp');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectShowBindingStatus(state: State) {
|
||||||
|
return state.matches('showBindingStatus');
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,167 +1,91 @@
|
|||||||
// This file was automatically generated. Edits will be overwritten
|
|
||||||
|
|
||||||
export interface Typegen0 {
|
// This file was automatically generated. Edits will be overwritten
|
||||||
'@@xstate/typegen': true;
|
|
||||||
'internalEvents': {
|
export interface Typegen0 {
|
||||||
'': { type: '' };
|
'@@xstate/typegen': true;
|
||||||
'done.invoke.checkStatus': {
|
internalEvents: {
|
||||||
type: 'done.invoke.checkStatus';
|
"": { type: "" };
|
||||||
data: unknown;
|
"done.invoke.checkStatus": { type: "done.invoke.checkStatus"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"done.invoke.downloadCredential": { type: "done.invoke.downloadCredential"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
};
|
"done.invoke.vc-item.addKeyPair:invocation[0]": { type: "done.invoke.vc-item.addKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
'done.invoke.downloadCredential': {
|
"done.invoke.vc-item.addingWalletBindingId:invocation[0]": { type: "done.invoke.vc-item.addingWalletBindingId:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
type: 'done.invoke.downloadCredential';
|
"done.invoke.vc-item.requestingBindingOtp:invocation[0]": { type: "done.invoke.vc-item.requestingBindingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
data: unknown;
|
"done.invoke.vc-item.requestingLock:invocation[0]": { type: "done.invoke.vc-item.requestingLock:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"done.invoke.vc-item.requestingOtp:invocation[0]": { type: "done.invoke.vc-item.requestingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
};
|
"done.invoke.vc-item.requestingRevoke:invocation[0]": { type: "done.invoke.vc-item.requestingRevoke:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
'done.invoke.vc-item.requestingLock:invocation[0]': {
|
"done.invoke.vc-item.verifyingCredential:invocation[0]": { type: "done.invoke.vc-item.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||||
type: 'done.invoke.vc-item.requestingLock:invocation[0]';
|
"error.platform.checkStatus": { type: "error.platform.checkStatus"; data: unknown };
|
||||||
data: unknown;
|
"error.platform.downloadCredential": { type: "error.platform.downloadCredential"; data: unknown };
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"error.platform.vc-item.addKeyPair:invocation[0]": { type: "error.platform.vc-item.addKeyPair:invocation[0]"; data: unknown };
|
||||||
};
|
"error.platform.vc-item.addingWalletBindingId:invocation[0]": { type: "error.platform.vc-item.addingWalletBindingId:invocation[0]"; data: unknown };
|
||||||
'done.invoke.vc-item.requestingOtp:invocation[0]': {
|
"error.platform.vc-item.requestingBindingOtp:invocation[0]": { type: "error.platform.vc-item.requestingBindingOtp:invocation[0]"; data: unknown };
|
||||||
type: 'done.invoke.vc-item.requestingOtp:invocation[0]';
|
"error.platform.vc-item.requestingLock:invocation[0]": { type: "error.platform.vc-item.requestingLock:invocation[0]"; data: unknown };
|
||||||
data: unknown;
|
"error.platform.vc-item.requestingOtp:invocation[0]": { type: "error.platform.vc-item.requestingOtp:invocation[0]"; data: unknown };
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"error.platform.vc-item.requestingRevoke:invocation[0]": { type: "error.platform.vc-item.requestingRevoke:invocation[0]"; data: unknown };
|
||||||
};
|
"error.platform.vc-item.verifyingCredential:invocation[0]": { type: "error.platform.vc-item.verifyingCredential:invocation[0]"; data: unknown };
|
||||||
'done.invoke.vc-item.requestingRevoke:invocation[0]': {
|
"xstate.init": { type: "xstate.init" };
|
||||||
type: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
|
};
|
||||||
data: unknown;
|
invokeSrcNameMap: {
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"addWalletBindnigId": "done.invoke.vc-item.addingWalletBindingId:invocation[0]";
|
||||||
};
|
"checkStatus": "done.invoke.checkStatus";
|
||||||
'done.invoke.vc-item.verifyingCredential:invocation[0]': {
|
"downloadCredential": "done.invoke.downloadCredential";
|
||||||
type: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
"generateKeyPair": "done.invoke.vc-item.addKeyPair:invocation[0]";
|
||||||
data: unknown;
|
"requestBindingOtp": "done.invoke.vc-item.requestingBindingOtp:invocation[0]";
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
"requestLock": "done.invoke.vc-item.requestingLock:invocation[0]";
|
||||||
};
|
"requestOtp": "done.invoke.vc-item.requestingOtp:invocation[0]";
|
||||||
'error.platform.checkStatus': {
|
"requestRevoke": "done.invoke.vc-item.requestingRevoke:invocation[0]";
|
||||||
type: 'error.platform.checkStatus';
|
"verifyCredential": "done.invoke.vc-item.verifyingCredential:invocation[0]";
|
||||||
data: unknown;
|
};
|
||||||
};
|
missingImplementations: {
|
||||||
'error.platform.downloadCredential': {
|
actions: never;
|
||||||
type: 'error.platform.downloadCredential';
|
delays: never;
|
||||||
data: unknown;
|
guards: never;
|
||||||
};
|
services: never;
|
||||||
'error.platform.vc-item.requestingLock:invocation[0]': {
|
};
|
||||||
type: 'error.platform.vc-item.requestingLock:invocation[0]';
|
eventsCausingActions: {
|
||||||
data: unknown;
|
"clearOtp": "" | "BINDING_DONE" | "DISMISS" | "REVOKE_VC" | "STORE_RESPONSE" | "done.invoke.vc-item.requestingBindingOtp:invocation[0]" | "done.invoke.vc-item.requestingOtp:invocation[0]" | "done.invoke.vc-item.verifyingCredential:invocation[0]" | "error.platform.vc-item.addKeyPair:invocation[0]" | "error.platform.vc-item.addingWalletBindingId:invocation[0]" | "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]" | "error.platform.vc-item.verifyingCredential:invocation[0]";
|
||||||
};
|
"clearTransactionId": "" | "BINDING_DONE" | "DISMISS" | "STORE_RESPONSE" | "done.invoke.vc-item.verifyingCredential:invocation[0]" | "error.platform.vc-item.addKeyPair:invocation[0]" | "error.platform.vc-item.addingWalletBindingId:invocation[0]" | "error.platform.vc-item.verifyingCredential:invocation[0]";
|
||||||
'error.platform.vc-item.requestingOtp:invocation[0]': {
|
"logDownloaded": "CREDENTIAL_DOWNLOADED";
|
||||||
type: 'error.platform.vc-item.requestingOtp:invocation[0]';
|
"logRevoked": "STORE_RESPONSE";
|
||||||
data: unknown;
|
"markVcValid": "done.invoke.vc-item.verifyingCredential:invocation[0]";
|
||||||
};
|
"requestStoredContext": "GET_VC_RESPONSE" | "REFRESH";
|
||||||
'error.platform.vc-item.requestingRevoke:invocation[0]': {
|
"requestVcContext": "xstate.init";
|
||||||
type: 'error.platform.vc-item.requestingRevoke:invocation[0]';
|
"revokeVID": "done.invoke.vc-item.requestingRevoke:invocation[0]";
|
||||||
data: unknown;
|
"setCredential": "CREDENTIAL_DOWNLOADED" | "GET_VC_RESPONSE" | "STORE_RESPONSE";
|
||||||
};
|
"setLock": "done.invoke.vc-item.requestingLock:invocation[0]";
|
||||||
'error.platform.vc-item.verifyingCredential:invocation[0]': {
|
"setOtp": "INPUT_OTP";
|
||||||
type: 'error.platform.vc-item.verifyingCredential:invocation[0]';
|
"setOtpError": "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]";
|
||||||
data: unknown;
|
"setPublicKey": "done.invoke.vc-item.addKeyPair:invocation[0]";
|
||||||
};
|
"setRevoke": "done.invoke.vc-item.requestingRevoke:invocation[0]";
|
||||||
'xstate.init': { type: 'xstate.init' };
|
"setTag": "SAVE_TAG";
|
||||||
};
|
"setTransactionId": "INPUT_OTP" | "REVOKE_VC" | "done.invoke.vc-item.requestingBindingOtp:invocation[0]" | "done.invoke.vc-item.requestingOtp:invocation[0]" | "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]";
|
||||||
'invokeSrcNameMap': {
|
"setWalletBindingError": "error.platform.vc-item.addKeyPair:invocation[0]" | "error.platform.vc-item.addingWalletBindingId:invocation[0]";
|
||||||
checkStatus: 'done.invoke.checkStatus';
|
"setWalletBindingId": "done.invoke.vc-item.addingWalletBindingId:invocation[0]";
|
||||||
downloadCredential: 'done.invoke.downloadCredential';
|
"storeContext": "CREDENTIAL_DOWNLOADED" | "done.invoke.vc-item.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item.verifyingCredential:invocation[0]";
|
||||||
requestLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
|
"storeLock": "done.invoke.vc-item.requestingLock:invocation[0]";
|
||||||
requestOtp: 'done.invoke.vc-item.requestingOtp:invocation[0]';
|
"storeTag": "SAVE_TAG";
|
||||||
requestRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
|
"updateVc": "CREDENTIAL_DOWNLOADED" | "STORE_RESPONSE" | "done.invoke.vc-item.verifyingCredential:invocation[0]";
|
||||||
verifyCredential: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
};
|
||||||
};
|
eventsCausingDelays: {
|
||||||
'missingImplementations': {
|
|
||||||
actions: never;
|
};
|
||||||
services: never;
|
eventsCausingGuards: {
|
||||||
guards: never;
|
"hasCredential": "GET_VC_RESPONSE" | "STORE_RESPONSE";
|
||||||
delays: never;
|
"isVcValid": "";
|
||||||
};
|
};
|
||||||
'eventsCausingActions': {
|
eventsCausingServices: {
|
||||||
clearOtp:
|
"addWalletBindnigId": "done.invoke.vc-item.addKeyPair:invocation[0]";
|
||||||
| ''
|
"checkStatus": "STORE_RESPONSE";
|
||||||
| 'DISMISS'
|
"downloadCredential": "DOWNLOAD_READY";
|
||||||
| 'REVOKE_VC'
|
"generateKeyPair": "INPUT_OTP";
|
||||||
| 'STORE_RESPONSE'
|
"requestBindingOtp": "ADD_WALLET_BINDING_ID";
|
||||||
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
|
"requestLock": "INPUT_OTP";
|
||||||
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
|
"requestOtp": "LOCK_VC";
|
||||||
| 'error.platform.vc-item.requestingLock:invocation[0]'
|
"requestRevoke": "INPUT_OTP";
|
||||||
| 'error.platform.vc-item.requestingRevoke:invocation[0]'
|
"verifyCredential": "" | "VERIFY";
|
||||||
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
|
};
|
||||||
clearTransactionId:
|
matchesStates: "acceptingBindingOtp" | "acceptingOtpInput" | "acceptingRevokeInput" | "addKeyPair" | "addingWalletBindingId" | "checkingServerData" | "checkingServerData.checkingStatus" | "checkingServerData.downloadingCredential" | "checkingStore" | "checkingVc" | "checkingVerificationStatus" | "editingTag" | "idle" | "invalid" | "invalid.backend" | "invalid.otp" | "lockingVc" | "loggingRevoke" | "requestingBindingOtp" | "requestingLock" | "requestingOtp" | "requestingRevoke" | "revokingVc" | "showBindingStatus" | "storingTag" | "verifyingCredential" | { "checkingServerData"?: "checkingStatus" | "downloadingCredential";
|
||||||
| ''
|
"invalid"?: "backend" | "otp"; };
|
||||||
| 'DISMISS'
|
tags: never;
|
||||||
| 'STORE_RESPONSE'
|
}
|
||||||
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
|
|
||||||
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
|
|
||||||
logDownloaded: 'CREDENTIAL_DOWNLOADED';
|
|
||||||
logRevoked: 'STORE_RESPONSE';
|
|
||||||
markVcValid: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
|
||||||
requestStoredContext: 'GET_VC_RESPONSE' | 'REFRESH';
|
|
||||||
requestVcContext: 'xstate.init';
|
|
||||||
revokeVID: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
|
|
||||||
setCredential:
|
|
||||||
| 'CREDENTIAL_DOWNLOADED'
|
|
||||||
| 'GET_VC_RESPONSE'
|
|
||||||
| 'STORE_RESPONSE';
|
|
||||||
setLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
|
|
||||||
setOtp: 'INPUT_OTP';
|
|
||||||
setOtpError:
|
|
||||||
| 'error.platform.vc-item.requestingLock:invocation[0]'
|
|
||||||
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
|
|
||||||
setRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
|
|
||||||
setTag: 'SAVE_TAG';
|
|
||||||
setTransactionId:
|
|
||||||
| 'INPUT_OTP'
|
|
||||||
| 'REVOKE_VC'
|
|
||||||
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
|
|
||||||
| 'error.platform.vc-item.requestingLock:invocation[0]'
|
|
||||||
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
|
|
||||||
storeContext:
|
|
||||||
| 'CREDENTIAL_DOWNLOADED'
|
|
||||||
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
|
||||||
storeLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
|
|
||||||
storeTag: 'SAVE_TAG';
|
|
||||||
updateVc:
|
|
||||||
| 'CREDENTIAL_DOWNLOADED'
|
|
||||||
| 'STORE_RESPONSE'
|
|
||||||
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
|
||||||
};
|
|
||||||
'eventsCausingServices': {
|
|
||||||
checkStatus: 'STORE_RESPONSE';
|
|
||||||
downloadCredential: 'DOWNLOAD_READY';
|
|
||||||
requestLock: 'INPUT_OTP';
|
|
||||||
requestOtp: 'LOCK_VC';
|
|
||||||
requestRevoke: 'INPUT_OTP';
|
|
||||||
verifyCredential: '' | 'VERIFY';
|
|
||||||
};
|
|
||||||
'eventsCausingGuards': {
|
|
||||||
hasCredential: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
|
|
||||||
isVcValid: '';
|
|
||||||
};
|
|
||||||
'eventsCausingDelays': {};
|
|
||||||
'matchesStates':
|
|
||||||
| 'acceptingOtpInput'
|
|
||||||
| 'acceptingRevokeInput'
|
|
||||||
| 'checkingServerData'
|
|
||||||
| 'checkingServerData.checkingStatus'
|
|
||||||
| 'checkingServerData.downloadingCredential'
|
|
||||||
| 'checkingStore'
|
|
||||||
| 'checkingVc'
|
|
||||||
| 'checkingVerificationStatus'
|
|
||||||
| 'editingTag'
|
|
||||||
| 'idle'
|
|
||||||
| 'invalid'
|
|
||||||
| 'invalid.backend'
|
|
||||||
| 'invalid.otp'
|
|
||||||
| 'lockingVc'
|
|
||||||
| 'loggingRevoke'
|
|
||||||
| 'requestingLock'
|
|
||||||
| 'requestingOtp'
|
|
||||||
| 'requestingRevoke'
|
|
||||||
| 'revokingVc'
|
|
||||||
| 'storingTag'
|
|
||||||
| 'verifyingCredential'
|
|
||||||
| {
|
|
||||||
checkingServerData?: 'checkingStatus' | 'downloadingCredential';
|
|
||||||
invalid?: 'backend' | 'otp';
|
|
||||||
};
|
|
||||||
'tags': never;
|
|
||||||
}
|
|
||||||
22
package-lock.json
generated
22
package-lock.json
generated
@@ -56,8 +56,10 @@
|
|||||||
"react-native-popable": "^0.4.3",
|
"react-native-popable": "^0.4.3",
|
||||||
"react-native-qrcode-svg": "^6.1.1",
|
"react-native-qrcode-svg": "^6.1.1",
|
||||||
"react-native-restart": "^0.0.24",
|
"react-native-restart": "^0.0.24",
|
||||||
|
"react-native-rsa-native": "^2.0.5",
|
||||||
"react-native-safe-area-context": "3.3.2",
|
"react-native-safe-area-context": "3.3.2",
|
||||||
"react-native-screens": "~3.10.1",
|
"react-native-screens": "~3.10.1",
|
||||||
|
"react-native-secure-key-store": "^2.0.10",
|
||||||
"react-native-securerandom": "^1.0.0",
|
"react-native-securerandom": "^1.0.0",
|
||||||
"react-native-simple-markdown": "^1.1.0",
|
"react-native-simple-markdown": "^1.1.0",
|
||||||
"react-native-svg": "12.1.1",
|
"react-native-svg": "12.1.1",
|
||||||
@@ -21206,6 +21208,11 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-rsa-native": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-rsa-native/-/react-native-rsa-native-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-gwwvFSwGW5WKrpDyBQ/eTf1UrVABeAvMcT4YWemzPSUo6aHZs1kbBm2rXmwN5okhUzJsry5zjjz/qdx5GXRugQ=="
|
||||||
|
},
|
||||||
"node_modules/react-native-safe-area-context": {
|
"node_modules/react-native-safe-area-context": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
||||||
@@ -21228,6 +21235,11 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-secure-key-store": {
|
||||||
|
"version": "2.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-secure-key-store/-/react-native-secure-key-store-2.0.10.tgz",
|
||||||
|
"integrity": "sha512-K7aVlIGxyklnjhCidVexVgZF3LsgUD9GIxMy2NB/xkQsS9E2SJWkD/fJ56e25L2I6a9Mp1zuJrKnCtfBs1CvAw=="
|
||||||
|
},
|
||||||
"node_modules/react-native-securerandom": {
|
"node_modules/react-native-securerandom": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz",
|
||||||
@@ -44088,6 +44100,11 @@
|
|||||||
"integrity": "sha512-pvJNU3NwQk6bCG2gOWcQpZ4IxhtELB0K9gzmtixfsaTFbW1UXXHkJNjk1kHazcbH5hrD7QbUkR63fsAVh8X4VQ==",
|
"integrity": "sha512-pvJNU3NwQk6bCG2gOWcQpZ4IxhtELB0K9gzmtixfsaTFbW1UXXHkJNjk1kHazcbH5hrD7QbUkR63fsAVh8X4VQ==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"react-native-rsa-native": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-rsa-native/-/react-native-rsa-native-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-gwwvFSwGW5WKrpDyBQ/eTf1UrVABeAvMcT4YWemzPSUo6aHZs1kbBm2rXmwN5okhUzJsry5zjjz/qdx5GXRugQ=="
|
||||||
|
},
|
||||||
"react-native-safe-area-context": {
|
"react-native-safe-area-context": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
||||||
@@ -44103,6 +44120,11 @@
|
|||||||
"warn-once": "^0.1.0"
|
"warn-once": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-native-secure-key-store": {
|
||||||
|
"version": "2.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-secure-key-store/-/react-native-secure-key-store-2.0.10.tgz",
|
||||||
|
"integrity": "sha512-K7aVlIGxyklnjhCidVexVgZF3LsgUD9GIxMy2NB/xkQsS9E2SJWkD/fJ56e25L2I6a9Mp1zuJrKnCtfBs1CvAw=="
|
||||||
|
},
|
||||||
"react-native-securerandom": {
|
"react-native-securerandom": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz",
|
||||||
|
|||||||
@@ -61,8 +61,10 @@
|
|||||||
"react-native-popable": "^0.4.3",
|
"react-native-popable": "^0.4.3",
|
||||||
"react-native-qrcode-svg": "^6.1.1",
|
"react-native-qrcode-svg": "^6.1.1",
|
||||||
"react-native-restart": "^0.0.24",
|
"react-native-restart": "^0.0.24",
|
||||||
|
"react-native-rsa-native": "^2.0.5",
|
||||||
"react-native-safe-area-context": "3.3.2",
|
"react-native-safe-area-context": "3.3.2",
|
||||||
"react-native-screens": "~3.10.1",
|
"react-native-screens": "~3.10.1",
|
||||||
|
"react-native-secure-key-store": "^2.0.10",
|
||||||
"react-native-securerandom": "^1.0.0",
|
"react-native-securerandom": "^1.0.0",
|
||||||
"react-native-simple-markdown": "^1.1.0",
|
"react-native-simple-markdown": "^1.1.0",
|
||||||
"react-native-svg": "12.1.1",
|
"react-native-svg": "12.1.1",
|
||||||
|
|||||||
69
screens/Home/MyVcs/BindVcController.ts
Normal file
69
screens/Home/MyVcs/BindVcController.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { useSelector } from '@xstate/react';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import { ActorRefFrom } from 'xstate';
|
||||||
|
import {
|
||||||
|
selectIsRefreshingMyVcs,
|
||||||
|
selectMyVcs,
|
||||||
|
VcEvents,
|
||||||
|
} from '../../../machines/vc';
|
||||||
|
import { GlobalContext } from '../../../shared/GlobalContext';
|
||||||
|
import NetInfo from '@react-native-community/netinfo';
|
||||||
|
import { selectVcLabel } from '../../../machines/settings';
|
||||||
|
import {
|
||||||
|
selectAcceptingBindingOtp,
|
||||||
|
selectIsRequestBindingOtp,
|
||||||
|
selectOtpError,
|
||||||
|
selectShowBindingStatus,
|
||||||
|
selectWalletBindingError,
|
||||||
|
selectWalletBindingId,
|
||||||
|
VcItemEvents,
|
||||||
|
vcItemMachine,
|
||||||
|
} from '../../../machines/vcItem';
|
||||||
|
import { ModalProps } from '../../../components/ui/Modal';
|
||||||
|
|
||||||
|
export function useBindVcStatus(props: BindVcProps) {
|
||||||
|
const { appService } = useContext(GlobalContext);
|
||||||
|
const settingsService = appService.children.get('settings');
|
||||||
|
const vcService = appService.children.get('vc');
|
||||||
|
|
||||||
|
const netInfoFetch = (otp: string) => {
|
||||||
|
NetInfo.fetch().then((state) => {
|
||||||
|
if (state.isConnected) {
|
||||||
|
vcService.send(VcItemEvents.INPUT_OTP(otp));
|
||||||
|
} else {
|
||||||
|
vcService.send(VcItemEvents.DISMISS());
|
||||||
|
showToast('Request network failed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
vcKeys: useSelector(vcService, selectMyVcs),
|
||||||
|
vcLabel: useSelector(settingsService, selectVcLabel),
|
||||||
|
|
||||||
|
isRefreshingVcs: useSelector(vcService, selectIsRefreshingMyVcs),
|
||||||
|
isBindingOtp: useSelector(vcService, selectIsRequestBindingOtp),
|
||||||
|
walletAddress: useSelector(vcService, selectWalletBindingId),
|
||||||
|
isAcceptingBindingOtp: useSelector(vcService, selectAcceptingBindingOtp),
|
||||||
|
showBindingStatus: useSelector(vcService, selectShowBindingStatus),
|
||||||
|
walletBindingError: useSelector(vcService, selectWalletBindingError),
|
||||||
|
|
||||||
|
inputOtp: (otp: string) => {
|
||||||
|
netInfoFetch(otp);
|
||||||
|
},
|
||||||
|
otpError: useSelector(vcService, selectOtpError),
|
||||||
|
BINDING_DONE: () => vcService.send(VcItemEvents.BINDING_DONE()),
|
||||||
|
INPUT_OTP: (otp: string) => vcService.send(VcItemEvents.INPUT_OTP(otp)),
|
||||||
|
DISMISS: () => vcService.send(VcItemEvents.DISMISS()),
|
||||||
|
|
||||||
|
REFRESH: () => vcService.send(VcEvents.REFRESH_MY_VCS()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function showToast(arg0: string) {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BindVcProps extends ModalProps {
|
||||||
|
bindingError: string;
|
||||||
|
onDone: () => void;
|
||||||
|
}
|
||||||
55
screens/Home/MyVcs/BindVcStatus.tsx
Normal file
55
screens/Home/MyVcs/BindVcStatus.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import { Button, Icon } from 'react-native-elements';
|
||||||
|
import { Column, Text } from '../../../components/ui';
|
||||||
|
import { Theme } from '../../../components/ui/styleUtils';
|
||||||
|
import { useBindVcStatus, BindVcProps } from './BindVcController';
|
||||||
|
|
||||||
|
export const BindStatus: React.FC<BindVcProps> = (props) => {
|
||||||
|
const controller = useBindVcStatus(props);
|
||||||
|
var message: string = controller.walletBindingError;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={Theme.OtpVerificationStyles.viewContainer}>
|
||||||
|
<Column
|
||||||
|
fill
|
||||||
|
padding="32"
|
||||||
|
backgroundColor={Theme.Colors.whiteBackgroundColor}>
|
||||||
|
<View style={Theme.OtpVerificationStyles.close}>
|
||||||
|
<Icon name="close" onPress={() => props.onDismiss()} />
|
||||||
|
</View>
|
||||||
|
<Column fill align="space-between">
|
||||||
|
{!controller.walletBindingError && <WalletVerified />}
|
||||||
|
|
||||||
|
{controller.walletBindingError ? (
|
||||||
|
<Text
|
||||||
|
align="center"
|
||||||
|
color={Theme.Colors.errorMessage}
|
||||||
|
margin="16 0 0 0">
|
||||||
|
{{ message }}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text align="center" margin="16 0 0 0">
|
||||||
|
{'Successfully added to wallet'}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button title={'GO BACK'} onPress={props.onDone} />
|
||||||
|
</Column>
|
||||||
|
<Column fill></Column>
|
||||||
|
</Column>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const WalletVerified: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name="verified-user"
|
||||||
|
color={'green'}
|
||||||
|
size={40}
|
||||||
|
containerStyle={{ marginStart: 4, bottom: 1 }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DropdownIcon } from '../../components/DropdownIcon';
|
import { DropdownIcon } from '../../components/DropdownIcon';
|
||||||
import { TextEditOverlay } from '../../components/TextEditOverlay';
|
import { TextEditOverlay } from '../../components/TextEditOverlay';
|
||||||
import { Column } from '../../components/ui';
|
import { Column, Text } from '../../components/ui';
|
||||||
import { Modal } from '../../components/ui/Modal';
|
import { Modal } from '../../components/ui/Modal';
|
||||||
import { MessageOverlay } from '../../components/MessageOverlay';
|
import { MessageOverlay } from '../../components/MessageOverlay';
|
||||||
import { ToastItem } from '../../components/ui/ToastItem';
|
import { ToastItem } from '../../components/ui/ToastItem';
|
||||||
@@ -12,6 +12,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { VcDetails } from '../../components/VcDetails';
|
import { VcDetails } from '../../components/VcDetails';
|
||||||
|
|
||||||
import { OtpVerification } from './MyVcs/OtpVerification';
|
import { OtpVerification } from './MyVcs/OtpVerification';
|
||||||
|
import { BindStatus } from './MyVcs/BindVcStatus';
|
||||||
|
|
||||||
export const ViewVcModal: React.FC<ViewVcModalProps> = (props) => {
|
export const ViewVcModal: React.FC<ViewVcModalProps> = (props) => {
|
||||||
const { t } = useTranslation('ViewVcModal');
|
const { t } = useTranslation('ViewVcModal');
|
||||||
@@ -52,7 +53,17 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = (props) => {
|
|||||||
}>
|
}>
|
||||||
<Column scroll>
|
<Column scroll>
|
||||||
<Column fill>
|
<Column fill>
|
||||||
<VcDetails vc={controller.vc} />
|
<VcDetails
|
||||||
|
vc={controller.vc}
|
||||||
|
onBinding={() => controller.addtoWallet()}
|
||||||
|
isBindingPending={controller.isWalletBindingPending}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{controller.walletBindingError !== '' && (
|
||||||
|
<Text style={{ color: 'red', fontSize: 20 }}>
|
||||||
|
Error Occured : {controller.walletBindingError}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</Column>
|
</Column>
|
||||||
</Column>
|
</Column>
|
||||||
{controller.isEditingTag && (
|
{controller.isEditingTag && (
|
||||||
@@ -85,6 +96,24 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{controller.isAcceptingBindingOtp && (
|
||||||
|
<OtpVerification
|
||||||
|
isVisible={controller.isAcceptingBindingOtp}
|
||||||
|
onDismiss={controller.DISMISS}
|
||||||
|
onInputDone={controller.inputOtp}
|
||||||
|
error={controller.otpError}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{controller.showBindingStatus && (
|
||||||
|
<BindStatus
|
||||||
|
isVisible={controller.showBindingStatus}
|
||||||
|
bindingError={controller.walletBindingError}
|
||||||
|
onDismiss={controller.DISMISS}
|
||||||
|
onDone={controller.BINDING_DONE}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<MessageOverlay
|
<MessageOverlay
|
||||||
isVisible={controller.isRequestingOtp}
|
isVisible={controller.isRequestingOtp}
|
||||||
title={t('requestingOtp')}
|
title={t('requestingOtp')}
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ import {
|
|||||||
selectVc,
|
selectVc,
|
||||||
VcItemEvents,
|
VcItemEvents,
|
||||||
vcItemMachine,
|
vcItemMachine,
|
||||||
|
selectWalletBindingId,
|
||||||
|
selectWalletBindingError,
|
||||||
|
selectIsRequestBindingOtp,
|
||||||
|
selectAcceptingBindingOtp,
|
||||||
|
selectShowBindingStatus,
|
||||||
|
selectEmptyWalletBindingId,
|
||||||
} from '../../machines/vcItem';
|
} from '../../machines/vcItem';
|
||||||
import { selectPasscode } from '../../machines/auth';
|
import { selectPasscode } from '../../machines/auth';
|
||||||
import { biometricsMachine, selectIsSuccess } from '../../machines/biometrics';
|
import { biometricsMachine, selectIsSuccess } from '../../machines/biometrics';
|
||||||
@@ -125,6 +131,14 @@ export function useViewVcModal({
|
|||||||
),
|
),
|
||||||
isRequestingOtp: useSelector(vcItemActor, selectIsRequestingOtp),
|
isRequestingOtp: useSelector(vcItemActor, selectIsRequestingOtp),
|
||||||
storedPasscode: useSelector(authService, selectPasscode),
|
storedPasscode: useSelector(authService, selectPasscode),
|
||||||
|
isBindingOtp: useSelector(vcItemActor, selectIsRequestBindingOtp),
|
||||||
|
isAcceptingBindingOtp: useSelector(vcItemActor, selectAcceptingBindingOtp),
|
||||||
|
showBindingStatus: useSelector(vcItemActor, selectShowBindingStatus),
|
||||||
|
walletBindingError: useSelector(vcItemActor, selectWalletBindingError),
|
||||||
|
isWalletBindingPending: useSelector(
|
||||||
|
vcItemActor,
|
||||||
|
selectEmptyWalletBindingId
|
||||||
|
),
|
||||||
|
|
||||||
CONFIRM_REVOKE_VC: () => {
|
CONFIRM_REVOKE_VC: () => {
|
||||||
setRevoking(true);
|
setRevoking(true);
|
||||||
@@ -136,6 +150,9 @@ export function useViewVcModal({
|
|||||||
setReAuthenticating,
|
setReAuthenticating,
|
||||||
setRevoking,
|
setRevoking,
|
||||||
onError,
|
onError,
|
||||||
|
addtoWallet: () => {
|
||||||
|
vcItemActor.send(VcItemEvents.ADD_WALLET_BINDING_ID());
|
||||||
|
},
|
||||||
lockVc: () => {
|
lockVc: () => {
|
||||||
vcItemActor.send(VcItemEvents.LOCK_VC());
|
vcItemActor.send(VcItemEvents.LOCK_VC());
|
||||||
},
|
},
|
||||||
@@ -145,10 +162,12 @@ export function useViewVcModal({
|
|||||||
revokeVc: (otp: string) => {
|
revokeVc: (otp: string) => {
|
||||||
netInfoFetch(otp);
|
netInfoFetch(otp);
|
||||||
},
|
},
|
||||||
|
ADD_WALLET: () => vcItemActor.send(VcItemEvents.ADD_WALLET_BINDING_ID()),
|
||||||
onSuccess,
|
onSuccess,
|
||||||
EDIT_TAG: () => vcItemActor.send(VcItemEvents.EDIT_TAG()),
|
EDIT_TAG: () => vcItemActor.send(VcItemEvents.EDIT_TAG()),
|
||||||
SAVE_TAG: (tag: string) => vcItemActor.send(VcItemEvents.SAVE_TAG(tag)),
|
SAVE_TAG: (tag: string) => vcItemActor.send(VcItemEvents.SAVE_TAG(tag)),
|
||||||
DISMISS: () => vcItemActor.send(VcItemEvents.DISMISS()),
|
DISMISS: () => vcItemActor.send(VcItemEvents.DISMISS()),
|
||||||
|
BINDING_DONE: () => vcItemActor.send(VcItemEvents.BINDING_DONE()),
|
||||||
LOCK_VC: () => vcItemActor.send(VcItemEvents.LOCK_VC()),
|
LOCK_VC: () => vcItemActor.send(VcItemEvents.LOCK_VC()),
|
||||||
INPUT_OTP: (otp: string) => vcItemActor.send(VcItemEvents.INPUT_OTP(otp)),
|
INPUT_OTP: (otp: string) => vcItemActor.send(VcItemEvents.INPUT_OTP(otp)),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const ReceiveVcScreen: React.FC = () => {
|
|||||||
<Text weight="semibold" margin="24 24 0 24">
|
<Text weight="semibold" margin="24 24 0 24">
|
||||||
{t('header', { vcLabel: controller.vcLabel.singular })}
|
{t('header', { vcLabel: controller.vcLabel.singular })}
|
||||||
</Text>
|
</Text>
|
||||||
<VcDetails vc={controller.incomingVc} />
|
<VcDetails vc={controller.incomingVc} isBindingPending={false} />
|
||||||
</Column>
|
</Column>
|
||||||
<Column padding="0 24" margin="32 0 0 0">
|
<Column padding="0 24" margin="32 0 0 0">
|
||||||
{controller.incomingVc.shouldVerifyPresence ? (
|
{controller.incomingVc.shouldVerifyPresence ? (
|
||||||
|
|||||||
13
shared/keystore/SecureKeystore.ts
Normal file
13
shared/keystore/SecureKeystore.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import RNSecureKeyStore, { ACCESSIBLE } from 'react-native-secure-key-store';
|
||||||
|
|
||||||
|
export async function savePrivateKey(id: string, privateKey: string) {
|
||||||
|
var result = await RNSecureKeyStore.set(id, privateKey, {
|
||||||
|
accessible: ACCESSIBLE.ALWAYS_THIS_DEVICE_ONLY,
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPrivateKey(id: string) {
|
||||||
|
var result = await RNSecureKeyStore.get(id);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
5
shared/rsakeypair/rsaKeypair.ts
Normal file
5
shared/rsakeypair/rsaKeypair.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { KeyPair, RSA } from 'react-native-rsa-native';
|
||||||
|
|
||||||
|
export function generateKeys(): Promise<KeyPair> {
|
||||||
|
return Promise.resolve(RSA.generateKeys(4096));
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ export interface VC {
|
|||||||
locked: boolean;
|
locked: boolean;
|
||||||
reason?: VCSharingReason[];
|
reason?: VCSharingReason[];
|
||||||
shouldVerifyPresence?: boolean;
|
shouldVerifyPresence?: boolean;
|
||||||
|
walletBindingId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VCSharingReason {
|
export interface VCSharingReason {
|
||||||
|
|||||||
Reference in New Issue
Block a user