From 1c0a530a3ae1375afd2625a1326ca063d82aca03 Mon Sep 17 00:00:00 2001 From: Sai Ranjit Tummalapalli Date: Wed, 17 Jul 2024 14:53:46 +0530 Subject: [PATCH] feat: add qrcode in certificate Signed-off-by: Sai Ranjit Tummalapalli --- app/screens/CredentialDetailsW3C.tsx | 34 +++++++++++++++++++++++++--- package.json | 4 +++- yarn.lock | 19 +++++++++++----- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/app/screens/CredentialDetailsW3C.tsx b/app/screens/CredentialDetailsW3C.tsx index fc3abf50..21c7a3ea 100644 --- a/app/screens/CredentialDetailsW3C.tsx +++ b/app/screens/CredentialDetailsW3C.tsx @@ -7,9 +7,11 @@ import { deleteCredentialExchangeRecordById, useCredentialByState, CredentialState, + createInvitation, } from '@adeya/ssi' import { BrandingOverlay } from '@hyperledger/aries-oca' import { CredentialOverlay } from '@hyperledger/aries-oca/build/legacy' +import { toString as toQRCodeString } from 'qrcode' import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { DeviceEventEmitter, Image, ImageBackground, Platform, StyleSheet, Text, View } from 'react-native' @@ -307,13 +309,40 @@ const CredentialDetailsW3C: React.FC = ({ navigation, ro ) } + const getA4Sizes = (type: 'landscape' | 'portrait') => { + return { + width: type === 'landscape' ? 842 : 595, + height: type === 'landscape' ? 595 : 842, + } + } + + const generateQRCodeString = async (text: string) => { + return toQRCodeString(text, { + width: 150, + margin: 1, + color: { + light: '#0000', + }, + }) + } + const navigateToRenderCertificate = async () => { try { setIsGeneratingPdf(true) + const invitation = await createInvitation(agent, 'https://adeya.com') + + const qrCodeSvg = await generateQRCodeString(invitation.invitationUrl) + const certificateAttributes = w3cCredential?.credential.credentialSubject.claims - let content = w3cCredential?.credential.prettyVc + const prettyVc = w3cCredential?.credential.prettyVc + let content = prettyVc.certificate + + const invitationUrlPlaceholder = '{{invitationUrl}}' + const invitationUrlEscapedPlaceholder = invitationUrlPlaceholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + + content = content.replace(new RegExp(invitationUrlEscapedPlaceholder, 'g'), qrCodeSvg) Object.keys(certificateAttributes).forEach(key => { // Statically picking the value of placeholder @@ -329,8 +358,7 @@ const CredentialDetailsW3C: React.FC = ({ navigation, ro fileName: w3cCredential?.credential.type[1], directory: 'Documents', // add height and width to the options of a4 paper size - height: 595, - width: 842, + ...getA4Sizes(prettyVc.orientation), } const file = await RNHTMLtoPDF.convert(options) diff --git a/package.json b/package.json index ee29b1f0..21c23f2a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "prepare": "husky install" }, "dependencies": { - "@adeya/ssi": "0.0.1-alpha.29", + "@adeya/ssi": "0.0.1-alpha.30", "@ayanworks/credo-polygon-w3c-module": "1.0.0", "@ethersproject/shims": "^5.7.0", "@formatjs/intl-datetimeformat": "^6.10.0", @@ -51,6 +51,7 @@ "lodash.startcase": "^4.4.0", "moment": "^2.29.4", "process": "^0.11.0", + "qrcode": "^1.5.3", "query-string": "^8.1.0", "react": "18.2.0", "react-i18next": "^13.0.3", @@ -109,6 +110,7 @@ "@types/lodash.merge": "^4.6.7", "@types/lodash.shuffle": "^4.2.7", "@types/lodash.startcase": "^4.4.7", + "@types/qrcode": "^1.5.5", "@types/react": "^18.0.24", "@types/react-native": "^0.72.2", "@types/react-native-html-to-pdf": "^0.8.3", diff --git a/yarn.lock b/yarn.lock index 9f7a2711..a4a55e2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@adeya/ssi@0.0.1-alpha.29": - version "0.0.1-alpha.29" - resolved "https://registry.yarnpkg.com/@adeya/ssi/-/ssi-0.0.1-alpha.29.tgz#154534a74a5ebbcd94f61d5d70d5f7ab9d69d9d3" - integrity sha512-OETGUdrlLpVWYBkrvGaRUOXjjdPGS+XCXLU06Y8hR0rlj6pY5Yijj0S1GL+VvZnjPHtkGFr5AdIqX5ENtMADFw== +"@adeya/ssi@0.0.1-alpha.30": + version "0.0.1-alpha.30" + resolved "https://registry.yarnpkg.com/@adeya/ssi/-/ssi-0.0.1-alpha.30.tgz#62e9131dc97af765ec9269fd418c3be2783c2265" + integrity sha512-v3O1MyZEPrYYQ64rADrWpvfFIdspAP43n+rsOk96nfpsQhono6UAU3wx5SP25TIr1mYMFOQyeDHXgFZJ2xKV5Q== dependencies: "@credo-ts/anoncreds" "0.5.3" "@credo-ts/askar" "0.5.3" @@ -3610,6 +3610,13 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/qrcode@^1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.5.5.tgz#993ff7c6b584277eee7aac0a20861eab682f9dac" + integrity sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg== + dependencies: + "@types/node" "*" + "@types/react-native-html-to-pdf@^0.8.3": version "0.8.3" resolved "https://registry.yarnpkg.com/@types/react-native-html-to-pdf/-/react-native-html-to-pdf-0.8.3.tgz#0e41b666c711b114957e42f7a7c665fb2fea8045" @@ -9752,9 +9759,9 @@ pvutils@^1.1.3: resolved "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz" integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== -qrcode@^1.5.1: +qrcode@^1.5.1, qrcode@^1.5.3: version "1.5.3" - resolved "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170" integrity sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg== dependencies: dijkstrajs "^1.0.1"