diff --git a/.gitignore b/.gitignore
index 89f70fad..758474b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -112,3 +112,21 @@ android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
+package.json
+yarn.lock
+android/app/src/main/assets/index.android.bundle
+android/app/src/main/res/drawable-hdpi/node_modules_reactnavigation_drawer_src_views_assets_toggledrawericon.png
+android/app/src/main/res/drawable-hdpi/node_modules_reactnavigation_elements_src_assets_backicon.png
+android/app/src/main/res/drawable-mdpi/node_modules_reactnative_libraries_newappscreen_components_logo.png
+android/app/src/main/res/drawable-mdpi/node_modules_reactnavigation_drawer_src_views_assets_toggledrawericon.png
+android/app/src/main/res/drawable-mdpi/node_modules_reactnavigation_elements_src_assets_backicon.png
+android/app/src/main/res/drawable-mdpi/node_modules_reactnavigation_elements_src_assets_backiconmask.png
+android/app/src/main/res/drawable-mdpi/src_images_customicons_coinsicon.png
+android/app/src/main/res/drawable-mdpi/src_images_customicons_recovericon.png
+android/app/src/main/res/drawable-mdpi/src_images_customicons_revokeicon.png
+android/app/src/main/res/drawable-xhdpi/node_modules_reactnavigation_drawer_src_views_assets_toggledrawericon.png
+android/app/src/main/res/drawable-xhdpi/node_modules_reactnavigation_elements_src_assets_backicon.png
+android/app/src/main/res/drawable-xxhdpi/node_modules_reactnavigation_drawer_src_views_assets_toggledrawericon.png
+android/app/src/main/res/drawable-xxhdpi/node_modules_reactnavigation_elements_src_assets_backicon.png
+android/app/src/main/res/drawable-xxxhdpi/node_modules_reactnavigation_drawer_src_views_assets_toggledrawericon.png
+android/app/src/main/res/drawable-xxxhdpi/node_modules_reactnavigation_elements_src_assets_backicon.png
diff --git a/env/main.android.json b/env/main.android.json
index 26469f8f..5b0581af 100644
--- a/env/main.android.json
+++ b/env/main.android.json
@@ -43,6 +43,7 @@
"SETTINGS_STORAGE_INTERNAL_KEY": "settings",
"BLOCK_HEIGHT_STORAGE_INTERNAL_KEY": "blockHeight",
"PERSONAL_DATA_STORAGE_INTERNAL_KEY": "personal",
+ "ATTESTATION_DATA_STORAGE_INTERNAL_KEY": "attestation",
"SERVICE_STORAGE_INTERNAL_KEY": "serviceStoredData",
"NOTIFICATIONS_STORAGE_INTERNAL_KEY": "notifications",
"WIDGET_STORAGE_INTERNAL_KEY": "widgets",
diff --git a/env/main.ios.json b/env/main.ios.json
index 899b32af..030b2c83 100644
--- a/env/main.ios.json
+++ b/env/main.ios.json
@@ -43,6 +43,7 @@
"SETTINGS_STORAGE_INTERNAL_KEY": "settings",
"BLOCK_HEIGHT_STORAGE_INTERNAL_KEY": "blockHeight",
"PERSONAL_DATA_STORAGE_INTERNAL_KEY": "personal",
+ "ATTESTATION_DATA_STORAGE_INTERNAL_KEY": "attestation",
"SERVICE_STORAGE_INTERNAL_KEY": "serviceStoredData",
"NOTIFICATIONS_STORAGE_INTERNAL_KEY": "notifications",
"WIDGET_STORAGE_INTERNAL_KEY": "widgets",
diff --git a/index.js b/index.js
index 5a4eb85b..41d1a4ca 100644
--- a/index.js
+++ b/index.js
@@ -16,9 +16,9 @@ const IGNORED_LOGS = [
LogBox.ignoreLogs(IGNORED_LOGS);
+import './shims/crypto.js';
import App from './App';
import {name as appName} from './app.json';
-import './shims/crypto.js';
import './shims/stringify.js';
AppRegistry.registerComponent(appName, () => App);
diff --git a/ios/assets/env/main.json b/ios/assets/env/main.json
index 899b32af..030b2c83 100644
--- a/ios/assets/env/main.json
+++ b/ios/assets/env/main.json
@@ -43,6 +43,7 @@
"SETTINGS_STORAGE_INTERNAL_KEY": "settings",
"BLOCK_HEIGHT_STORAGE_INTERNAL_KEY": "blockHeight",
"PERSONAL_DATA_STORAGE_INTERNAL_KEY": "personal",
+ "ATTESTATION_DATA_STORAGE_INTERNAL_KEY": "attestation",
"SERVICE_STORAGE_INTERNAL_KEY": "serviceStoredData",
"NOTIFICATIONS_STORAGE_INTERNAL_KEY": "notifications",
"WIDGET_STORAGE_INTERNAL_KEY": "widgets",
diff --git a/metro.config.js b/metro.config.js
index ba3e67d0..d654bbc4 100644
--- a/metro.config.js
+++ b/metro.config.js
@@ -19,6 +19,10 @@ module.exports = (async () => {
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
+ extraNodeModules: {
+ stream: require.resolve('readable-stream'),
+ crypto: require.resolve('react-native-crypto'),
+ }
},
};
})();
diff --git a/package.json b/package.json
old mode 100644
new mode 100755
index 3a263e1d..73a74504
--- a/package.json
+++ b/package.json
@@ -117,7 +117,7 @@
"uuid": "8.0.0",
"version_compare": "0.0.3",
"verus-pay-utils": "git+https://github.com/michaeltout/verus-pay-utils.git",
- "verus-typescript-primitives": "git+https://github.com/VerusCoin/verus-typescript-primitives.git",
+ "verus-typescript-primitives": "file:d:/dev/verus-typescript-primitives",
"verus-zkedid-utils": "git+https://github.com/michaeltout/verus-zkedid-utils.git",
"verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git",
"verusid-ts-client": "git+https://github.com/VerusCoin/verusid-ts-client.git",
@@ -220,8 +220,10 @@
"@sideway/formula": "3.0.1",
"@babel/traverse": "7.23.2",
"@babel/core": "7.21.3",
+ "@bitgo/utxo-lib": "git+https://github.com/VerusCoin/BitGoJS.git#7c754d4a5920198d9fe6827d3e23bd5cf431f264",
"blake2b-wasm": "https://github.com/michaeltout/blake2b-wasm/",
"@bitgo/blake2b-wasm": "https://github.com/michaeltout/blake2b-wasm/",
+ "verus-typescript-primitives": "file:d:/dev/verus-typescript-primitives",
"browserify-sign": "4.2.2"
},
"jest": {
diff --git a/shim.js b/shim.js
new file mode 100644
index 00000000..812d6b45
--- /dev/null
+++ b/shim.js
@@ -0,0 +1,26 @@
+if (typeof __dirname === 'undefined') global.__dirname = '/'
+if (typeof __filename === 'undefined') global.__filename = ''
+if (typeof process === 'undefined') {
+ global.process = require('process')
+} else {
+ const bProcess = require('process')
+ for (var p in bProcess) {
+ if (!(p in process)) {
+ process[p] = bProcess[p]
+ }
+ }
+}
+
+process.browser = false
+if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer
+
+// global.location = global.location || { port: 80 }
+const isDev = typeof __DEV__ === 'boolean' && __DEV__
+process.env['NODE_ENV'] = isDev ? 'development' : 'production'
+if (typeof localStorage !== 'undefined') {
+ localStorage.debug = isDev ? '*' : ''
+}
+
+// If using the crypto shim, uncomment the following line to ensure
+// crypto is loaded first, so it can populate global.crypto
+// require('crypto')
diff --git a/src/actions/actions/account/dispatchers/account.js b/src/actions/actions/account/dispatchers/account.js
index 22e2b6a1..16aac85e 100644
--- a/src/actions/actions/account/dispatchers/account.js
+++ b/src/actions/actions/account/dispatchers/account.js
@@ -8,6 +8,7 @@ import {
clearChainLifecycle,
} from "../../intervals/dispatchers/lifecycleManager";
import { initPersonalDataForUser } from "../../personal/dispatchers/personal";
+import { initAttestationDataForUser } from "../../attestations/dispatchers/attestations";
import { initServiceStoredDataForUser } from "../../services/dispatchers/services";
import { fetchUsers, validateLogin } from "../../UserData";
import { initSettings, saveGeneralSettings } from "../../WalletSettings";
@@ -100,6 +101,7 @@ export const initializeAccountData = async (
activateServiceLifecycle();
await initPersonalDataForUser(account.accountHash);
+ await initAttestationDataForUser(account.accountHash);
store.dispatch(signIntoAuthenticatedAccount());
} else {
throw new Error(
diff --git a/src/actions/actions/attestations/creators/attestations.js b/src/actions/actions/attestations/creators/attestations.js
new file mode 100644
index 00000000..bef5efda
--- /dev/null
+++ b/src/actions/actions/attestations/creators/attestations.js
@@ -0,0 +1,10 @@
+import { SET_ATTESTATION_DATA } from "../../../../utils/constants/storeType"
+
+export const setAttestationData = (
+ data = {
+ attestations_provisioned: null
+ }
+) => ({
+ type: SET_ATTESTATION_DATA,
+ data,
+});
\ No newline at end of file
diff --git a/src/actions/actions/attestations/dispatchers/attestations.js b/src/actions/actions/attestations/dispatchers/attestations.js
new file mode 100644
index 00000000..23167a19
--- /dev/null
+++ b/src/actions/actions/attestations/dispatchers/attestations.js
@@ -0,0 +1,31 @@
+import store from "../../../../store"
+import { deleteAttestationDataForUser, loadAttestationDataForUser, storeAttestationDataForUser } from "../../../../utils/nativeStore/attestationDataStorage"
+import { requestPassword } from "../../../../utils/auth/authBox"
+import { encryptkey } from "../../../../utils/seedCrypt"
+import { setAttestationData } from "../creators/attestations"
+
+export const saveEncryptedAttestationDataForUser = async (encryptedData = {}, accountHash) => {
+ const attestationData = await storeAttestationDataForUser(encryptedData, accountHash)
+ store.dispatch(setAttestationData(encryptedData))
+ return attestationData
+}
+
+export const clearEncryptedAttestationDataForUser = async (accountHash) => {
+ const attestationData = await deleteAttestationDataForUser(accountHash)
+ store.dispatch(setAttestationData({}))
+ return attestationData
+}
+
+export const modifyAttestationDataForUser = async (data = {}, dataType, accountHash) => {
+ let attestationData = {...(await loadAttestationDataForUser(accountHash))}
+ attestationData[dataType] = await encryptkey(await requestPassword(), JSON.stringify(data))
+ await saveEncryptedAttestationDataForUser(attestationData, accountHash)
+
+ return data
+}
+
+export const initAttestationDataForUser = async (accountHash) => {
+ const attestationData = await loadAttestationDataForUser(accountHash)
+ store.dispatch(setAttestationData(attestationData))
+ return attestationData
+}
\ No newline at end of file
diff --git a/src/containers/DeepLink/DeepLink.js b/src/containers/DeepLink/DeepLink.js
index d6f310c1..ea8f50bb 100644
--- a/src/containers/DeepLink/DeepLink.js
+++ b/src/containers/DeepLink/DeepLink.js
@@ -21,7 +21,12 @@ import { getCurrency, getIdentity } from '../../utils/api/channels/verusid/callC
import { convertFqnToDisplayFormat } from '../../utils/fullyqualifiedname';
import { resetDeeplinkData } from '../../actions/actionCreators';
-const authorizedPermissions = [primitives.IDENTITY_VIEW.vdxfid,/*TODO: primitives.IDENTITY_AGREEMENT.vdxfid, primitives.ATTESTATION_READ_REQUEST.vdxfid */]
+const authorizedPermissions = [primitives.IDENTITY_VIEW.vdxfid,
+ primitives.IDENTITY_AGREEMENT.vdxfid,
+ primitives.ATTESTATION_READ_REQUEST.vdxfid,
+ primitives.PROFILE_DATA_VIEW_REQUEST.vdxfid,
+ primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid,
+]
import { CoinDirectory } from '../../utils/CoinData/CoinDirectory';
import BigNumber from 'bignumber.js';
import { blocksToTime, satsToCoins } from '../../utils/math';
diff --git a/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.js b/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.js
new file mode 100644
index 00000000..35fd6b91
--- /dev/null
+++ b/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.js
@@ -0,0 +1,180 @@
+import { Component } from "react"
+import { connect } from 'react-redux'
+import { createAlert, resolveAlert } from "../../../actions/actions/alert/dispatchers/alert"
+import { LoginReceiveAttestationRender } from "./LoginReceiveAttestation.render"
+import { primitives } from "verusid-ts-client"
+import { VDXFDataToUniValueArray } from "verus-typescript-primitives/dist/vdxf/classes/DataDescriptor.js";
+import * as VDXF_Data from "verus-typescript-primitives/dist/vdxf/vdxfDataKeys";
+import { SignatureData } from "verus-typescript-primitives/dist/vdxf/classes/SignatureData";
+import { verifyHash } from "../../../utils/api/channels/vrpc/requests/verifyHash";
+import { getSignatureInfo } from "../../../utils/api/channels/vrpc/requests/getSignatureInfo";
+const { ATTESTATION_NAME } = primitives;
+import { IdentityVdxfidMap } from "verus-typescript-primitives/dist/vdxf/classes/IdentityData";
+import { ATTESTATIONS_PROVISIONED } from "../../../utils/constants/attestations";
+import { modifyAttestationDataForUser } from "../../../actions/actions/attestations/dispatchers/attestations";
+
+class LoginReceiveAttestation extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ loginConsent: null,
+ loading: false,
+ ready: false,
+ personalDataURL: "",
+ signerFqn: this.props.route.params.signerFqn,
+ attestationName: "",
+ attestationData: {},
+ completeAttestaton: {},
+ };
+ const dfg = 2111111
+ }
+
+ componentDidMount() {
+ this.updateDisplay();
+ }
+
+ cancel = () => {
+ if (this.props.route.params.cancel) {
+ this.props.route.params.cancel.cancel()
+ }
+ }
+
+ validateAttestation = async (signatureData) => {
+
+ const sigObject = SignatureData.fromJson(signatureData);
+
+ const sigInfo = await getSignatureInfo(
+ sigObject.systemID,
+ sigObject.identityID,
+ sigObject.signatureAsVch.toString('base64'),
+ );
+
+ return await verifyHash(sigObject.systemID, sigObject.identityID, sigObject.signatureAsVch.toString('base64'), sigObject.getIdentityHash(sigInfo));
+
+ }
+
+ getAttestationData = (dataDescriptors) => {
+
+ const data = {};
+ dataDescriptors.forEach((dataDescriptor) => {
+ const label = dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].label;
+ let key = "";
+
+ if (label === ATTESTATION_NAME.vdxfid) {
+ key = `Attestation name`
+ } else {
+ key = IdentityVdxfidMap[label]?.name || label;
+ }
+
+ const mime = dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].mimetype || "";
+ if (mime.startsWith("text/")) {
+ data[key] = { "message": dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].objectdata.message };
+ } else if (mime.startsWith("image/")) {
+ if (mime === "image/jpeg" || mime === "image/png") {
+ data[key] = { "image": `data:${mime};base64,${Buffer.from(dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].objectdata, "hex").toString("base64")}` };
+ }
+ }
+ });
+
+ return data;
+
+ }
+
+ updateDisplay() {
+ const { deeplinkData } = this.props.route.params
+ const loginConsent = new primitives.LoginConsentRequest(deeplinkData);
+
+ if (loginConsent.challenge.attestations && loginConsent.challenge.attestations.length > 1) {
+ createAlert("Error", "Only one attestation is allowed to be received at a time.");
+ this.cancel();
+ return;
+ }
+
+ const checkAttestation = loginConsent.challenge.attestations[0];
+
+ if (checkAttestation.vdxfkey === primitives.ATTESTATION_PROVISION_OBJECT.vdxfid) {
+
+ const dataDescriptorObject = VDXFDataToUniValueArray(Buffer.from(checkAttestation.data, "hex"));
+
+ if (!Array.isArray(dataDescriptorObject)) {
+ createAlert("Error", "Invalid data descriptor object in Attestation.");
+ this.cancel();
+ return;
+ }
+
+ if (dataDescriptorObject.some((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.DataURLKey().vdxfid)) {
+
+ // TODO: Handle fetch data from URL
+ }
+ else if (dataDescriptorObject.some((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.MMRDescriptorKey().vdxfid) &&
+ dataDescriptorObject.some((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.SignatureDataKey().vdxfid)) {
+
+ const signatureData = dataDescriptorObject.find((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.SignatureDataKey().vdxfid)[VDXF_Data.SignatureDataKey().vdxfid];
+ const mmrData = dataDescriptorObject.find((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.MMRDescriptorKey().vdxfid)[VDXF_Data.MMRDescriptorKey().vdxfid];
+
+ if (!this.validateAttestation(signatureData) || mmrData.mmrroot.objectdata != signatureData.signaturehash) {
+ createAlert("Error", "Invalid attestation signature.");
+ this.cancel();
+ return;
+ }
+
+ const attestationName = mmrData.datadescriptors.find((dataDescriptor) => dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].label === ATTESTATION_NAME.vdxfid)?.objectdata;
+
+ if (!attestationName || Object.values(attestationName)[0].label !== ATTESTATION_NAME.vdxfid) {
+ createAlert("Error", "Attestation has no name.");
+ this.cancel();
+ return;
+ } else {
+
+ this.setState({ attestationName: Object.values(attestationName)[0].objectdata.message });
+
+ }
+
+ const containingData = this.getAttestationData(mmrData.datadescriptors);
+ this.setState({ attestationData: containingData,
+ completeAttestaton: {[loginConsent.getChallengeHash(1).toString('base64')]:{ name: Object.values(attestationName)[0].objectdata.message,
+ signer: this.state.signerFqn,
+ data: dataDescriptorObject}}
+ });
+
+ } else {
+ createAlert("Error", "Invalid attestation type.");
+ this.cancel();
+ return;
+ }
+
+ }
+ }
+
+ handleContinue() {
+ this.setState(
+ { loading: true },
+ async () => {
+ await modifyAttestationDataForUser(
+ this.state.completeAttestaton,
+ ATTESTATIONS_PROVISIONED,
+ this.props.activeAccount.accountHash
+ );
+
+ this.setState({ loading: false });
+ this.props.route.params.onGoBack(true);
+ this.props.navigation.goBack();
+ this.cancel();
+ }
+ );
+ };
+
+
+ render() {
+ return LoginReceiveAttestationRender.call(this);
+ }
+}
+
+const mapStateToProps = (state) => {
+ return {
+ activeAccount: state.authentication.activeAccount,
+ encryptedPersonalData: state.personal
+ }
+};
+
+export default connect(mapStateToProps)(LoginReceiveAttestation);
\ No newline at end of file
diff --git a/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.render.js b/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.render.js
new file mode 100644
index 00000000..7c08dd2b
--- /dev/null
+++ b/src/containers/DeepLink/LoginReceiveAttestation/LoginReceiveAttestation.render.js
@@ -0,0 +1,67 @@
+import React from "react";
+import { SafeAreaView, ScrollView, View, Image } from "react-native";
+import { Divider, List, Button, Text } from "react-native-paper";
+import Styles from "../../../styles";
+import Colors from '../../../globals/colors';
+import {convertFqnToDisplayFormat} from '../../../utils/fullyqualifiedname';
+
+export const LoginReceiveAttestationRender = function (props) {
+
+ return (
+
+
+
+
+
+ Agree to Receive the following attestation.
+
+
+ {`${convertFqnToDisplayFormat(this.state.attestationName)}`}
+
+
+ {`From: `}{`${this.state.signerFqn}`}
+
+ {this.state.attestationData && Object.keys(this.state.attestationData).map(request => {
+ return (
+
+ this.state.attestationData[request]?.image ? : null}
+ />
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/containers/DeepLink/LoginRequestInfo/LoginRequestInfo.js b/src/containers/DeepLink/LoginRequestInfo/LoginRequestInfo.js
index 1c808c4e..27671d7a 100644
--- a/src/containers/DeepLink/LoginRequestInfo/LoginRequestInfo.js
+++ b/src/containers/DeepLink/LoginRequestInfo/LoginRequestInfo.js
@@ -1,5 +1,5 @@
-import React, {useState, useEffect} from 'react';
-import {SafeAreaView, ScrollView, TouchableOpacity, View} from 'react-native';
+import React, { useState, useEffect } from 'react';
+import { SafeAreaView, ScrollView, TouchableOpacity, View } from 'react-native';
import Styles from '../../../styles/index';
import { primitives } from "verusid-ts-client"
import { Button, Divider, List, Portal, Text } from 'react-native-paper';
@@ -29,6 +29,8 @@ const LoginRequestInfo = props => {
const signedIn = useSelector(state => state.authentication.signedIn)
const passthrough = useSelector((state) => state.deeplink.passthrough);
const sendModalType = useSelector(state => state.sendModal.type)
+ const [permissions, setExtraPermissions] = useState(null);
+ const [ready, setReady] = useState(false);
const dispatch = useDispatch()
@@ -56,6 +58,8 @@ const LoginRequestInfo = props => {
} else {
if (passthrough?.fqnToAutoLink) {
mainLoginMessage = `VerusID from ${signerFqn} now ready to link`
+ } else if (challenge.attestations && challenge.attestations.length > 0) {
+ mainLoginMessage = `Would you like to accept an attestation from ${signerFqn}?`
} else {
mainLoginMessage = `Would you like to request a VerusID from ${signerFqn}?`
}
@@ -77,7 +81,7 @@ const LoginRequestInfo = props => {
loadFriendlyNames: async () => {
try {
const identityObj = await getVerusId(chain, iAddress);
-
+
return getFriendlyNameMap(CoinDirectory.getBasicCoinObj(chain), identityObj);
} catch (e) {
return {
@@ -122,6 +126,121 @@ const LoginRequestInfo = props => {
} else setLoading(true)
}, [sendModalType]);
+ const buildAlert = (request) => {
+
+ const setPermission = () => {
+ const _permissions = permissions.map(permission => {
+ if (permission.vdxfkey === request.vdxfkey) {
+ return { ...permission, agreed: true };
+ }
+ return permission;
+ });
+ setExtraPermissions(_permissions);
+ }
+
+ if (request.agreed) return;
+
+ if (request.viewAttestation) {
+ if (!signedIn) return;
+ props.navigation.navigate("LoginShareAttestation",
+ {
+ deeplinkData,
+ fromService: false,
+ cancel: { cancel },
+ onGoBack: (data) => data ? setPermission(data) : () => { },
+ signerFqn
+ });
+ return;
+ }
+ else if (request.attestationToAccept) {
+ if (!signedIn) return;
+ props.navigation.navigate("LoginReceiveAttestation",
+ {
+ deeplinkData,
+ fromService: false,
+ cancel: { cancel },
+ onGoBack: (data) => data ? setPermission(data) : () => { },
+ signerFqn
+ });
+ return;
+ }
+ else if (request.openProfile) {
+ if (!signedIn) return;
+ props.navigation.navigate("PersonalSelectData",
+ {
+ deeplinkData,
+ fromService: false,
+ cancel: { cancel },
+ onGoBack: (data) => data ? setPermission(data) : () => { },
+ signerFqn
+ });
+ return;
+ }
+
+ return createAlert(
+ request.title,
+ request.data,
+ [
+ {
+ text: 'DECLINE',
+ onPress: () => resolveAlert(false),
+ style: 'cancel',
+ },
+ {
+ text: 'ACCEPT', onPress: () => {
+ setPermission();
+ resolveAlert(true)
+ }
+ },
+ ],
+ { cancelable: true });
+ }
+
+ useEffect(() => {
+
+ if (req && req.challenge && req.challenge.requested_access) {
+ var loginTemp = [];
+ if (req.challenge.requested_access.length === 1 && req.challenge.requested_access.some(value => value.vdxfkey === primitives.IDENTITY_VIEW.vdxfid)) {
+ if (req.challenge.attestations && req.challenge.attestations.length > 0) {
+ loginTemp.push({ data: "Accept attestation", title: "Attestation Provisioning Request", attestationToAccept: true, agreed: false });
+ } else {
+ setReady(true);
+ }
+ } else {
+ for (let i = 0; i < req.challenge.requested_access.length; i++) {
+ var tempdata = {};
+
+ if (req.challenge.requested_access[i].vdxfkey === primitives.IDENTITY_VIEW.vdxfid) {
+ continue;
+ } else if (req.challenge.requested_access[i].vdxfkey === primitives.IDENTITY_AGREEMENT.vdxfid) {
+ tempdata = { data: req.challenge.requested_access[i].toJson().data, title: "Agreement to accept" }
+ } else if (req.challenge.requested_access[i].vdxfkey === primitives.ATTESTATION_READ_REQUEST.vdxfid) {
+ tempdata = { data: "Agree to share attestation data", title: "Attestation View Request", viewAttestation: true }
+ } else if (req.challenge.requested_access[i].vdxfkey === primitives.PROFILE_DATA_VIEW_REQUEST.vdxfid) {
+ tempdata = { data: "Agree to share profile data", title: "Personal Data Input Request", openProfile: true }
+ } else if (req.challenge.requested_access[i].vdxfkey === primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid) {
+ continue;
+ }
+ loginTemp.push({ vdxfkey: req.challenge.requested_access[i].vdxfkey, ...tempdata, agreed: false })
+ }
+ }
+
+ if (loginTemp.length > 0) setExtraPermissions(loginTemp);
+ }
+ }, [req]);
+
+ useEffect(() => {
+ if (permissions) {
+ for (let i = 0; i < permissions.length; i++) {
+ if (!permissions[i].agreed)
+ return;
+ }
+ setReady(true);
+ }
+ }, [permissions]);
+
+
+
const addRootSystem = async () => {
setLoading(true)
@@ -137,28 +256,28 @@ const LoginRequestInfo = props => {
: activeAccount.keyDerivationVersion,
),
);
-
+
const addCoinAction = await addCoin(
fullCoinData,
activeCoinList,
activeAccount.id,
fullCoinData.compatible_channels,
);
-
+
if (addCoinAction) {
dispatch(addCoinAction);
-
+
const setUserCoinsAction = setUserCoins(
activeCoinList,
activeAccount.id,
);
dispatch(setUserCoinsAction);
-
+
refreshActiveChainLifecycles(setUserCoinsAction.payload.activeCoinsForUser);
} else {
createAlert("Error", "Error adding coin")
}
- } catch(e) {
+ } catch (e) {
createAlert("Error", e.message)
}
@@ -175,7 +294,7 @@ const LoginRequestInfo = props => {
onPress: () => resolveAlert(false),
style: 'cancel',
},
- {text: 'Yes', onPress: () => resolveAlert(true)},
+ { text: 'Yes', onPress: () => resolveAlert(true) },
],
{
cancelable: true,
@@ -189,15 +308,20 @@ const LoginRequestInfo = props => {
}
}
- const handleContinue = () => {
+ const handleContinue = async () => {
if (signedIn) {
+ if (!ready) {
+ for (let i = 0; i < permissions.length; i++) {
+ const result = await buildAlert(permissions[i], i);
+ if (!result) return;
+ }
+ }
const coinObj = CoinDirectory.findCoinObj(chain_id);
if (!!coinObj.testnet != isTestnet) {
createAlert(
"Incorrect profile type",
- `Please login to a ${
- coinObj.testnet ? 'testnet' : 'mainnet'
- } profile to use this login request.`, );
+ `Please login to a ${coinObj.testnet ? 'testnet' : 'mainnet'
+ } profile to use this login request.`,);
return;
}
else if (!rootSystemAdded) {
@@ -234,15 +358,13 @@ const LoginRequestInfo = props => {
const data = {
[SEND_MODAL_USER_ALLOWLIST]: allowList
}
-
+
openAuthenticateUserModal(data);
} else {
createAlert(
"Cannot continue",
- `No ${
- coinObj.testnet ? 'testnet' : 'mainnet'
- } profiles found, cannot respond to ${
- coinObj.testnet ? 'testnet' : 'mainnet'
+ `No ${coinObj.testnet ? 'testnet' : 'mainnet'
+ } profiles found, cannot respond to ${coinObj.testnet ? 'testnet' : 'mainnet'
} login request.`,
);
}
@@ -263,7 +385,7 @@ const LoginRequestInfo = props => {
contentContainerStyle={Styles.focalCenter}>
-
+
{mainLoginMessage}
@@ -294,6 +416,23 @@ const LoginRequestInfo = props => {
+ {permissions && permissions.map((request, index) => {
+ return (
+ buildAlert(request)}>
+ (
+
+ )} />
+
+
+ );
+ })}
{
}}>
diff --git a/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.js b/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.js
new file mode 100644
index 00000000..6511545a
--- /dev/null
+++ b/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.js
@@ -0,0 +1,207 @@
+import moment from "moment";
+import { Component } from "react"
+import { connect } from 'react-redux'
+import { createAlert, resolveAlert } from "../../../actions/actions/alert/dispatchers/alert"
+import { modifyPersonalDataForUser } from "../../../actions/actionDispatchers";
+import { requestPersonalData } from "../../../utils/auth/authBox";
+import { PERSONAL_ATTRIBUTES, PERSONAL_CONTACT, PERSONAL_LOCATIONS, PERSONAL_PAYMENT_METHODS, PERSONAL_IMAGES } from "../../../utils/constants/personal";
+import { provideCustomBackButton } from "../../../utils/navigation/customBack";
+import { LoginShareAttestationRender } from "./LoginShareAttestation.render"
+import { checkPersonalDataCatagories } from "../../../utils/personal/displayUtils";
+import { handleAttestationDataSend } from "../../../utils/deeplink/handlePersonalDataSend";
+import { primitives } from "verusid-ts-client"
+import { ATTESTATIONS_PROVISIONED } from "../../../utils/constants/attestations";
+import { requestAttestationData } from "../../../utils/auth/authBox";
+import { IdentityVdxfidMap } from 'verus-typescript-primitives/dist/vdxf/classes/IdentityData';
+import { getIdentity } from '../../../utils/api/channels/verusid/callCreators';
+import { createAttestationResponse } from "../../../utils/attestations/createAttestationResponse";
+
+const { IDENTITYDATA_CONTACT, IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_LOCATIONS, IDENTITYDATA_DOCUMENTS_AND_IMAGES, IDENTITYDATA_BANKING_INFORMATION } = primitives;
+import * as VDXF_Data from "verus-typescript-primitives/dist/vdxf/vdxfDataKeys";
+import { DrawerContentScrollView } from "@react-navigation/drawer";
+
+class LoginShareAttestation extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ attestationName: "",
+ attestationAcceptedAttestors: [],
+ attestationRequestedFields: [],
+ attestationRequestedVdxfKeys:[],
+ attestationID: "",
+ loading: false,
+ ready: false,
+ attestationDataURL: "",
+ signerFqn: this.props.route.params.signerFqn
+ };
+ const sdf = 234111
+ }
+
+ componentDidMount() {
+ this.updateDisplay();
+ }
+
+ cancel = () => {
+ if (this.props.route.params.cancel) {
+ this.props.route.params.cancel.cancel()
+ }
+ }
+
+ createAttestationReply = async () => {
+
+ const reply = await createAttestationResponse(this.state.attestationID, this.state.attestationRequestedVdxfKeys)
+ return reply;
+ }
+
+
+ updateDisplay = async () => {
+ const { deeplinkData } = this.props.route.params
+ const loginConsent = new primitives.LoginConsentRequest(deeplinkData);
+
+ const subjectKeys = {};
+ let attestationName = "";
+ let attestationAcceptedAttestors = [];
+ let attestationID = "";
+
+ const attestationDataURL = loginConsent.challenge.subject
+ .filter((permission) => permission.vdxfkey === primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid);
+
+ for (let i = 0; i < loginConsent.challenge.subject.length; i++) {
+
+ let permission = loginConsent.challenge.subject[i];
+
+ if (permission.vdxfkey == primitives.ATTESTATION_VIEW_REQUEST_NAME.vdxfid) {
+ attestationName = permission.data;
+ } else if (permission.vdxfkey == primitives.ATTESTATION_VIEW_REQUEST_ATTESTOR.vdxfid) {
+ let attestorFqn;
+
+ try {
+ const reply = await getIdentity(loginConsent.system_id, permission.data);
+ attestorFqn = reply.result.friendlyname;
+ } catch (e) {
+ console.log("Error getting attestation signer ", e);
+ return false;
+ }
+ attestationAcceptedAttestors.push(attestorFqn);
+
+ }
+ else {
+ subjectKeys[permission.data] = true;
+ }
+ };
+
+ let attestationData;
+ try {
+ attestationData = await requestAttestationData(ATTESTATIONS_PROVISIONED);
+ } catch (e) {
+ createAlert('Error Loading Attestations', e.message);
+ }
+
+ // check that the requested attestestation name is in the attestationData
+
+ let attestationRequestedFields = [];
+ const attestationDataKeys = Object.keys(attestationData);
+ const attestationDataValues = Object.values(attestationData);
+ let attestationRequestedVdxfKeys = loginConsent.challenge.subject
+ .map((permission) => permission.data);
+
+ for (let i = 0; i < attestationDataKeys.length; i++) {
+
+ for (let j = 0; j < attestationDataValues[i].data.length; j++) {
+
+ const vdxfobjKey = Object.keys(attestationDataValues[i].data[j])[0];
+ const vdxfobjValue = attestationDataValues[i].data[j][vdxfobjKey];
+
+ if (vdxfobjKey === VDXF_Data.MMRDescriptorKey().vdxfid) {
+
+ for (let k = 0; k < vdxfobjValue.datadescriptors.length; k++) {
+
+ const item = vdxfobjValue.datadescriptors[k].objectdata[VDXF_Data.DataDescriptorKey().vdxfid];
+
+ if (item.label === primitives.ATTESTATION_NAME.vdxfid) {
+ if (item.objectdata.message !== attestationName) {
+ continue;
+ }
+ } else if (item.label === primitives.ATTESTATION_VIEW_REQUEST_ATTESTOR.vdxfid) {
+ if (attestationAcceptedAttestors.indexOf(item.objectdata.message) === -1) {
+ continue;
+ }
+ } else if (subjectKeys[item.label]) {
+ let name;
+
+ if (name = IdentityVdxfidMap[item.label]?.name) {
+ attestationRequestedFields.push(name);
+ } else {
+ attestationRequestedFields.push(item.label);
+ }
+ }
+ }
+ if (attestationRequestedFields && attestationAcceptedAttestors) {
+ attestationID = attestationDataKeys[0];
+ }
+ }
+ }
+ }
+ this.setState({ attestationRequestedFields,
+ attestationAcceptedAttestors,
+ attestationName,
+ attestationID,
+ attestationDataURL: { vdxfkey: attestationDataURL[0].vdxfkey, uri: attestationDataURL[0].data },
+ attestationRequestedVdxfKeys });
+ }
+
+ async handleContinue() {
+ this.setState({ loading: true });
+
+ const createdAttestation = await this.createAttestationReply()
+
+ createAlert(
+ "Send Selected Attestation info",
+ "Are you sure you want to send your attestation data to: \n" + `${this.state.signerFqn}`,
+ [
+ {
+ text: "No",
+ onPress: () => {
+ resolveAlert();
+ },
+ },
+ {
+ text: "Yes",
+ onPress: () => {
+ resolveAlert();
+ handleAttestationDataSend(createdAttestation, this.state.attestationDataURL)
+ .then(() => {
+ this.setState({ loading: false });
+ this.props.route.params.onGoBack(true);
+ this.props.navigation.goBack();
+ this.cancel();
+ }).catch((e) => {
+
+ this.setState({ loading: false });
+ createAlert("Error, Failed to Send Attestation, server may be unavailable.", e.message);
+
+ })
+ },
+ },
+ ],
+ {
+ cancelable: false,
+ }
+ );
+
+
+ };
+
+ render() {
+ return LoginShareAttestationRender.call(this);
+ }
+}
+
+const mapStateToProps = (state) => {
+ return {
+ activeAccount: state.authentication.activeAccount,
+ encryptedPersonalData: state.personal
+ }
+};
+
+export default connect(mapStateToProps)(LoginShareAttestation);
\ No newline at end of file
diff --git a/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.render.js b/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.render.js
new file mode 100644
index 00000000..0253aa2d
--- /dev/null
+++ b/src/containers/DeepLink/LoginShareAttestation/LoginShareAttestation.render.js
@@ -0,0 +1,68 @@
+import React from "react";
+import { SafeAreaView, ScrollView, View } from "react-native";
+import { Divider, List, Button, Text } from "react-native-paper";
+
+import Styles from "../../../styles";
+
+import Colors from '../../../globals/colors';
+
+export const LoginShareAttestationRender = function (props) {
+
+ return (
+
+
+
+
+
+ Agree to share the following attestation data.
+
+
+ {`Attestation Name: `}{`${this.state.attestationName}`}
+
+ {this.state.attestationAcceptedAttestors &&
+ {`From: `}{`${this.state.attestationAcceptedAttestors[0]}`}
+ }
+
+
+ {this.state.attestationRequestedFields.map(request => {
+ return (
+
+
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.js b/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.js
new file mode 100644
index 00000000..b05274d4
--- /dev/null
+++ b/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.js
@@ -0,0 +1,187 @@
+import moment from "moment";
+import { Component } from "react"
+import { connect } from 'react-redux'
+import { createAlert, resolveAlert } from "../../../actions/actions/alert/dispatchers/alert"
+import { modifyPersonalDataForUser } from "../../../actions/actionDispatchers";
+import { requestPersonalData } from "../../../utils/auth/authBox";
+import { PERSONAL_ATTRIBUTES, PERSONAL_CONTACT, PERSONAL_LOCATIONS, PERSONAL_PAYMENT_METHODS, PERSONAL_IMAGES } from "../../../utils/constants/personal";
+import { provideCustomBackButton } from "../../../utils/navigation/customBack";
+import { PersonalSelectDataRender } from "./PersonalSelectData.render"
+import { checkPersonalDataCatagories } from "../../../utils/personal/displayUtils";
+import { handlePersonalDataSend } from "../../../utils/deeplink/handlePersonalDataSend";
+import { primitives } from "verusid-ts-client"
+
+const { IDENTITYDATA_CONTACT, IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_LOCATIONS, IDENTITYDATA_DOCUMENTS_AND_IMAGES, IDENTITYDATA_BANKING_INFORMATION} = primitives;
+
+
+//const { defaultPersonalProfileDataTemplate } = primitives;
+const EDIT = 'edit'
+const REMOVE = 'remove'
+const PERSONALDATACATAGORIES = [
+ IDENTITYDATA_CONTACT.vdxfid,
+ IDENTITYDATA_LOCATIONS.vdxfid,
+ IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid,
+ IDENTITYDATA_PERSONAL_DETAILS.vdxfid,
+ IDENTITYDATA_BANKING_INFORMATION.vdxfid
+];
+
+const PERSONALDATALINKS = [
+ "PersonalContact",
+ "PersonalLocations",
+ "PersonalImages",
+ "PersonalAttributes",
+ "PersonalPaymentMethods"
+]
+class PersonalSelectData extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ loginConsent: null,
+ nationalityModalOpen: false,
+ birthdaySelectorModalOpen: false,
+ editPropertyModal: {
+ open: false,
+ property: null,
+ label: "",
+ index: null
+ },
+ loading: false,
+ ready: false,
+ catagoriesRequested: null,
+ personalDataURL: "",
+ signerFqn: this.props.route.params.signerFqn
+ };
+ }
+
+ componentDidMount() {
+ this.updateDisplay();
+ }
+
+ componentDidUpdate(lastProps) {
+ if (lastProps.encryptedPersonalData !== this.props.encryptedPersonalData) {
+ this.updateDisplay();
+ }
+ }
+
+ cancel = () => {
+ if (this.props.route.params.cancel) {
+ this.props.route.params.cancel.cancel()
+ }
+ }
+
+ updateDisplay() {
+ const { deeplinkData } = this.props.route.params
+ const loginConsent = new primitives.LoginConsentRequest(deeplinkData);
+
+ const personalDataURL = loginConsent.challenge.subject
+ .filter((permission) => permission.vdxfkey === primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid);
+
+ const requestedPersonalData = loginConsent.challenge.subject
+ .filter((permission) => permission.vdxfkey === primitives.PROFILE_DATA_VIEW_REQUEST.vdxfid);
+
+ const catagoriesRequested = {};
+ requestedPersonalData.forEach((permission) => {
+ PERSONALDATACATAGORIES.forEach((category, idx) => {
+ if (category === permission.data) {
+ primitives.defaultPersonalProfileDataTemplate.forEach((templateCategory) => {
+ if (templateCategory.vdxfid === permission.data) {
+ catagoriesRequested[permission.data] = { title: templateCategory.category,
+ details: templateCategory.details, navigateTo: PERSONALDATALINKS[idx], color: "black" };
+ }
+ })
+ }
+ })
+ });
+
+ checkPersonalDataCatagories(catagoriesRequested).then((success) => {
+ this.setState({ catagoriesRequested: catagoriesRequested, personalDataURL: {vdxfkey: personalDataURL[0].vdxfkey ,uri: personalDataURL[0].data}, ready: success});
+ });
+ }
+
+ handleContinue() {
+ this.setState({loading: true});
+
+ this.getPersonalDataFromCategories().then((personalData) => {
+
+ createAlert(
+ "Send Personal info",
+ "Are you sure you want to send your data to: \n" + `${this.state.signerFqn}`,
+ [
+ {
+ text: "No",
+ onPress: () => {
+ resolveAlert();
+ },
+ },
+ {
+ text: "Yes",
+ onPress: () => {
+ resolveAlert();
+ handlePersonalDataSend(personalData, this.state.personalDataURL)
+ .then(() => {
+ this.setState({loading: false});
+ this.props.route.params.onGoBack(true);
+ this.props.navigation.goBack();
+ })
+ },
+ },
+ ],
+ {
+ cancelable: false,
+ }
+ );
+ }
+ ).catch((e) => {
+ this.setState({loading: false});
+ createAlert("Error", e.message);
+ });
+
+ };
+
+ async getPersonalDataFromCategories() {
+ let personalData = {};
+
+ await Promise.all(Object.keys(this.state.catagoriesRequested).map(async (categoryVdxfkey) => {
+ switch (categoryVdxfkey) {
+ case IDENTITYDATA_PERSONAL_DETAILS.vdxfid:
+ personalData[IDENTITYDATA_PERSONAL_DETAILS.vdxfid] = await requestPersonalData(PERSONAL_ATTRIBUTES);
+ break;
+ case IDENTITYDATA_CONTACT.vdxfid:
+ personalData[IDENTITYDATA_CONTACT.vdxfid] = await requestPersonalData(PERSONAL_CONTACT);
+ break;
+ case IDENTITYDATA_LOCATIONS.vdxfid:
+ personalData[IDENTITYDATA_LOCATIONS.vdxfid] = await requestPersonalData(PERSONAL_LOCATIONS);
+ break;
+ case IDENTITYDATA_BANKING_INFORMATION.vdxfid:
+ personalData[IDENTITYDATA_BANKING_INFORMATION.vdxfid] = await requestPersonalData(PERSONAL_PAYMENT_METHODS);
+ break;
+ case IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid:
+ personalData[IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid] = await requestPersonalData(PERSONAL_IMAGES);
+ break;
+ default:
+ break;
+ }
+ }));
+
+ return personalData;
+ }
+
+ openAttributes(navigateTo) {
+ this.props.navigation.navigate("ProfileStackScreens", {
+ screen: navigateTo
+ });
+ }
+
+ render() {
+ return PersonalSelectDataRender.call(this);
+ }
+}
+
+const mapStateToProps = (state) => {
+ return {
+ activeAccount: state.authentication.activeAccount,
+ encryptedPersonalData: state.personal
+ }
+};
+
+export default connect(mapStateToProps)(PersonalSelectData);
\ No newline at end of file
diff --git a/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.render.js b/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.render.js
new file mode 100644
index 00000000..8e55b469
--- /dev/null
+++ b/src/containers/DeepLink/PersonalSelectData/PersonalSelectData.render.js
@@ -0,0 +1,63 @@
+import React from "react";
+import { SafeAreaView, ScrollView, View } from "react-native";
+import { Divider, List, Button, Text } from "react-native-paper";
+
+import Styles from "../../../styles";
+
+import Colors from '../../../globals/colors';
+
+export const PersonalSelectDataRender = function (props) {
+
+ return (
+
+
+
+
+
+ Agree to share the following personal data.
+
+ {this.state.catagoriesRequested && Object.values(this.state.catagoriesRequested).map(request => {
+ return (
+
+ {request.details}}
+ onPress={this.state.loading ? () => { } : () => this.openAttributes(request.navigateTo)}
+ right={(props) => }
+ key={request.details}
+ />
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/containers/Personal/PersonalAttributes/PersonalAttributes.js b/src/containers/Personal/PersonalAttributes/PersonalAttributes.js
index e4a872a8..18b16c09 100644
--- a/src/containers/Personal/PersonalAttributes/PersonalAttributes.js
+++ b/src/containers/Personal/PersonalAttributes/PersonalAttributes.js
@@ -1,11 +1,14 @@
import moment from "moment";
-import { Component } from "react"
+import { Component } from "react"
+import { Platform, NativeModules } from 'react-native'
import { connect } from 'react-redux'
import { modifyPersonalDataForUser } from "../../../actions/actionDispatchers";
import { requestPersonalData } from "../../../utils/auth/authBox";
import { PERSONAL_ATTRIBUTES, PERSONAL_BIRTHDAY, PERSONAL_NATIONALITIES } from "../../../utils/constants/personal";
import { provideCustomBackButton } from "../../../utils/navigation/customBack";
import { PersonalAttributesRender } from "./PersonalAttributes.render"
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_FIRSTNAME, IDENTITYDATA_MIDDLENAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_DATEOFBIRTH, IDENTITYDATA_NATIONALITY } = primitives;
const EDIT = 'edit'
const REMOVE = 'remove'
@@ -15,17 +18,11 @@ class PersonalAttributes extends Component {
super();
this.state = {
attributes: {
- name: {
- first: "John",
- middle: "",
- last: "Doe"
- },
- birthday: {
- day: null,
- month: null,
- year: null
- },
- nationalities: []
+ [IDENTITYDATA_FIRSTNAME.vdxfid]: "John",
+ [IDENTITYDATA_MIDDLENAME.vdxfid]: "",
+ [IDENTITYDATA_LASTNAME.vdxfid]: "Doe",
+ [IDENTITYDATA_DATEOFBIRTH.vdxfid]: {},
+ [IDENTITYDATA_NATIONALITY.vdxfid]: [],
},
nationalityModalOpen: false,
birthdaySelectorModalOpen: false,
@@ -126,21 +123,23 @@ class PersonalAttributes extends Component {
}
addNationality(nationalityCode) {
- const nationalities = this.state.attributes.nationalities ? this.state.attributes.nationalities : []
- this.updateAttribute(PERSONAL_NATIONALITIES, [...nationalities, nationalityCode])
+ const nationalities = this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid]
+ ? this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid] : []
+ this.updateAttribute(IDENTITYDATA_NATIONALITY.vdxfid, [...nationalities, nationalityCode])
}
removeNationality(index) {
- let nationalities = this.state.attributes.nationalities ? this.state.attributes.nationalities : []
+ let nationalities = this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid]
+ ? this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid] : []
nationalities.splice(index, 1);
- this.updateAttribute(PERSONAL_NATIONALITIES, nationalities)
+ this.updateAttribute(IDENTITYDATA_NATIONALITY.vdxfid, nationalities)
}
setBirthday(date) {
this.setState({
birthdaySelectorModalOpen: false
}, () => {
- this.updateAttribute(PERSONAL_BIRTHDAY, date)
+ this.updateAttribute(IDENTITYDATA_DATEOFBIRTH.vdxfid, date)
})
}
@@ -173,10 +172,16 @@ class PersonalAttributes extends Component {
}
renderDate() {
- const { day, month, year } = this.state.attributes.birthday;
+ const { day, month, year } = this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid];
const date = this.getDateClassInstance(day, month, year)
- return date.toLocaleDateString("en-US", {
+ const deviceLanguage =
+ Platform.OS === 'ios'
+ ? NativeModules.SettingsManager.settings.AppleLocale ||
+ NativeModules.SettingsManager.settings.AppleLanguages[0] //iOS 13
+ : NativeModules.I18nManager.localeIdentifier;
+
+ return date.toLocaleDateString(deviceLanguage, {
year: "numeric",
month: "long",
day: "numeric",
diff --git a/src/containers/Personal/PersonalAttributes/PersonalAttributes.render.js b/src/containers/Personal/PersonalAttributes/PersonalAttributes.render.js
index 562e3646..c043c91d 100644
--- a/src/containers/Personal/PersonalAttributes/PersonalAttributes.render.js
+++ b/src/containers/Personal/PersonalAttributes/PersonalAttributes.render.js
@@ -7,6 +7,8 @@ import Styles from "../../../styles";
import { ISO_3166_COUNTRIES, ISO_3166_ALPHA_2_CODES } from "../../../utils/constants/iso3166";
import { PERSONAL_NATIONALITIES } from "../../../utils/constants/personal";
import { renderPersonalBirthday, renderPersonalFullName } from "../../../utils/personal/displayUtils";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_FIRSTNAME, IDENTITYDATA_MIDDLENAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_DATEOFBIRTH, IDENTITYDATA_NATIONALITY } = primitives;
export const PersonalAttributesRender = function () {
return (
@@ -46,12 +48,12 @@ export const PersonalAttributesRender = function () {
flexHeight={0.5}
visible={this.state.birthdaySelectorModalOpen}
initialDate={
- this.state.attributes.birthday == null
+ this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid] == null
? new Date()
: this.getDateClassInstance(
- this.state.attributes.birthday.day,
- this.state.attributes.birthday.month,
- this.state.attributes.birthday.year
+ this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid].day,
+ this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid].month,
+ this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid].year
)
}
onSelect={(date) => this.setBirthday(date)}
@@ -64,7 +66,7 @@ export const PersonalAttributesRender = function () {
{"Name"}
(
)}
@@ -73,9 +75,9 @@ export const PersonalAttributesRender = function () {
{"Date of birth"}
- {this.state.attributes.birthday != null ? (
+ {this.state.attributes[IDENTITYDATA_DATEOFBIRTH.vdxfid] != null ? (
(
)}
@@ -91,9 +93,9 @@ export const PersonalAttributesRender = function () {
{"Nationalities"}
- {this.state.attributes.nationalities == null
+ {this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid] == null
? null
- : this.state.attributes.nationalities.map((code, index) => {
+ : this.state.attributes[IDENTITYDATA_NATIONALITY.vdxfid].map((code, index) => {
const nationality = ISO_3166_COUNTRIES[code];
return (
diff --git a/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.js b/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.js
index 3dc753b5..a636d203 100644
--- a/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.js
+++ b/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.js
@@ -4,17 +4,14 @@ import { modifyPersonalDataForUser } from "../../../../actions/actionDispatchers
import { PERSONAL_ATTRIBUTES } from "../../../../utils/constants/personal";
import { provideCustomBackButton } from "../../../../utils/navigation/customBack";
import { PersonalAttributesEditNameRender } from "./PersonalAttributesEditName.render"
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_DATEOFBIRTH} = primitives;
class PersonalAttributesEditName extends Component {
constructor(props) {
super(props);
this.state = {
attributes: props.route.params.attributes,
- name: {
- first: props.route.params.attributes.name ? props.route.params.attributes.name.first : "",
- middle: props.route.params.attributes.name ? props.route.params.attributes.name.middle : "",
- last: props.route.params.attributes.name ? props.route.params.attributes.name.last : "",
- },
currentTextInputModal: null,
loading: false,
};
@@ -33,7 +30,7 @@ class PersonalAttributesEditName extends Component {
updateName() {
this.setState({ loading: true }, async () => {
await modifyPersonalDataForUser(
- {...this.state.attributes, name: this.state.name},
+ this.state.attributes,
PERSONAL_ATTRIBUTES,
this.props.activeAccount.accountHash
);
diff --git a/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.render.js b/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.render.js
index 3f3f3b16..f0d93110 100644
--- a/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.render.js
+++ b/src/containers/Personal/PersonalAttributes/PersonalAttributesEditName/PersonalAttributesEditName.render.js
@@ -4,6 +4,8 @@ import { Divider, List, Portal } from "react-native-paper";
import Styles from "../../../../styles";
import TextInputModal from "../../../../components/TextInputModal/TextInputModal"
import Colors from "../../../../globals/colors";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_FIRSTNAME, IDENTITYDATA_MIDDLENAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_DATEOFBIRTH, IDENTITYDATA_NATIONALITY } = primitives;
export const PersonalAttributesEditNameRender = function () {
return (
@@ -12,13 +14,13 @@ export const PersonalAttributesEditNameRender = function () {
{this.state.currentTextInputModal != null && (
{
if (text != null)
this.setState({
- name: {
- ...this.state.name,
+ attributes: {
+ ...this.state.attributes,
[this.state.currentTextInputModal]: text,
},
});
@@ -31,19 +33,19 @@ export const PersonalAttributesEditNameRender = function () {
}
onPress={
- this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: "first" })
+ this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: IDENTITYDATA_FIRSTNAME.vdxfid })
}
/>
@@ -51,19 +53,19 @@ export const PersonalAttributesEditNameRender = function () {
}
onPress={
- this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: "middle" })
+ this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: IDENTITYDATA_MIDDLENAME.vdxfid })
}
/>
@@ -71,19 +73,19 @@ export const PersonalAttributesEditNameRender = function () {
}
onPress={
- this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: "last" })
+ this.state.loading ? () => {} : () => this.setState({ currentTextInputModal: IDENTITYDATA_LASTNAME.vdxfid })
}
/>
diff --git a/src/containers/Personal/PersonalContact/PersonalContact.js b/src/containers/Personal/PersonalContact/PersonalContact.js
index 6f046996..50e76313 100644
--- a/src/containers/Personal/PersonalContact/PersonalContact.js
+++ b/src/containers/Personal/PersonalContact/PersonalContact.js
@@ -9,6 +9,8 @@ import {
} from "../../../utils/constants/personal";
import { provideCustomBackButton } from "../../../utils/navigation/customBack";
import { PersonalContactRender } from "./PersonalContact.render"
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_EMAIL, IDENTITYDATA_PHONENUMBER } = primitives;
const EDIT = 'edit'
const REMOVE = 'remove'
@@ -18,8 +20,8 @@ class PersonalContact extends Component {
super();
this.state = {
contact: {
- phone_numbers: [],
- emails: []
+ [IDENTITYDATA_PHONENUMBER.vdxfid]: [],
+ [IDENTITYDATA_EMAIL.vdxfid]: []
},
addPropertyModal: {
open: false,
@@ -157,13 +159,13 @@ class PersonalContact extends Component {
}
editPhone(phone, index) {
- let phones = this.state.contact.phone_numbers ? this.state.contact.phone_numbers : []
+ let phones = this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid] ? this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid] : []
if (index == null) {
- this.updateContactPoint(PERSONAL_PHONE_NUMBERS, [...phones, phone])
+ this.updateContactPoint(IDENTITYDATA_PHONENUMBER.vdxfid, [...phones, phone])
} else {
phones[index] = phone
- this.updateContactPoint(PERSONAL_PHONE_NUMBERS, phones)
+ this.updateContactPoint(IDENTITYDATA_PHONENUMBER.vdxfid, phones)
}
}
@@ -179,26 +181,26 @@ class PersonalContact extends Component {
}
editEmail(email, index) {
- let emails = this.state.contact.emails ? this.state.contact.emails : []
+ let emails = this.state.contact[IDENTITYDATA_EMAIL.vdxfid] ? this.state.contact[IDENTITYDATA_EMAIL.vdxfid] : []
if (index == null) {
- this.updateContactPoint(PERSONAL_EMAILS, [...emails, email])
+ this.updateContactPoint(IDENTITYDATA_EMAIL.vdxfid, [...emails, email])
} else {
emails[index] = email
- this.updateContactPoint(PERSONAL_EMAILS, emails)
+ this.updateContactPoint(IDENTITYDATA_EMAIL.vdxfid, emails)
}
}
removePhone(index) {
- let phone_numbers = this.state.contact.phone_numbers ? this.state.contact.phone_numbers : []
+ let phone_numbers = this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid] ? this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid] : []
phone_numbers.splice(index, 1);
- this.updateContactPoint(PERSONAL_PHONE_NUMBERS, phone_numbers)
+ this.updateContactPoint(IDENTITYDATA_PHONENUMBER.vdxfid, phone_numbers)
}
removeEmail(index) {
- let emails = this.state.contact.emails ? this.state.contact.emails : []
+ let emails = this.state.contact[IDENTITYDATA_EMAIL.vdxfid] ? this.state.contact[IDENTITYDATA_EMAIL.vdxfid] : []
emails.splice(index, 1);
- this.updateContactPoint(PERSONAL_EMAILS, emails)
+ this.updateContactPoint(IDENTITYDATA_EMAIL.vdxfid, emails)
}
finishPhoneEdit(phone, index) {
diff --git a/src/containers/Personal/PersonalContact/PersonalContact.render.js b/src/containers/Personal/PersonalContact/PersonalContact.render.js
index 9304024c..35e33d20 100644
--- a/src/containers/Personal/PersonalContact/PersonalContact.render.js
+++ b/src/containers/Personal/PersonalContact/PersonalContact.render.js
@@ -10,6 +10,8 @@ import { ISO_3166_COUNTRIES, ISO_3166_ALPHA_2_CODES } from "../../../utils/const
import { CALLING_CODES_TO_ISO_3166 } from "../../../utils/constants/callingCodes";
import { PERSONAL_EMAILS, PERSONAL_NATIONALITIES, PERSONAL_PHONE_NUMBERS } from "../../../utils/constants/personal";
import { renderPersonalPhoneNumber } from "../../../utils/personal/displayUtils";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_EMAIL, IDENTITYDATA_PHONENUMBER } = primitives;
export const PersonalContactRender = function () {
return (
@@ -70,9 +72,9 @@ export const PersonalContactRender = function () {
{"Email addresses"}
- {this.state.contact.emails == null
+ {this.state.contact[IDENTITYDATA_EMAIL.vdxfid] == null
? null
- : this.state.contact.emails.map((email, index) => {
+ : this.state.contact[IDENTITYDATA_EMAIL.vdxfid].map((email, index) => {
return (
{"Phone numbers"}
- {this.state.contact.phone_numbers == null
+ {this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid] == null
? null
- : this.state.contact.phone_numbers.map((phone, index) => {
+ : this.state.contact[IDENTITYDATA_PHONENUMBER.vdxfid].map((phone, index) => {
const type = phone.type;
const typeFr = type.charAt(0).toUpperCase() + type.slice(1);
diff --git a/src/containers/Personal/PersonalInfo/PersonalInfo.js b/src/containers/Personal/PersonalInfo/PersonalInfo.js
index 5592ff26..dcea3f81 100644
--- a/src/containers/Personal/PersonalInfo/PersonalInfo.js
+++ b/src/containers/Personal/PersonalInfo/PersonalInfo.js
@@ -3,24 +3,25 @@
use to configure their personal wallet profile. They can then
take this profile data and submit it to applications that require
KYC if they want.
-*/
+*/
import { Component } from "react"
import { connect } from 'react-redux'
import { requestPersonalData } from "../../../utils/auth/authBox";
import { PERSONAL_ATTRIBUTES } from "../../../utils/constants/personal";
import { PersonalInfoRender } from "./PersonalInfo.render"
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_MIDDLENAME, IDENTITYDATA_FIRSTNAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_DATEOFBIRTH } = primitives;
class PersonalInfo extends Component {
constructor(props) {
super(props);
this.state = {
attributes: {
- name: {
- first: "John",
- middle: "",
- last: "Doe"
- }
+ [IDENTITYDATA_FIRSTNAME.vdxfid]: "John",
+ [IDENTITYDATA_MIDDLENAME.vdxfid]: "",
+ [IDENTITYDATA_LASTNAME.vdxfid]: "Doe",
+ [IDENTITYDATA_DATEOFBIRTH.vdxfid]: {},
},
loading: false
};
diff --git a/src/containers/Personal/PersonalInfo/PersonalInfo.render.js b/src/containers/Personal/PersonalInfo/PersonalInfo.render.js
index a4bd5e87..88262fa0 100644
--- a/src/containers/Personal/PersonalInfo/PersonalInfo.render.js
+++ b/src/containers/Personal/PersonalInfo/PersonalInfo.render.js
@@ -3,7 +3,8 @@ import { Text, SafeAreaView, ScrollView, View } from "react-native";
import { Divider, List, Avatar, Title } from "react-native-paper";
import Styles from "../../../styles";
import { renderPersonalFullName } from "../../../utils/personal/displayUtils";
-
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_FIRSTNAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_PERSONAL_DETAILS} = primitives;
export const PersonalInfoRender = function () {
return (
@@ -11,9 +12,9 @@ export const PersonalInfoRender = function () {
- {renderPersonalFullName(this.state.attributes.name).title}
+ {renderPersonalFullName(this.state.attributes).title}
diff --git a/src/containers/Personal/PersonalIntroSlider/PersonalIntroSlider.js b/src/containers/Personal/PersonalIntroSlider/PersonalIntroSlider.js
index 9fd3f046..ad247a84 100644
--- a/src/containers/Personal/PersonalIntroSlider/PersonalIntroSlider.js
+++ b/src/containers/Personal/PersonalIntroSlider/PersonalIntroSlider.js
@@ -16,6 +16,8 @@ import { useEffect } from "react";
import { modifyPersonalDataForUser } from "../../../actions/actionDispatchers";
import { PERSONAL_ATTRIBUTES } from "../../../utils/constants/personal";
import { createAlert } from "../../../actions/actions/alert/dispatchers/alert";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_FIRSTNAME, IDENTITYDATA_MIDDLENAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_DATEOFBIRTH, IDENTITYDATA_NATIONALITY } = primitives;
const slides = [
{
@@ -48,7 +50,7 @@ const NameForm = (props) => {
const [last, setLast] = React.useState('');
useEffect(() => {
- onChange({ first: first.trim(), middle: middle.trim(), last: last.trim() });
+ onChange({ [IDENTITYDATA_FIRSTNAME.vdxfid]: first.trim(), [IDENTITYDATA_MIDDLENAME.vdxfid]: middle.trim(), [IDENTITYDATA_LASTNAME.vdxfid]: last.trim() });
}, [first, middle, last]);
return (
@@ -104,9 +106,9 @@ class PersonalIntroSlider extends Component {
super();
this.state = {
name: {
- first: '',
- middle: '',
- last: ''
+ [IDENTITYDATA_FIRSTNAME.vdxfid]: '',
+ [IDENTITYDATA_MIDDLENAME.vdxfid]: '',
+ [IDENTITYDATA_LASTNAME.vdxfid]: ''
},
loading: false,
currentSlide: 0
@@ -179,7 +181,7 @@ class PersonalIntroSlider extends Component {
_onDone = () => {
this.setState({loading: true}, async () => {
await modifyPersonalDataForUser(
- { name: this.state.name },
+ this.state.name,
PERSONAL_ATTRIBUTES,
this.props.activeAccount.accountHash
)
diff --git a/src/containers/Personal/PersonalLocations/PersonalLocations.render.js b/src/containers/Personal/PersonalLocations/PersonalLocations.render.js
index 60b8fccd..d8467791 100644
--- a/src/containers/Personal/PersonalLocations/PersonalLocations.render.js
+++ b/src/containers/Personal/PersonalLocations/PersonalLocations.render.js
@@ -5,6 +5,8 @@ import ListSelectionModal from "../../../components/ListSelectionModal/ListSelec
import Styles from "../../../styles";
import { ISO_3166_COUNTRIES } from "../../../utils/constants/iso3166";
import { renderPersonalTaxId } from "../../../utils/personal/displayUtils";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_HOMEADDRESS_STREET1, IDENTITYDATA_HOMEADDRESS_STREET2, IDENTITYDATA_HOMEADDRESS_CITY, IDENTITYDATA_HOMEADDRESS_REGION, IDENTITYDATA_HOMEADDRESS_POSTCODE, IDENTITYDATA_HOMEADDRESS_COUNTRY } = primitives;
export const PersonalLocationsRender = function () {
return (
@@ -64,24 +66,24 @@ export const PersonalLocationsRender = function () {
0
- ? `${address.street1}${
- address.street2 != null && address.street2.length > 0
- ? `, ${address.street2}`
+ address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]?.length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]}${
+ address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid] != null && address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid].length > 0
+ ? `, ${address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]}`
: ""
}`
: "Empty address"
}
description={`${
- address.postal_code.length > 0 ? `${address.postal_code} ` : ""
+ address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]} ` : ""
}${
- address.state_province_region.length > 0
- ? `${address.state_province_region}, `
+ address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]?.length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]}, `
: ""
- }${address.city.length > 0 ? `${address.city}, ` : "Unknown City, "}${
- ISO_3166_COUNTRIES[address.country] != null
- ? `${ISO_3166_COUNTRIES[address.country].emoji} ${
- ISO_3166_COUNTRIES[address.country].name
+ }${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]}, ` : "Unknown City, "}${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]] != null
+ ? `${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].emoji} ${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].name
}`
: "Unknown Country"
}`}
diff --git a/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.js b/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.js
index 53b0ec32..a0627ec5 100644
--- a/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.js
+++ b/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.js
@@ -6,6 +6,8 @@ import { createAlert, resolveAlert } from "../../../../actions/actions/alert/dis
import { PERSONAL_LOCATIONS } from "../../../../utils/constants/personal";
import { provideCustomBackButton } from "../../../../utils/navigation/customBack";
import { PersonalLocationsEditAddressRender } from "./PersonalLocationsEditAddress.render"
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_HOMEADDRESS_STREET1, IDENTITYDATA_HOMEADDRESS_STREET2, IDENTITYDATA_HOMEADDRESS_CITY, IDENTITYDATA_HOMEADDRESS_REGION, IDENTITYDATA_HOMEADDRESS_POSTCODE, IDENTITYDATA_HOMEADDRESS_COUNTRY } = primitives;
class PersonalLocationsEditAddress extends Component {
constructor(props) {
@@ -19,12 +21,12 @@ class PersonalLocationsEditAddress extends Component {
props.route.params.index
]
: {
- street1: "",
- street2: "",
- city: "",
- state_province_region: "",
- postal_code: "",
- country: "",
+ [IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]: "",
+ [IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]: "",
+ [IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]: "",
+ [IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]: "",
+ [IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]: "",
+ [IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]: "",
};
this.state = {
@@ -37,29 +39,30 @@ class PersonalLocationsEditAddress extends Component {
};
this.addressTextInputLabels = {
- street1: {
+ [IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]: {
title: "Address line 1",
description: "Street address, company name, P.O. box",
placeholder: "required"
},
- street2: {
+ [IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]: {
title: "Address line 2",
description: "Apartment number, unit, floor, etc.",
placeholder: "optional"
},
- city: {
+ [IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]: {
title: "City",
placeholder: "required"
},
- state_province_region: {
+ [IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]: {
title: "State/Province/Region",
placeholder: "optional"
},
- postal_code: {
+ [IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]: {
title: "ZIP/Postal Code",
placeholder: "required"
}
}
+ const sdf =324
}
componentDidMount() {
@@ -142,7 +145,7 @@ class PersonalLocationsEditAddress extends Component {
this.setState({
address: {
...this.state.address,
- country: countryCode
+ [IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]: countryCode
}
}, () => this.updateAddress())
}
diff --git a/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.render.js b/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.render.js
index 7fe2db15..15c1f9a8 100644
--- a/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.render.js
+++ b/src/containers/Personal/PersonalLocations/PersonalLocationsEditAddress/PersonalLocationsEditAddress.render.js
@@ -6,7 +6,8 @@ import TextInputModal from "../../../../components/TextInputModal/TextInputModal
import ListSelectionModal from "../../../../components/ListSelectionModal/ListSelectionModal";
import { ISO_3166_COUNTRIES, ISO_3166_ALPHA_2_CODES } from "../../../../utils/constants/iso3166";
import Colors from "../../../../globals/colors";
-
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_HOMEADDRESS_COUNTRY } = primitives;
export const PersonalLocationsEditAddressRender = function () {
return (
@@ -83,15 +84,15 @@ export const PersonalLocationsEditAddressRender = function () {
0
- ? `${address.street1}${
- address.street2 != null && address.street2.length > 0 ? `, ${address.street2}` : ""
+ address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]?.length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]}${
+ address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid] != null && address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]?.length > 0 ? `, ${address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]}` : ""
}`
: "Configure address",
- `${address.postal_code.length > 0 ? `${address.postal_code} ` : ""}${
- address.state_province_region.length > 0 ? `${address.state_province_region}, ` : ""
- }${address.city.length > 0 ? `${address.city}, ` : "Unknown City, "}${
- ISO_3166_COUNTRIES[address.country] != null
- ? `${ISO_3166_COUNTRIES[address.country].emoji} ${
- ISO_3166_COUNTRIES[address.country].name
+ `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]} ` : ""}${
+ address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid].length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]}, ` : ""
+ }${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid].length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]}, ` : "Unknown City, "}${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]] != null
+ ? `${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].emoji} ${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].name
}`
: "Unknown Country"
}`,
diff --git a/src/containers/Personal/PersonalPaymentMethods/PersonalPaymentMethodsEditBankAccountAddress/PersonalPaymentMethodsEditBankAccountAddress.render.js b/src/containers/Personal/PersonalPaymentMethods/PersonalPaymentMethodsEditBankAccountAddress/PersonalPaymentMethodsEditBankAccountAddress.render.js
index 9dad0575..9e56d5fe 100644
--- a/src/containers/Personal/PersonalPaymentMethods/PersonalPaymentMethodsEditBankAccountAddress/PersonalPaymentMethodsEditBankAccountAddress.render.js
+++ b/src/containers/Personal/PersonalPaymentMethods/PersonalPaymentMethodsEditBankAccountAddress/PersonalPaymentMethodsEditBankAccountAddress.render.js
@@ -4,6 +4,8 @@ import { Divider, List } from "react-native-paper";
import Styles from "../../../../styles";
import Colors from "../../../../globals/colors";
import { ISO_3166_COUNTRIES } from "../../../../utils/constants/iso3166";
+import { primitives } from "verusid-ts-client"
+const { IDENTITYDATA_HOMEADDRESS_STREET1, IDENTITYDATA_HOMEADDRESS_STREET2, IDENTITYDATA_HOMEADDRESS_CITY, IDENTITYDATA_HOMEADDRESS_REGION, IDENTITYDATA_HOMEADDRESS_POSTCODE, IDENTITYDATA_HOMEADDRESS_COUNTRY } = primitives;
export const PersonalPaymentMethodsEditBankAccountAddressRender = function () {
return (
@@ -20,24 +22,24 @@ export const PersonalPaymentMethodsEditBankAccountAddressRender = function () {
0
- ? `${address.street1}${
- address.street2 != null && address.street2.length > 0
- ? `, ${address.street2}`
+ address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]?.length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]}${
+ address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid] != null && address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid].length > 0
+ ? `, ${address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]}`
: ""
}`
: "Empty address"
}
description={`${
- address.postal_code.length > 0 ? `${address.postal_code} ` : ""
+ address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]} ` : ""
}${
- address.state_province_region.length > 0
- ? `${address.state_province_region}, `
+ address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]?.length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]}, `
: ""
- }${address.city.length > 0 ? `${address.city}, ` : "Unknown City, "}${
- ISO_3166_COUNTRIES[address.country] != null
- ? `${ISO_3166_COUNTRIES[address.country].emoji} ${
- ISO_3166_COUNTRIES[address.country].name
+ }${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]}, ` : "Unknown City, "}${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]] != null
+ ? `${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].emoji} ${
+ ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].name
}`
: "Unknown Country"
}`}
diff --git a/src/containers/RootStack/DeepLinkStackScreens/DeepLinkStackScreens.js b/src/containers/RootStack/DeepLinkStackScreens/DeepLinkStackScreens.js
index 5f37647a..f87ab756 100644
--- a/src/containers/RootStack/DeepLinkStackScreens/DeepLinkStackScreens.js
+++ b/src/containers/RootStack/DeepLinkStackScreens/DeepLinkStackScreens.js
@@ -5,6 +5,10 @@ import DeepLink from '../../DeepLink/DeepLink';
import LoginRequestIdentity from '../../DeepLink/LoginRequestIdentity/LoginRequestIdentity';
import LoginRequestComplete from '../../DeepLink/LoginRequestComplete/LoginRequestComplete';
import InvoicePaymentConfiguration from '../../DeepLink/InvoicePaymentConfiguration/InvoicePaymentConfiguration';
+import PersonalSelectData from '../../DeepLink/PersonalSelectData/PersonalSelectData';
+import ProfileStackScreens from '../ProfileStackScreens/ProfileStackScreens';
+import LoginReceiveAttestation from '../../DeepLink/LoginReceiveAttestation/LoginReceiveAttestation';
+import LoginShareAttestation from '../../DeepLink/LoginShareAttestation/LoginShareAttestation';
const DeepLinkStack = createStackNavigator();
@@ -43,6 +47,35 @@ const DeepLinkStackScreens = props => {
title: "Configure Payment"
}}
/>
+ null,
+ title: "Personal Data"
+ }}
+ />
+
+ null,
+ title: "Receive Attestation"
+ }}
+ />
+ null,
+ title: "Share Attestation data"
+ }}
+ />
);
};
diff --git a/src/containers/RootStack/ServicesStackScreens/ServicesStackScreens.js b/src/containers/RootStack/ServicesStackScreens/ServicesStackScreens.js
index c5005baa..b6c4056c 100644
--- a/src/containers/RootStack/ServicesStackScreens/ServicesStackScreens.js
+++ b/src/containers/RootStack/ServicesStackScreens/ServicesStackScreens.js
@@ -6,7 +6,7 @@ import Service from '../../Services/Service/Service'
import WyreServiceAccountData from '../../Services/ServiceComponents/WyreService/WyreServiceAccount/WyreServiceAccountData/WyreServiceAccountData';
import WyreServiceAddPaymentMethod from '../../Services/ServiceComponents/WyreService/WyreServiceAccount/WyreServiceAddPaymentMethod/WyreServiceAddPaymentMethod';
import WyreServiceEditPaymentMethod from '../../Services/ServiceComponents/WyreService/WyreServiceAccount/WyreServiceEditPaymentMethod/WyreServiceEditPaymentMethod';
-
+import ViewAttestation from '../../Services/ServiceComponents/AttestationService/ViewAttestation/ViewAttestation';
const ServicesStack = createStackNavigator();
const ServicesStackScreens = props => {
@@ -43,6 +43,13 @@ const ServicesStackScreens = props => {
title: "Edit Account",
}}
/>
+
);
};
diff --git a/src/containers/Services/Service/Service.js b/src/containers/Services/Service/Service.js
index 83593652..6b942ded 100644
--- a/src/containers/Services/Service/Service.js
+++ b/src/containers/Services/Service/Service.js
@@ -3,11 +3,11 @@
*/
import React, { Component } from "react"
-import { PBAAS_PRECONVERT_SERVICE_ID, VERUSID_SERVICE_ID, WYRE_SERVICE_ID } from "../../../utils/constants/services";
+import { PBAAS_PRECONVERT_SERVICE_ID, VERUSID_SERVICE_ID, WYRE_SERVICE_ID, ATTESTATION_SERVICE_ID } from "../../../utils/constants/services";
import VerusIdService from "../ServiceComponents/VerusIdService/VerusIdService";
import WyreService from "../ServiceComponents/WyreService/WyreService";
import PbaasPreconvertService from "../ServiceComponents/PbaasPreconvertService/PbaasPreconvertService";
-
+import AttestationService from "../ServiceComponents/AttestationService/AttestationService";
class Service extends Component {
constructor(props) {
super(props);
@@ -18,7 +18,8 @@ class Service extends Component {
this.SERVICE_COMPONENTS = {
[WYRE_SERVICE_ID]: ,
[VERUSID_SERVICE_ID]: ,
- [PBAAS_PRECONVERT_SERVICE_ID]:
+ [PBAAS_PRECONVERT_SERVICE_ID]: ,
+ [ATTESTATION_SERVICE_ID]: ,
}
}
diff --git a/src/containers/Services/ServiceComponents/AttestationService/AttestationService.js b/src/containers/Services/ServiceComponents/AttestationService/AttestationService.js
new file mode 100644
index 00000000..d147de65
--- /dev/null
+++ b/src/containers/Services/ServiceComponents/AttestationService/AttestationService.js
@@ -0,0 +1,66 @@
+import React, { Component } from "react"
+import { connect } from 'react-redux'
+import { setServiceLoading } from "../../../../actions/actionCreators";
+import { createAlert } from "../../../../actions/actions/alert/dispatchers/alert";
+import { requestServiceStoredData } from "../../../../utils/auth/authBox";
+import { ATTESTATION_SERVICE_ID } from "../../../../utils/constants/services";
+import { VerusAttestationRender } from "./AttestationService.render";
+import { ATTESTATIONS_PROVISIONED } from "../../../../utils/constants/attestations";
+import { requestAttestationData } from "../../../../utils/auth/authBox";
+
+class AttestationService extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ attestations: {},
+ };
+ this.props.navigation.setOptions({title: 'Attestations'});
+ const sdf=234
+ }
+
+ async getAttestations() {
+ this.props.dispatch(setServiceLoading(true, ATTESTATION_SERVICE_ID));
+
+ try {
+ const attestationData = await requestAttestationData(ATTESTATIONS_PROVISIONED);
+ if (attestationData) {
+ this.setState({
+ attestations: attestationData
+ });
+ }
+ } catch (e) {
+ createAlert('Error Loading Attestations', e.message);
+ }
+
+ this.props.dispatch(setServiceLoading(false, ATTESTATION_SERVICE_ID));
+ }
+
+ componentDidMount() {
+
+ this.getAttestations();
+ }
+
+ viewDetails = (attestation) => {
+ this.props.navigation.navigate("ViewAttestation", {attestation});
+ }
+
+ componentDidUpdate(lastProps) {
+ // if (lastProps.encryptedIds !== this.props.encryptedIds) {
+ // this.getLinkedIds()
+ // }
+ }
+
+ render() {
+ return VerusAttestationRender.call(this);
+ }
+}
+
+const mapStateToProps = state => {
+
+ return {
+ loading: state.services.loading[ATTESTATION_SERVICE_ID],
+ attestestationdata: state.attestation
+ };
+};
+
+export default connect(mapStateToProps)(AttestationService);
\ No newline at end of file
diff --git a/src/containers/Services/ServiceComponents/AttestationService/AttestationService.render.js b/src/containers/Services/ServiceComponents/AttestationService/AttestationService.render.js
new file mode 100644
index 00000000..7934faf1
--- /dev/null
+++ b/src/containers/Services/ServiceComponents/AttestationService/AttestationService.render.js
@@ -0,0 +1,54 @@
+import React from "react";
+import { View, Text } from 'react-native'
+import styles from "../../../../styles";
+import AnimatedActivityIndicator from "../../../../components/AnimatedActivityIndicator";
+import {Divider, List} from 'react-native-paper';
+
+export const VerusAttestationRender = function () {
+ return (
+
+ {(this.props.loading) && (
+
+
+
+ )}
+ {!this.props.loading && (
+
+ {Object.values(this.state.attestations || {}).length === 0 && (
+ No attestations present
+ )}
+ {Object.values(this.state.attestations || {}).map((attestation, index) => {
+
+ return (
+
+ this.viewDetails(attestation)}
+ right={props => (
+
+ )}
+ />
+
+
+ );
+
+
+ })}
+
+ )}
+
+ );
+};
diff --git a/src/containers/Services/ServiceComponents/AttestationService/ViewAttestation/ViewAttestation.js b/src/containers/Services/ServiceComponents/AttestationService/ViewAttestation/ViewAttestation.js
new file mode 100644
index 00000000..257fec15
--- /dev/null
+++ b/src/containers/Services/ServiceComponents/AttestationService/ViewAttestation/ViewAttestation.js
@@ -0,0 +1,104 @@
+import React, { Component } from "react"
+import { connect } from 'react-redux'
+
+import { primitives } from "verusid-ts-client"
+
+import * as VDXF_Data from "verus-typescript-primitives/dist/vdxf/vdxfDataKeys";
+
+const { ATTESTATION_NAME } = primitives;
+import { IdentityVdxfidMap } from "verus-typescript-primitives/dist/vdxf/classes/IdentityData";
+import { SafeAreaView, ScrollView, View, Image } from 'react-native'
+
+import { Divider, List, Button, Text } from 'react-native-paper';
+import Styles from "../../../../../styles";
+import Colors from '../../../../../globals/colors';
+
+class ViewAttestation extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ attestationData: {},
+ signer: ""
+ };
+ }
+
+ componentDidMount() {
+ this.updateDisplay();
+ }
+
+ getAttestationData = (dataDescriptors) => {
+
+ const data = {};
+ dataDescriptors.forEach((dataDescriptor) => {
+ const label = dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].label;
+ let key = "";
+
+ if (label === ATTESTATION_NAME.vdxfid) {
+ key = `Attestation name`
+ } else {
+ key = IdentityVdxfidMap[label]?.name || label;
+ }
+
+ const mime = dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].mimetype || "";
+ if (mime.startsWith("text/")) {
+ data[key] = { "message": dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].objectdata.message };
+ } else if (mime.startsWith("image/")) {
+ if (mime === "image/jpeg" || mime === "image/png") {
+ data[key] = { "image": `data:${mime};base64,${Buffer.from(dataDescriptor.objectdata[Object.keys(dataDescriptor.objectdata)[0]].objectdata, "hex").toString("base64")}` };
+ }
+ }
+ });
+
+ return data;
+
+ }
+
+ updateDisplay() {
+ const { attestation } = this.props.route.params
+
+ const signatureData = attestation.data.find((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.SignatureDataKey().vdxfid)[VDXF_Data.SignatureDataKey().vdxfid];
+ const mmrData = attestation.data.find((dataDescriptor) => Object.keys(dataDescriptor)[0] === VDXF_Data.MMRDescriptorKey().vdxfid)[VDXF_Data.MMRDescriptorKey().vdxfid];
+
+ const containingData = this.getAttestationData(mmrData.datadescriptors);
+ this.setState({ attestationData: containingData, signer:attestation.signer });
+
+ }
+
+ render() {
+ return (
+
+
+
+
+
+ {`From: `}{`${this.state.signer}`}
+
+ {this.state.attestationData && Object.keys(this.state.attestationData).map(request => {
+ return (
+
+ this.state.attestationData[request]?.image ? : null}
+ />
+
+
+ );
+ })}
+
+
+ )
+ }
+}
+
+const mapStateToProps = (state) => {
+ return {
+ activeAccount: state.authentication.activeAccount,
+ encryptedPersonalData: state.personal
+ }
+};
+
+export default connect(mapStateToProps)(ViewAttestation);
\ No newline at end of file
diff --git a/src/images/servicelogo/index.js b/src/images/servicelogo/index.js
index 0becf58f..adba8100 100644
--- a/src/images/servicelogo/index.js
+++ b/src/images/servicelogo/index.js
@@ -1,8 +1,9 @@
-import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID } from '../../utils/constants/services'
+import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID, ATTESTATION_SERVICE_ID } from '../../utils/constants/services'
import WYRE_LIGHT from './wyre/wyre_light.svg'
import VERUSID_LIGHT from './verusid/verusid_light.svg'
export default {
[WYRE_SERVICE_ID]: { light: WYRE_LIGHT },
- [VERUSID_SERVICE_ID]: { light: VERUSID_LIGHT }
+ [VERUSID_SERVICE_ID]: { light: VERUSID_LIGHT },
+ [ATTESTATION_SERVICE_ID]: { light: VERUSID_LIGHT },
}
\ No newline at end of file
diff --git a/src/reducers/attestations.js b/src/reducers/attestations.js
new file mode 100644
index 00000000..b505d6fc
--- /dev/null
+++ b/src/reducers/attestations.js
@@ -0,0 +1,19 @@
+import {SIGN_OUT, SET_ATTESTATION_DATA} from '../utils/constants/storeType';
+
+export const attestation = (
+ state = {
+ attestations: null
+ },
+ action,
+) => {
+ switch (action.type) {
+ case SET_ATTESTATION_DATA:
+ return action.data;
+ case SIGN_OUT:
+ return {
+ attestations: null
+ };
+ default:
+ return state;
+ }
+};
diff --git a/src/reducers/index.js b/src/reducers/index.js
index 250fa43d..bfd9704f 100644
--- a/src/reducers/index.js
+++ b/src/reducers/index.js
@@ -4,6 +4,7 @@ import { coins } from './coins';
import { ledger } from './ledger';
import { settings } from './settings';
import { personal } from './personal';
+import { attestation } from './attestations';
import { services } from './services';
import { electrum } from './cache/electrum';
import { headers } from './cache/headers';
@@ -71,5 +72,6 @@ export default combineReducers({
sendModal,
loadingModal,
secureLoading,
- deeplink
+ deeplink,
+ attestation
});
diff --git a/src/reducers/services.js b/src/reducers/services.js
index d637c2e0..ded58121 100644
--- a/src/reducers/services.js
+++ b/src/reducers/services.js
@@ -2,7 +2,7 @@
The personal reducer stores data used by services
*/
-import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID, PBAAS_PRECONVERT_SERVICE_ID } from "../utils/constants/services";
+import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID, PBAAS_PRECONVERT_SERVICE_ID, ATTESTATION_SERVICE_ID } from "../utils/constants/services";
import {
SET_SERVICE_ACCOUNT,
SIGN_OUT,
@@ -24,7 +24,8 @@ export const services = (
loading: {
[WYRE_SERVICE_ID]: false,
[VERUSID_SERVICE_ID]: false,
- [PBAAS_PRECONVERT_SERVICE_ID]: false
+ [PBAAS_PRECONVERT_SERVICE_ID]: false,
+ [ATTESTATION_SERVICE_ID]: false
},
},
action,
@@ -94,7 +95,8 @@ export const services = (
loading: {
[WYRE_SERVICE_ID]: false,
[VERUSID_SERVICE_ID]: false,
- [PBAAS_PRECONVERT_SERVICE_ID]: false
+ [PBAAS_PRECONVERT_SERVICE_ID]: false,
+ [ATTESTATION_SERVICE_ID]: false
},
};
default:
diff --git a/src/utils/api/channels/vrpc/requests/verifyHash.js b/src/utils/api/channels/vrpc/requests/verifyHash.js
new file mode 100644
index 00000000..376cdddf
--- /dev/null
+++ b/src/utils/api/channels/vrpc/requests/verifyHash.js
@@ -0,0 +1,15 @@
+import VrpcProvider from "../../../../vrpc/vrpcInterface"
+
+export const verifyHash = async (systemId, iAddrOrIdentity, base64Sig, hash) => {
+ const provider = VrpcProvider.getVerusIdInterface(systemId);
+
+ const identity = await provider.interface.getIdentity(iAddrOrIdentity);
+
+ return provider.verifyHash(
+ iAddrOrIdentity,
+ base64Sig,
+ hash,
+ identity.result,
+ systemId
+ );
+}
\ No newline at end of file
diff --git a/src/utils/asyncStore/serviceStoredDataStorage.js b/src/utils/asyncStore/serviceStoredDataStorage.js
index 09c51e13..2850d246 100644
--- a/src/utils/asyncStore/serviceStoredDataStorage.js
+++ b/src/utils/asyncStore/serviceStoredDataStorage.js
@@ -1,6 +1,6 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { SERVICE_STORAGE_INTERNAL_KEY } from "../../../env/index";
-import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID } from "../constants/services";
+import { VERUSID_SERVICE_ID, WYRE_SERVICE_ID, ATTESTATION_SERVICE_ID } from "../constants/services";
export const storeServiceStoredData = (data) => {
if (typeof data !== "object")
diff --git a/src/utils/attestations/createAttestationResponse.js b/src/utils/attestations/createAttestationResponse.js
new file mode 100644
index 00000000..55382eb0
--- /dev/null
+++ b/src/utils/attestations/createAttestationResponse.js
@@ -0,0 +1,37 @@
+import { requestAttestationData } from "../../utils/auth/authBox";
+import { ATTESTATIONS_PROVISIONED } from "../../utils/constants/attestations";
+import * as VDXF_Data from "verus-typescript-primitives/dist/vdxf/vdxfDataKeys";
+
+export const createAttestationResponse = async (attestationID, requiredKeys) => {
+
+ const attestationData = await requestAttestationData(ATTESTATIONS_PROVISIONED);
+
+ if (!attestationData[attestationID]) {
+ throw new Error(`Attestation not found in attestation data`);
+ }
+
+ const attestation = attestationData[attestationID];
+ const attestataionKeysToRemove = [];
+ const indexedDatadescriptor = {}
+
+ for (let i = 0; i < attestation.data.length; i++) {
+ if (Object.keys(attestation.data[i])[0] === VDXF_Data.MMRDescriptorKey().vdxfid) {
+
+ for (let j = 0; j < attestation.data[i][VDXF_Data.MMRDescriptorKey().vdxfid].datadescriptors.length; j++) {
+
+ const item = attestation.data[i][VDXF_Data.MMRDescriptorKey().vdxfid].datadescriptors[j].objectdata[VDXF_Data.DataDescriptorKey().vdxfid];
+
+ if (requiredKeys.indexOf(item.label) === -1) {
+ attestataionKeysToRemove.push(j)
+ } else {
+ indexedDatadescriptor[j] = attestation.data[i][VDXF_Data.MMRDescriptorKey().vdxfid].datadescriptors[j];
+ }
+
+ }
+ delete attestation.data[i][VDXF_Data.MMRDescriptorKey().vdxfid].datadescriptors
+ attestation.data[i][VDXF_Data.MMRDescriptorKey().vdxfid].datadescriptors = indexedDatadescriptor
+ }
+ };
+
+ return attestation
+}
\ No newline at end of file
diff --git a/src/utils/auth/authBox.js b/src/utils/auth/authBox.js
index 037c8698..3586e03e 100644
--- a/src/utils/auth/authBox.js
+++ b/src/utils/auth/authBox.js
@@ -176,4 +176,29 @@ export const requestServiceStoredData = async (service) => {
throw new Error("Unable to decrypt service stored data for " + service);
}
}
-};
\ No newline at end of file
+};
+
+export const requestAttestationData = async (dataType) => {
+ const state = store.getState()
+
+ if (
+ state.authentication.activeAccount == null
+ ) {
+ throw new Error("You must be signed in to retrieve attestation data");
+ } else if (state.attestation[dataType] == null) {
+ return {}
+ } else {
+ const password = await requestPassword()
+ const data = decryptkey(password, state.attestation[dataType])
+
+ if (data !== false) {
+ try {
+ return JSON.parse(data)
+ } catch(e) {
+ throw new Error("Unable to parse attestation data")
+ }
+ } else {
+ throw new Error("Unable to decrypt attestation data");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/utils/constants/attestations.js b/src/utils/constants/attestations.js
new file mode 100644
index 00000000..337c15e5
--- /dev/null
+++ b/src/utils/constants/attestations.js
@@ -0,0 +1 @@
+export const ATTESTATIONS_PROVISIONED = "attestations_provisioned"
\ No newline at end of file
diff --git a/src/utils/constants/services.js b/src/utils/constants/services.js
index ba1900b1..40177952 100644
--- a/src/utils/constants/services.js
+++ b/src/utils/constants/services.js
@@ -3,6 +3,7 @@ import { WYRE_SERVICE } from "./intervalConstants"
export const WYRE_SERVICE_ID = 'wyre_service'
export const VERUSID_SERVICE_ID = 'verusid_service'
export const PBAAS_PRECONVERT_SERVICE_ID = 'pbaas_preconvert'
+export const ATTESTATION_SERVICE_ID = 'attestation_service'
export const CONNECTED_SERVICE_DISPLAY_INFO = {
[WYRE_SERVICE_ID]: {
@@ -18,6 +19,11 @@ export const CONNECTED_SERVICE_DISPLAY_INFO = {
title: "Preconvert Currency",
description: "Participate in a PBaaS currency launch by sending your funds to the currency before it starts",
decentralized: true
+ },
+ [ATTESTATION_SERVICE_ID]: {
+ title: "Attestations",
+ description: "Stored attestations that can be used to prove information about you to services you use",
+ decentralized: true
}
}
@@ -25,7 +31,7 @@ export const CONNECTED_SERVICE_CHANNELS = {
[WYRE_SERVICE_ID]: WYRE_SERVICE
}
-export const CONNECTED_SERVICES = [VERUSID_SERVICE_ID, /*PBAAS_PRECONVERT_SERVICE_ID ,*/ WYRE_SERVICE_ID]
+export const CONNECTED_SERVICES = [VERUSID_SERVICE_ID, /*PBAAS_PRECONVERT_SERVICE_ID ,*/ WYRE_SERVICE_ID, ATTESTATION_SERVICE_ID]
// Wyre specific constants
export const WYRE_INDIVIDUAL_NAME = 'individualLegalName'
diff --git a/src/utils/constants/storeType.js b/src/utils/constants/storeType.js
index 1717a2db..445b53ff 100644
--- a/src/utils/constants/storeType.js
+++ b/src/utils/constants/storeType.js
@@ -309,4 +309,7 @@ export const SET_PERSONAL_DATA = "SET_PERSONAL_DATA"
// Services
export const SET_SERVICE_STORED_DATA = "SET_SERVICE_STORED_DATA"
-export const SET_SERVICE_DATA = "SET_SERVICE_DATA"
\ No newline at end of file
+export const SET_SERVICE_DATA = "SET_SERVICE_DATA"
+
+// Attestations
+export const SET_ATTESTATION_DATA = "SET_ATTESTATION_DATA"
\ No newline at end of file
diff --git a/src/utils/deeplink/handlePersonalDataSend.js b/src/utils/deeplink/handlePersonalDataSend.js
new file mode 100644
index 00000000..404a7cd0
--- /dev/null
+++ b/src/utils/deeplink/handlePersonalDataSend.js
@@ -0,0 +1,30 @@
+import axios from "axios";
+import * as primitives from "verus-typescript-primitives"
+
+
+const handlers = {
+ [primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid]: async (uri, response) => {
+ return await axios.post(
+ uri,
+ response
+ );
+ },
+ [primitives.LOGIN_CONSENT_PERSONALINFO_WEBHOOK_VDXF_KEY.vdxfid]: async (uri, response) => {
+ return await axios.post(
+ uri,
+ response
+ );
+ }
+}
+
+export const handlePersonalDataSend = (response, redirectinfo) => {
+ const { vdxfkey, uri } = redirectinfo
+
+ return handlers[vdxfkey] == null ? null : handlers[vdxfkey](uri, response);
+}
+
+export const handleAttestationDataSend = (response, redirectinfo) => {
+ const { vdxfkey, uri } = redirectinfo
+
+ return handlers[vdxfkey] == null ? null : handlers[vdxfkey](uri, response);
+}
\ No newline at end of file
diff --git a/src/utils/nativeStore/attestationDataStorage.js b/src/utils/nativeStore/attestationDataStorage.js
new file mode 100644
index 00000000..9847bb10
--- /dev/null
+++ b/src/utils/nativeStore/attestationDataStorage.js
@@ -0,0 +1,69 @@
+var RNFS = require('react-native-fs');
+import { ATTESTATION_DATA_STORAGE_INTERNAL_KEY } from '../../../env/index'
+
+export const storeAttestationData = (data) => {
+ if (typeof data !== 'object') throw new Error(`Attestation data store function expected object, received ${typeof data}`)
+
+ return new Promise((resolve, reject) => {
+ RNFS.writeFile(RNFS.DocumentDirectoryPath + `/${ATTESTATION_DATA_STORAGE_INTERNAL_KEY}.txt`, JSON.stringify(data), 'utf8')
+ .then((success) => {
+ resolve(data);
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+};
+
+export const loadAttestationData = () => {
+ return new Promise((resolve, reject) => {
+ RNFS.readFile(RNFS.DocumentDirectoryPath + `/${ATTESTATION_DATA_STORAGE_INTERNAL_KEY}.txt`, "utf8")
+ .then(res => {
+ if (!res) {
+ resolve({});
+ } else {
+ _res = JSON.parse(res);
+ resolve(_res);
+ }
+ })
+ .catch(err => {
+ if (err.code === 'ENOENT') {
+ resolve({});
+ } else {
+ reject(err);
+ }
+ });
+ })
+};
+
+export const clearAllAttestationData = () => {
+ return new Promise((resolve, reject) => {
+ RNFS.unlink(RNFS.DocumentDirectoryPath + `/${ATTESTATION_DATA_STORAGE_INTERNAL_KEY}.txt`)
+ .then(() => {
+ resolve();
+ })
+ .catch(err => reject(err));
+ })
+};
+
+export const storeAttestationDataForUser = async (data, accountHash) => {
+ let allAttestationData = { ...(await loadAttestationData()) }
+ allAttestationData[accountHash] = data
+ return (await storeAttestationData(allAttestationData))[accountHash]
+}
+
+export const deleteAttestationDataForUser = async (accountHash) => {
+ let allAttestationData = { ...(await loadAttestationData()) }
+ delete allAttestationData[accountHash]
+ return (await storeAttestationData(allAttestationData))[accountHash]
+}
+
+export const loadAttestationDataForUser = async (accountHash) => {
+ const allAttestationData = await loadAttestationData()
+
+ if (allAttestationData[accountHash] == null)
+ return {
+ attestations_provisioned: null
+ };
+ else return allAttestationData[accountHash];
+};
diff --git a/src/utils/nativeStore/personalDataStorage.js b/src/utils/nativeStore/personalDataStorage.js
new file mode 100644
index 00000000..1f220b9e
--- /dev/null
+++ b/src/utils/nativeStore/personalDataStorage.js
@@ -0,0 +1,67 @@
+var RNFS = require('react-native-fs');
+import { PERSONAL_DATA_STORAGE_INTERNAL_KEY } from '../../../env/index'
+
+export const storePersonalData = (data) => {
+ if (typeof data !== 'object') throw new Error(`Personal data store function expected object, received ${typeof data}`)
+
+ return new Promise((resolve, reject) => {
+ RNFS.writeFile(RNFS.DocumentDirectoryPath + `/${PERSONAL_DATA_STORAGE_INTERNAL_KEY}.txt`, JSON.stringify(data), 'utf8')
+ .then((success) => {
+ resolve(data);
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+};
+
+export const loadPersonalData = () => {
+ return new Promise((resolve, reject) => {
+ RNFS.readFile(RNFS.DocumentDirectoryPath + `/${PERSONAL_DATA_STORAGE_INTERNAL_KEY}.txt`, "utf8")
+ .then(res => {
+ if (!res) {
+ resolve({});
+ } else {
+ _res = JSON.parse(res);
+ resolve(_res);
+ }
+ })
+ .catch(err => reject(err));
+ })
+};
+
+export const clearAllPersonalData = () => {
+ return new Promise((resolve, reject) => {
+ RNFS.unlink(RNFS.DocumentDirectoryPath + `/${PERSONAL_DATA_STORAGE_INTERNAL_KEY}.txt`)
+ .then(() => {
+ resolve();
+ })
+ .catch(err => reject(err));
+ })
+};
+
+export const storePersonalDataForUser = async (data, accountHash) => {
+ let allPersonalData = { ...(await loadPersonalData()) }
+ allPersonalData[accountHash] = data
+ return (await storePersonalData(allPersonalData))[accountHash]
+}
+
+export const deletePersonalDataForUser = async (accountHash) => {
+ let allPersonalData = { ...(await loadPersonalData()) }
+ delete allPersonalData[accountHash]
+ return (await storePersonalData(allPersonalData))[accountHash]
+}
+
+export const loadPersonalDataForUser = async (accountHash) => {
+ const allPersonalData = await loadPersonalData()
+
+ if (allPersonalData[accountHash] == null)
+ return {
+ attributes: null,
+ contact: null,
+ locations: null,
+ payment_methods: null,
+ images: null,
+ };
+ else return allPersonalData[accountHash];
+};
diff --git a/src/utils/personal/displayUtils.js b/src/utils/personal/displayUtils.js
index 610d406f..d0606680 100644
--- a/src/utils/personal/displayUtils.js
+++ b/src/utils/personal/displayUtils.js
@@ -8,27 +8,47 @@ import {
} from "../constants/personal";
import { Platform } from 'react-native';
var RNFS = require('react-native-fs');
+import { primitives } from "verusid-ts-client"
+import { requestPersonalData } from "../auth/authBox";
+import {
+ PERSONAL_ATTRIBUTES,
+ PERSONAL_CONTACT,
+ PERSONAL_LOCATIONS,
+ PERSONAL_PAYMENT_METHODS,
+ PERSONAL_IMAGES,
+} from "../constants/personal";
+
+import { IdentityVdxfidMap } from 'verus-typescript-primitives/dist/vdxf/classes/IdentityData';
+import Colors from '../../globals/colors';
+
+const { IDENTITYDATA_FIRSTNAME, IDENTITYDATA_LASTNAME, IDENTITYDATA_MIDDLENAME,
+ BANK_ACCOUNT_COUNTRY, BANK_ACCOUNT_CURRENCY, BANK_ACCOUNT_NUMBER, BANK_ACCOUNT_TYPE } = primitives;
+const { IDENTITYDATA_HOMEADDRESS_STREET1, IDENTITYDATA_HOMEADDRESS_STREET2, IDENTITYDATA_HOMEADDRESS_CITY, IDENTITYDATA_HOMEADDRESS_REGION, IDENTITYDATA_HOMEADDRESS_POSTCODE, IDENTITYDATA_HOMEADDRESS_COUNTRY } = primitives;
+const { IDENTITYDATA_CONTACT, IDENTITYDATA_PERSONAL_DETAILS, IDENTITYDATA_LOCATIONS, IDENTITYDATA_DOCUMENTS_AND_IMAGES, IDENTITYDATA_BANKING_INFORMATION } = primitives;
+
+
+export const renderPersonalFullName = (state) => {
+
+ if (!state[IDENTITYDATA_FIRSTNAME.vdxfid] && !state[IDENTITYDATA_LASTNAME.vdxfid]) {
+ return {title: "John Doe"}
+ }
-export const renderPersonalFullName = (name) => {
return {
- title: `${name.first} ${
- name.middle != null && name.middle.length > 0 ? name.middle + " " : ""
- }${name.last}`
+ title: `${state[IDENTITYDATA_FIRSTNAME.vdxfid] || ""} ${state[IDENTITYDATA_MIDDLENAME.vdxfid] != null && state[IDENTITYDATA_MIDDLENAME.vdxfid] > 0 ? state[IDENTITYDATA_MIDDLENAME.vdxfid] + " " : ""
+ }${state[IDENTITYDATA_LASTNAME.vdxfid] || ""}`
};
};
export const renderPersonalPhoneNumber = (phone, includeEmoji = true) => {
return {
- title: `${
- includeEmoji &&
+ title: `${includeEmoji &&
CALLING_CODES_TO_ISO_3166[phone.calling_code] != null &&
ISO_3166_COUNTRIES[CALLING_CODES_TO_ISO_3166[phone.calling_code]] != null
- ? ISO_3166_COUNTRIES[CALLING_CODES_TO_ISO_3166[phone.calling_code]]
- .emoji + " "
- : ""
- }${phone.calling_code.length > 0 ? phone.calling_code : "+0"} ${
- phone.number.length > 0 ? phone.number : "000000000"
- }`,
+ ? ISO_3166_COUNTRIES[CALLING_CODES_TO_ISO_3166[phone.calling_code]]
+ .emoji + " "
+ : ""
+ }${phone.calling_code.length > 0 ? phone.calling_code : "+0"} ${phone.number.length > 0 ? phone.number : "000000000"
+ }`,
};
};
@@ -74,14 +94,13 @@ export const renderPersonalDocument = (document) => {
document.image_type == null
? 'Document'
: PERSONAL_IMAGE_TYPE_SCHEMA[document.image_type] == null
- ? "??"
- : `${PERSONAL_IMAGE_TYPE_SCHEMA[document.image_type].title}${
- document.image_subtype == null ||
+ ? "??"
+ : `${PERSONAL_IMAGE_TYPE_SCHEMA[document.image_type].title}${document.image_subtype == null ||
PERSONAL_IMAGE_SUBTYPE_SCHEMA[document.image_subtype] == null
- ? ""
- : ` (${PERSONAL_IMAGE_SUBTYPE_SCHEMA[
- document.image_subtype
- ].title.toLowerCase()})`
+ ? ""
+ : ` (${PERSONAL_IMAGE_SUBTYPE_SCHEMA[
+ document.image_subtype
+ ].title.toLowerCase()})`
}`,
};
};
@@ -102,37 +121,121 @@ export const renderPersonalTaxId = (taxCountry) => {
export const renderPersonalAddress = (address) => {
return {
title:
- address.street1.length > 0
- ? `${address.street1}${
- address.street2 != null && address.street2.length > 0 ? `, ${address.street2}` : ""
- }`
+ address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid].length > 0
+ ? `${address[IDENTITYDATA_HOMEADDRESS_STREET1.vdxfid]}${address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid] != null && address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid].length > 0 ? `, ${address[IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]}` : ""
+ }`
: "Empty address",
- description: `${address.postal_code.length > 0 ? `${address.postal_code} ` : ""}${
- address.state_province_region.length > 0 ? `${address.state_province_region}, ` : ""
- }${address.city.length > 0 ? `${address.city}, ` : "Unknown City, "}${
- ISO_3166_COUNTRIES[address.country] != null
- ? `${ISO_3166_COUNTRIES[address.country].emoji} ${ISO_3166_COUNTRIES[address.country].name}`
+ description: `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid].length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_POSTCODE.vdxfid]} ` : ""}${address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_REGION.vdxfid]}, ` : ""
+ }${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]?.length > 0 ? `${address[IDENTITYDATA_HOMEADDRESS_CITY.vdxfid]}, ` : "Unknown City, "}${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]] != null
+ ? `${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].emoji} ${ISO_3166_COUNTRIES[address[IDENTITYDATA_HOMEADDRESS_COUNTRY.vdxfid]].name}`
: "Unknown Country"
- }`,
+ }`,
};
}
export const renderPersonalBankAccount = (account) => {
- const accountLocaleString = ISO_3166_COUNTRIES[account.country]
- ? `${ISO_3166_COUNTRIES[account.country].emoji} Account`
+ const accountLocaleString = ISO_3166_COUNTRIES[account[BANK_ACCOUNT_COUNTRY.vdxfid]]
+ ? `${ISO_3166_COUNTRIES[account[BANK_ACCOUNT_COUNTRY.vdxfid]].emoji} Account`
: "Bank Account";
const accountNumberString =
- account.account_number != null && account.account_number.length > 4
- ? ` ending in ${account.account_number.slice(-4)}`
+ account[BANK_ACCOUNT_NUMBER.vdxfid] != null && account[BANK_ACCOUNT_NUMBER.vdxfid].length > 4
+ ? ` ending in ${account[BANK_ACCOUNT_NUMBER.vdxfid].slice(-4)}`
: "";
- const accountDescription = `${
- account.primary_currency != null && account.primary_currency.length > 0
- ? account.primary_currency + " "
- : ""
- }${account.account_type}`;
+ const accountDescription = `${account[BANK_ACCOUNT_CURRENCY.vdxfid] != null && account[BANK_ACCOUNT_CURRENCY.vdxfid].length > 0
+ ? account[BANK_ACCOUNT_CURRENCY.vdxfid] + " "
+ : ""
+ }${account[BANK_ACCOUNT_TYPE.vdxfid]}`;
return {
title: `${accountLocaleString}${accountNumberString}`,
description: accountDescription,
};
-};
\ No newline at end of file
+};
+
+/********************************/
+// template defaultPersonalProfileDataTemplate in the order:
+// new PersonalDataCategory(),
+// new ContactDataCategory(),
+// new LocationDataCategory(),
+// new BankingDataCategory(),
+// new DocumentsCategory()
+/********************************/
+
+export const checkPersonalDataCatagories = async (profileDataRequested = []) => {
+ let success = true;
+ await Promise.all(Object.keys(profileDataRequested).map(async (permission) => {
+ let errorDetails = "";
+ let profiletype;
+ let optionalKeys = {}
+ let attributes = {};
+ switch (permission) {
+
+ case IDENTITYDATA_PERSONAL_DETAILS.vdxfid:
+ attributes = await requestPersonalData(PERSONAL_ATTRIBUTES);
+ optionalKeys = { [primitives.IDENTITYDATA_MIDDLENAME.vdxfid]: true };
+ profiletype = primitives.defaultPersonalProfileDataTemplate[0].data;
+ break;
+ case IDENTITYDATA_CONTACT.vdxfid:
+ attributes = await requestPersonalData(PERSONAL_CONTACT);
+ profiletype = primitives.defaultPersonalProfileDataTemplate[1].data;
+ break;
+ case IDENTITYDATA_LOCATIONS.vdxfid:
+ const locationReply = await requestPersonalData(PERSONAL_LOCATIONS);
+ attributes = locationReply.physical_addresses && locationReply.physical_addresses.length > 0 ? locationReply.physical_addresses[0] : {};
+ optionalKeys = { [primitives.IDENTITYDATA_HOMEADDRESS_STREET2.vdxfid]: true };
+ profiletype = primitives.defaultPersonalProfileDataTemplate[2].data;
+ break;
+ case IDENTITYDATA_BANKING_INFORMATION.vdxfid:
+ const bankRetval = await checkBankAccountPresent();
+ attributes = bankRetval.attributes;
+ profiletype = bankRetval.profiletype;
+ break;
+ case IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid:
+ const retval = await checkDocumentsPresent();
+ attributes = retval.attributes;
+ profiletype = retval.profiletype;
+ break;
+ }
+
+ profiletype.forEach((templateCategory) => {
+ const one = attributes[templateCategory.vdxfkey];
+ if (!optionalKeys[templateCategory.vdxfkey] && ((typeof one === 'object' && Array.isArray(one) && one.length === 0) ||
+ (typeof one === 'object' && Object.keys(one).length === 0) ||
+ (typeof one === 'string' && one.length === 0)
+ || one == undefined)) {
+ errorDetails += (errorDetails ? ", " : "") +`${IdentityVdxfidMap[templateCategory.vdxfkey]?.name || templateCategory.vdxfkey}`;
+ }
+ })
+
+ if (errorDetails.length > 0) {
+ profileDataRequested[permission].details = "Missing Information: " + errorDetails;
+ profileDataRequested[permission].color = Colors.warningButtonColor;
+ success = false;
+ }
+
+ }));
+ return success;
+}
+
+export const checkBankAccountPresent = async () => {
+
+ const paymentMethods = await requestPersonalData(PERSONAL_PAYMENT_METHODS);
+
+ if (!paymentMethods.bank_accounts || paymentMethods.bank_accounts.length === 0) {
+ return { profiletype: [{ vdxfkey: primitives.BANK_ACCOUNT.vdxfid }], attributes: { [primitives.BANK_ACCOUNT.vdxfid]: "" } };
+ }
+ return { profiletype: [{ vdxfkey: primitives.BANK_ACCOUNT.vdxfid }], attributes: { [primitives.BANK_ACCOUNT.vdxfid]: "OK" } };
+}
+
+export const checkDocumentsPresent = async () => {
+
+ const images = await requestPersonalData(PERSONAL_IMAGES);
+
+ if (!images.documents || images.documents.length === 0) {
+ return { profiletype: [{ vdxfkey: primitives.IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid }], attributes: { [primitives.IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid]: "" }};
+ }
+ return { profiletype: [{ vdxfkey: primitives.IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid }], attributes: { [primitives.IDENTITYDATA_DOCUMENTS_AND_IMAGES.vdxfid]: "OK" }};
+
+}
+
+export const checkPersonalDataKeys = () => { }
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 16b1187b..4bd255bf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -946,7 +946,7 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
-"@bitgo/blake2b-wasm@^3.0.1", "@bitgo/blake2b-wasm@https://github.com/michaeltout/blake2b-wasm/", "blake2b-wasm@https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b", "blake2b-wasm@https://github.com/michaeltout/blake2b-wasm/":
+"@bitgo/blake2b-wasm@^3.0.1", "@bitgo/blake2b-wasm@https://github.com/michaeltout/blake2b-wasm/":
version "2.0.0"
resolved "https://github.com/michaeltout/blake2b-wasm/#a16070b30bb8d8aee670f0c69b642913eca79998"
dependencies:
@@ -960,7 +960,7 @@
"@bitgo/blake2b-wasm" "^3.0.1"
nanoassert "^2.0.0"
-"@bitgo/utxo-lib@git+https://github.com/VerusCoin/BitGoJS.git#7c754d4a5920198d9fe6827d3e23bd5cf431f264":
+"@bitgo/utxo-lib@git+https://github.com/VerusCoin/BitGoJS.git#7c754d4a5920198d9fe6827d3e23bd5cf431f264", "@bitgo/utxo-lib@https://github.com/VerusCoin/BitGoJS.git#f8723bcc2bf4052de171ca8654de23fc06a03337":
version "1.9.6"
resolved "git+https://github.com/VerusCoin/BitGoJS.git#7c754d4a5920198d9fe6827d3e23bd5cf431f264"
dependencies:
@@ -986,31 +986,6 @@
optionalDependencies:
secp256k1 "3.5.2"
-"@bitgo/utxo-lib@https://github.com/VerusCoin/BitGoJS.git#f8723bcc2bf4052de171ca8654de23fc06a03337":
- version "1.9.6"
- resolved "https://github.com/VerusCoin/BitGoJS.git#f8723bcc2bf4052de171ca8654de23fc06a03337"
- dependencies:
- "@bitgo/blake2b" "3.0.1"
- bech32 "0.0.3"
- bigi "1.4.0"
- bip32 "2.0.6"
- bip66 "1.1.0"
- bitcoin-ops "git+https://github.com/VerusCoin/bitcoin-ops"
- bs58check "2.0.0"
- create-hash "1.1.0"
- create-hmac "1.1.3"
- debug "~3.1.0"
- ecurve "1.0.0"
- merkle-lib "2.0.10"
- pushdata-bitcoin "1.0.1"
- randombytes "2.0.1"
- safe-buffer "5.0.1"
- typeforce "1.11.3"
- varuint-bitcoin "1.0.4"
- wif "2.0.1"
- optionalDependencies:
- secp256k1 "3.5.2"
-
"@callstack/react-theme-provider@^3.0.5":
version "3.0.8"
resolved "https://registry.yarnpkg.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.8.tgz#d0d7ac71e422133c5f7b78f4c4aa1bc57f156f50"
@@ -3367,6 +3342,12 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
+blake2b-wasm@^2.4.0, "blake2b-wasm@https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b", "blake2b-wasm@https://github.com/michaeltout/blake2b-wasm/":
+ version "2.0.0"
+ resolved "https://github.com/michaeltout/blake2b-wasm/#a16070b30bb8d8aee670f0c69b642913eca79998"
+ dependencies:
+ nanoassert "1.0.0"
+
"blake2b@git+https://github.com/michaeltout/blake2b":
version "2.1.3"
resolved "git+https://github.com/michaeltout/blake2b#777f844b986173d08fc27fe9547c6f6320a82d62"
@@ -3374,6 +3355,13 @@ bl@^4.1.0:
blake2b-wasm "https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b"
nanoassert "^1.0.0"
+"blake2b@https://github.com/VerusCoin/blake2b":
+ version "2.1.4"
+ resolved "https://github.com/VerusCoin/blake2b#578dc12b7b68a3ce76d1e1add1402b28a5890a6b"
+ dependencies:
+ blake2b-wasm "^2.4.0"
+ nanoassert "^2.0.0"
+
bn.js@5.2.1, bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
@@ -11557,21 +11545,22 @@ version_compare@0.0.3:
bignumber.js "^9.0.0"
verus-zkedid-utils "https://github.com/michaeltout/verus-zkedid-utils#dev"
-"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
- version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#b130230b0ba8f330972ea9466a7b152c1690dd75"
+"verus-typescript-primitives@file:../../verus-typescript-primitives":
+ version "1.0.1"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
+ blake2b "https://github.com/VerusCoin/blake2b"
bn.js "5.2.1"
bs58check "https://github.com/bitcoinjs/bs58check"
create-hash "1.2.0"
-"verus-typescript-primitives@https://github.com/VerusCoin/verus-typescript-primitives.git":
- version "1.0.0"
- resolved "https://github.com/VerusCoin/verus-typescript-primitives.git#ca735cf46b0dd4ad4a6d4b37ab451bd2f5af4c3e"
+"verus-typescript-primitives@file:d:/dev/verus-typescript-primitives", "verus-typescript-primitives@https://github.com/VerusCoin/verus-typescript-primitives.git":
+ version "1.0.1"
dependencies:
base64url "3.0.1"
+ bech32 "2.0.0"
+ blake2b "https://github.com/VerusCoin/blake2b"
bn.js "5.2.1"
bs58check "https://github.com/bitcoinjs/bs58check"
create-hash "1.2.0"
@@ -11593,7 +11582,7 @@ version_compare@0.0.3:
"verusd-rpc-ts-client@https://github.com/VerusCoin/verusd-rpc-ts-client.git":
version "0.1.0"
- resolved "https://github.com/VerusCoin/verusd-rpc-ts-client.git#c12448144559b8ffecf58630346a97cdb5356dde"
+ resolved "https://github.com/VerusCoin/verusd-rpc-ts-client.git#62d260563c23ecf9b3333355e8596191c764e415"
dependencies:
axios "1.6.5"
verus-typescript-primitives "https://github.com/VerusCoin/verus-typescript-primitives.git"