|  |  | @ -112,14 +112,29 @@ | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Cannot see you</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa icon="eye-slash" class="text-slate-900 fa-fw ml-1" /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           <button class="tooltip" @click="checkVisibility(contact)"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Check Visibility</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa icon="rotate" class="text-slate-900 fa-fw ml-1" /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           <button @click="deleteContact(contact)" class="px-9"> | 
			
		
	
		
			
				
					|  |  |  |           <button v-if="contact.registered" class="tooltip"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Registered</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  |           <button v-else @click="register(contact)" class="tooltip"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Maybe not registered</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa | 
			
		
	
		
			
				
					|  |  |  |               icon="person-circle-question" | 
			
		
	
		
			
				
					|  |  |  |               class="text-slate-900 fa-fw ml-1" | 
			
		
	
		
			
				
					|  |  |  |             /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           <button @click="deleteContact(contact)" class="px-9 tooltip"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Delete!</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa icon="trash-can" class="text-red-600 fa-fw ml-1" /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           <div v-if="showGiveTotals" class="float-right"> | 
			
		
	
		
			
				
					|  |  |  |             <div class="float-right"> | 
			
		
	
		
			
				
					|  |  |  |               to: {{ givenByMeTotals[contact.did] || 0 }} | 
			
		
	
	
		
			
				
					|  |  | @ -170,6 +185,8 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; | 
			
		
	
		
			
				
					|  |  |  | // eslint-disable-next-line @typescript-eslint/no-var-requires | 
			
		
	
		
			
				
					|  |  |  | const Buffer = require("buffer/").Buffer; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | const SERVICE_ID = "endorser.ch"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | export interface GiveVerifiableCredential { | 
			
		
	
		
			
				
					|  |  |  |   "@context": string; | 
			
		
	
		
			
				
					|  |  |  |   "@type": string; | 
			
		
	
	
		
			
				
					|  |  | @ -179,6 +196,14 @@ export interface GiveVerifiableCredential { | 
			
		
	
		
			
				
					|  |  |  |   recipient: { identifier: string }; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | export interface RegisterVerifiableCredential { | 
			
		
	
		
			
				
					|  |  |  |   "@context": string; | 
			
		
	
		
			
				
					|  |  |  |   "@type": string; | 
			
		
	
		
			
				
					|  |  |  |   agent: { identifier: string }; | 
			
		
	
		
			
				
					|  |  |  |   object: string; | 
			
		
	
		
			
				
					|  |  |  |   recipient: { identifier: string }; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | @Options({ | 
			
		
	
		
			
				
					|  |  |  |   components: {}, | 
			
		
	
		
			
				
					|  |  |  | }) | 
			
		
	
	
		
			
				
					|  |  | @ -319,7 +344,7 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |           this.nameForDid(this.contacts, contact.did) + | 
			
		
	
		
			
				
					|  |  |  |           " with DID " + | 
			
		
	
		
			
				
					|  |  |  |           contact.did + | 
			
		
	
		
			
				
					|  |  |  |           "?" | 
			
		
	
		
			
				
					|  |  |  |           " ?" | 
			
		
	
		
			
				
					|  |  |  |       ) | 
			
		
	
		
			
				
					|  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |       await db.open(); | 
			
		
	
	
		
			
				
					|  |  | @ -328,6 +353,88 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   async register(contact: Contact) { | 
			
		
	
		
			
				
					|  |  |  |     if ( | 
			
		
	
		
			
				
					|  |  |  |       confirm( | 
			
		
	
		
			
				
					|  |  |  |         "Are you sure you want to use one of your registrations for " + | 
			
		
	
		
			
				
					|  |  |  |           this.nameForDid(this.contacts, contact.did) + | 
			
		
	
		
			
				
					|  |  |  |           "?" | 
			
		
	
		
			
				
					|  |  |  |       ) | 
			
		
	
		
			
				
					|  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |       await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |       const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |       const identity = JSON.parse(accounts[0].identity); | 
			
		
	
		
			
				
					|  |  |  |       // Make a claim | 
			
		
	
		
			
				
					|  |  |  |       const vcClaim: RegisterVerifiableCredential = { | 
			
		
	
		
			
				
					|  |  |  |         "@context": "https://schema.org", | 
			
		
	
		
			
				
					|  |  |  |         "@type": "RegisterAction", | 
			
		
	
		
			
				
					|  |  |  |         agent: { identifier: identity.did }, | 
			
		
	
		
			
				
					|  |  |  |         object: SERVICE_ID, | 
			
		
	
		
			
				
					|  |  |  |         recipient: { identifier: contact.did }, | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |       // Make a payload for the claim | 
			
		
	
		
			
				
					|  |  |  |       const vcPayload = { | 
			
		
	
		
			
				
					|  |  |  |         vc: { | 
			
		
	
		
			
				
					|  |  |  |           "@context": ["https://www.w3.org/2018/credentials/v1"], | 
			
		
	
		
			
				
					|  |  |  |           type: ["VerifiableCredential"], | 
			
		
	
		
			
				
					|  |  |  |           credentialSubject: vcClaim, | 
			
		
	
		
			
				
					|  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |       // Create a signature using private key of identity | 
			
		
	
		
			
				
					|  |  |  |       if (identity.keys[0].privateKeyHex !== null) { | 
			
		
	
		
			
				
					|  |  |  |         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | 
			
		
	
		
			
				
					|  |  |  |         const privateKeyHex: string = identity.keys[0].privateKeyHex!; | 
			
		
	
		
			
				
					|  |  |  |         const signer = await SimpleSigner(privateKeyHex); | 
			
		
	
		
			
				
					|  |  |  |         const alg = undefined; | 
			
		
	
		
			
				
					|  |  |  |         // Create a JWT for the request | 
			
		
	
		
			
				
					|  |  |  |         const vcJwt: string = await didJwt.createJWT(vcPayload, { | 
			
		
	
		
			
				
					|  |  |  |           alg: alg, | 
			
		
	
		
			
				
					|  |  |  |           issuer: identity.did, | 
			
		
	
		
			
				
					|  |  |  |           signer: signer, | 
			
		
	
		
			
				
					|  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // Make the xhr request payload | 
			
		
	
		
			
				
					|  |  |  |         const payload = JSON.stringify({ jwtEncoded: vcJwt }); | 
			
		
	
		
			
				
					|  |  |  |         const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER; | 
			
		
	
		
			
				
					|  |  |  |         const url = endorserApiServer + "/api/v2/claim"; | 
			
		
	
		
			
				
					|  |  |  |         const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |         const headers = { | 
			
		
	
		
			
				
					|  |  |  |           "Content-Type": "application/json", | 
			
		
	
		
			
				
					|  |  |  |           Authorization: "Bearer " + token, | 
			
		
	
		
			
				
					|  |  |  |         }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         try { | 
			
		
	
		
			
				
					|  |  |  |           const resp = await this.axios.post(url, payload, { headers }); | 
			
		
	
		
			
				
					|  |  |  |           //console.log("Got resp data:", resp.data); | 
			
		
	
		
			
				
					|  |  |  |           if (resp.data?.success?.handleId) { | 
			
		
	
		
			
				
					|  |  |  |             contact.registered = true; | 
			
		
	
		
			
				
					|  |  |  |             db.contacts.update(contact.did, { registered: true }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             this.alertTitle = "Registration Success"; | 
			
		
	
		
			
				
					|  |  |  |             this.alertMessage = contact.name + " has been registered."; | 
			
		
	
		
			
				
					|  |  |  |             this.isAlertVisible = true; | 
			
		
	
		
			
				
					|  |  |  |           } | 
			
		
	
		
			
				
					|  |  |  |         } catch (error) { | 
			
		
	
		
			
				
					|  |  |  |           let userMessage = "There was an error. See logs for more info."; | 
			
		
	
		
			
				
					|  |  |  |           const serverError = error as AxiosError; | 
			
		
	
		
			
				
					|  |  |  |           if (serverError) { | 
			
		
	
		
			
				
					|  |  |  |             if (serverError.message) { | 
			
		
	
		
			
				
					|  |  |  |               userMessage = serverError.message; // Info for the user | 
			
		
	
		
			
				
					|  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |               userMessage = JSON.stringify(serverError.toJSON()); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |           } else { | 
			
		
	
		
			
				
					|  |  |  |             userMessage = error as string; | 
			
		
	
		
			
				
					|  |  |  |           } | 
			
		
	
		
			
				
					|  |  |  |           // Now set that error for the user to see. | 
			
		
	
		
			
				
					|  |  |  |           this.alertTitle = "Error with Server"; | 
			
		
	
		
			
				
					|  |  |  |           this.alertMessage = userMessage; | 
			
		
	
		
			
				
					|  |  |  |           this.isAlertVisible = true; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   async setVisibility(contact: Contact, visibility: boolean) { | 
			
		
	
		
			
				
					|  |  |  |     const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER; | 
			
		
	
		
			
				
					|  |  |  |     const url = | 
			
		
	
	
		
			
				
					|  |  | @ -387,6 +494,7 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |         const visibility = resp.data; | 
			
		
	
		
			
				
					|  |  |  |         contact.seesMe = visibility; | 
			
		
	
		
			
				
					|  |  |  |         db.contacts.update(contact.did, { seesMe: visibility }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         this.alertTitle = "Refreshed"; | 
			
		
	
		
			
				
					|  |  |  |         this.alertMessage = | 
			
		
	
		
			
				
					|  |  |  |           this.nameForContact(contact, true) + | 
			
		
	
	
		
			
				
					|  |  | @ -396,7 +504,6 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |         this.isAlertVisible = true; | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         this.alertTitle = "Error from Server"; | 
			
		
	
		
			
				
					|  |  |  |         console.log("Bad response checking visibility: ", resp.data); | 
			
		
	
		
			
				
					|  |  |  |         if (resp.data.error?.message) { | 
			
		
	
		
			
				
					|  |  |  |           this.alertMessage = resp.data.error?.message; | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
	
		
			
				
					|  |  | 
 |