<template> <!-- QUICK NAV --> <nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200"> <ul class="flex text-2xl p-2 gap-2"> <!-- Home Feed --> <li class="basis-1/5 rounded-md text-slate-500"> <router-link :to="{ name: 'home' }" class="block text-center py-3 px-1"> <fa icon="house-chimney" class="fa-fw"></fa> </router-link> </li> <!-- Search --> <li class="basis-1/5 rounded-md text-slate-500"> <router-link :to="{ name: 'discover' }" class="block text-center py-3 px-1" > <fa icon="magnifying-glass" class="fa-fw"></fa> </router-link> </li> <!-- Projects --> <li class="basis-1/5 rounded-md text-slate-500"> <router-link :to="{ name: 'projects' }" class="block text-center py-3 px-1" > <fa icon="folder-open" class="fa-fw"></fa> </router-link> </li> <!-- Commitments --> <li class="basis-1/5 rounded-md text-slate-500"> <router-link :to="{ name: 'commitments' }" class="block text-center py-3 px-1" > <fa icon="hand" class="fa-fw"></fa> </router-link> </li> <!-- Profile --> <li class="basis-1/5 rounded-md bg-slate-400 text-white"> <router-link :to="{ name: 'account' }" class="block text-center py-3 px-1" > <fa icon="circle-user" class="fa-fw"></fa> </router-link> </li> </ul> </nav> <!-- CONTENT --> <section id="Content" class="p-6 pb-24"> <!-- Heading --> <h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8"> Your Identity </h1> <!-- Friend referral requirement notice --> <div class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mb-4" > <p class="mb-4"> <b>Important:</b> before you can create a new project or commit time to one, you need a friend to register you. </p> <button id="btnShowQR" class="inline-block text-md uppercase bg-amber-600 text-white px-4 py-2 rounded-md" > Share Your ID </button> </div> <!-- Identity Details --> <div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4"> <h2 class="text-xl font-semibold mb-2">Firstname Lastname</h2> <div class="text-slate-500 text-sm font-bold">ID</div> <div class="text-sm text-slate-500 flex justify-between items-center mb-1" > <span ><code>{{ address }}</code> <button @click="copy(address)"> <fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa> </button> </span> <span> <button class="text-xs uppercase bg-slate-500 text-white px-1.5 py-1 rounded-md" > <fa icon="share-nodes" class="fa-fw"></fa> </button> <button class="text-xs uppercase bg-slate-500 text-white px-1.5 py-1 rounded-md ml-1" > <fa icon="qrcode" class="fa-fw"></fa> </button> </span> </div> <div class="text-slate-500 text-sm font-bold">Public Key</div> <div class="text-sm text-slate-500 mb-1"> <span ><code>{{ publicHex }}</code> <button @click="copy(publicHex)"> <fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa> </button> </span> </div> <div class="text-slate-500 text-sm font-bold">Derivation Path</div> <div class="text-sm text-slate-500 mb-1"> <span ><code>{{ UPORT_ROOT_DERIVATION_PATH }}</code> <button @click="copy(UPORT_ROOT_DERIVATION_PATH)"> <fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa> </button> </span> </div> </div> <router-link :to="{ name: 'new-edit-account' }" class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8" >Edit Identity</router-link > <h3 class="text-sm uppercase font-semibold mb-3">Contact Actions</h3> <a href="contact-scan.html" class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6" >Scan New Contact</a > <h3 class="text-sm uppercase font-semibold mb-3">Identity Actions</h3> <a href="" class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-2" >Backup Seed</a > <a href="" class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6" >Backup Other Data</a > <!-- QR code popup --> <dialog id="dlgQR" class="backdrop:bg-black/75 rounded-md"> <form method="dialog"> <div class="text-slate-500 text-center"> <b>ID:</b> <code>did:peer:kl45kj41lk451kl3</code> </div> <img src="img/sample-qr-code.png" class="w-full mb-3" /> <button value="cancel" class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-2" > Copy to Clipboard </button> <button value="cancel" class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md" > Close </button> </form> </dialog> </section> </template> <script lang="ts"> import { Options, Vue } from "vue-class-component"; import { useClipboard } from "@vueuse/core"; import { createIdentifier, deriveAddress, newIdentifier } from "../libs/crypto"; import { IIdentifier } from "@veramo/core"; import * as R from "ramda"; import { db } from "../db"; import { useAppStore } from "@/store/app"; import { ref } from "vue"; @Options({ components: {}, }) export default class AccountViewView extends Vue { mnemonic = ""; address = ""; privateHex = ""; publicHex = ""; UPORT_ROOT_DERIVATION_PATH = ""; source = ref("Hello"); copy = useClipboard().copy; async created() { const previousIdentifiers: Array<IIdentifier> = []; const toLowercase = true; const appCondition = useAppStore().condition; if (appCondition == "uninitialized") { this.mnemonic = createIdentifier(); [ this.address, this.privateHex, this.publicHex, this.UPORT_ROOT_DERIVATION_PATH, ] = deriveAddress(this.mnemonic); //appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... derived keys and address..."})) const prevIds = previousIdentifiers || []; if (toLowercase) { const foundEqual = R.find( (id: IIdentifier) => id.did.split(":")[2] === this.address, prevIds ); if (foundEqual) { // appStore.dispatch(appSlice.actions.addLog({log: true, msg: "Will create a normal-case version of the DID since a regular version exists."})) } else { this.address = this.address.toLowerCase(); } } else { // They're not trying to convert to lowercase. const foundLower = R.find( (id: IIdentifier) => id.did.split(":")[2] === this.address.toLowerCase(), prevIds ); if (foundLower) { // appStore.dispatch(appSlice.actions.addLog({log: true, msg: "Will create a lowercase version of the DID since a lowercase version exists."})) this.address = this.address.toLowerCase(); } } const newId = newIdentifier( this.address, this.publicHex, this.privateHex, this.UPORT_ROOT_DERIVATION_PATH ); try { await db.open(); const num_accounts = await db.accounts.count(); if (num_accounts === 0) { console.log("..."); await db.accounts.add({ publicKey: newId.keys[0].publicKeyHex, mnemonic: this.mnemonic, identity: JSON.stringify(newId), dateCreated: new Date().getTime(), }); } useAppStore().setCondition("registered"); //appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... created new ID..."})) //appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... stored new ID..."})) } catch (err) { console.log("Error!"); console.log(err); } } await db.open(); const num_accounts = await db.accounts.count(); if (num_accounts === 0) { console.log("Problem! Should have a profile!"); } else { const accounts = await db.accounts.toArray(); console.log(accounts[0]); const identity = JSON.parse(accounts[0].identity); this.address = identity.did; this.publicHex = identity.keys[0].publicKeyHex; this.UPORT_ROOT_DERIVATION_PATH = identity.keys[0].meta.derivationPath; } } } </script>