Compare commits
6 Commits
502352ad36
...
ffb0f2d37f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffb0f2d37f | ||
| db7b3fff06 | |||
| bd75802a0c | |||
| 1a86730354 | |||
| a96728bec5 | |||
| 944b0ad759 |
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
- .5 customize favicon
|
- .5 customize favicon
|
||||||
- .5 make advanced features harder to access; advanced build?
|
- .5 make advanced features harder to access; advanced build?
|
||||||
|
- 04 allow user to download claims, mine + ones I can see about me from others
|
||||||
|
|
||||||
- 24 Move to Vite
|
- 24 Move to Vite
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import "./assets/styles/tailwind.css";
|
|||||||
|
|
||||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||||
import {
|
import {
|
||||||
|
faBurst,
|
||||||
faCalendar,
|
faCalendar,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
faCircle,
|
faCircle,
|
||||||
@@ -43,6 +44,7 @@ import {
|
|||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
faBurst,
|
||||||
faCalendar,
|
faCalendar,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
faCircle,
|
faCircle,
|
||||||
|
|||||||
@@ -111,6 +111,14 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
/* webpackChunkName: "new-edit-project" */ "../views/NewEditProjectView.vue"
|
/* webpackChunkName: "new-edit-project" */ "../views/NewEditProjectView.vue"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/new-identifier",
|
||||||
|
name: "new-identifier",
|
||||||
|
component: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "new-identifier" */ "../views/NewIdentifierView.vue"
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/project",
|
path: "/project",
|
||||||
name: "project",
|
name: "project",
|
||||||
|
|||||||
@@ -66,20 +66,22 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Friend referral requirement notice -->
|
<!-- Registration notice -->
|
||||||
|
<!-- We won't show any loading indicator; we'll just pop the message in once we know they need it. -->
|
||||||
<div
|
<div
|
||||||
|
v-if="!loadingLimits && !limits?.nextWeekBeginDateTime"
|
||||||
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"
|
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">
|
<p class="mb-4">
|
||||||
<b>Important:</b> before you can create a new project or commit time to
|
<b>Note:</b> Before you can publicly announce a new project or time
|
||||||
one, you need a friend to register you.
|
commitment, a friend needs to register you.
|
||||||
</p>
|
</p>
|
||||||
<button
|
<router-link
|
||||||
id="btnShowQR"
|
:to="{ name: 'contact-qr' }"
|
||||||
class="inline-block text-md uppercase bg-amber-600 text-white px-4 py-2 rounded-md"
|
class="inline-block text-md uppercase bg-amber-600 text-white px-4 py-2 rounded-md"
|
||||||
>
|
>
|
||||||
Share Your ID
|
Share Your Info
|
||||||
</button>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Identity Details -->
|
<!-- Identity Details -->
|
||||||
@@ -181,7 +183,7 @@
|
|||||||
<div class="text-slate-500 text-center">
|
<div class="text-slate-500 text-center">
|
||||||
<b>ID:</b> <code>did:peer:kl45kj41lk451kl3</code>
|
<b>ID:</b> <code>did:peer:kl45kj41lk451kl3</code>
|
||||||
</div>
|
</div>
|
||||||
<img src="img/sample-qr-code.png" class="w-full mb-3" />
|
<img src="/img/sample-qr-code.png" class="w-full mb-3" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
value="cancel"
|
value="cancel"
|
||||||
@@ -229,6 +231,13 @@
|
|||||||
<button class="text-center text-md text-blue-500" @click="checkLimits()">
|
<button class="text-center text-md text-blue-500" @click="checkLimits()">
|
||||||
Check Limits
|
Check Limits
|
||||||
</button>
|
</button>
|
||||||
|
<!-- show spinner if loading limits -->
|
||||||
|
<div v-if="loadingLimits" class="ml-2">
|
||||||
|
Checking... <fa icon="spinner" class="fa-spin"></fa>
|
||||||
|
</div>
|
||||||
|
<div class="ml-2">
|
||||||
|
{{ limitsMessage }}
|
||||||
|
</div>
|
||||||
<div v-if="!!limits?.nextWeekBeginDateTime" class="px-9">
|
<div v-if="!!limits?.nextWeekBeginDateTime" class="px-9">
|
||||||
<span class="font-bold">Rate Limits</span>
|
<span class="font-bold">Rate Limits</span>
|
||||||
<p>
|
<p>
|
||||||
@@ -254,10 +263,10 @@
|
|||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-if="apiServerInput != apiServer"
|
v-if="apiServerInput != apiServer"
|
||||||
class="px-4 rounded bg-slate-200 border border-slate-400"
|
class="px-4 rounded bg-red-500 border border-slate-400"
|
||||||
@click="onClickSaveApiServer()"
|
@click="onClickSaveApiServer()"
|
||||||
>
|
>
|
||||||
<fa icon="floppy-disk" class="fa-fw"></fa>
|
<fa icon="floppy-disk" class="fa-fw" color="white"></fa>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="px-4 rounded bg-slate-200 border border-slate-400"
|
class="px-4 rounded bg-slate-200 border border-slate-400"
|
||||||
@@ -280,7 +289,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="numAccounts > 0" class="flex py-2">
|
<div v-if="numAccounts > 0" class="flex py-2">
|
||||||
Switch Account
|
Switch Identifier
|
||||||
<span v-for="accountNum in numAccounts" :key="accountNum">
|
<span v-for="accountNum in numAccounts" :key="accountNum">
|
||||||
<button class="text-blue-500 px-2" @click="switchAccount(accountNum)">
|
<button class="text-blue-500 px-2" @click="switchAccount(accountNum)">
|
||||||
#{{ accountNum }}
|
#{{ accountNum }}
|
||||||
@@ -323,12 +332,7 @@ import { useClipboard } from "@vueuse/core";
|
|||||||
import { AppString } from "@/constants/app";
|
import { AppString } from "@/constants/app";
|
||||||
import { db, accountsDB } from "@/db";
|
import { db, accountsDB } from "@/db";
|
||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import {
|
import { accessToken } from "@/libs/crypto";
|
||||||
accessToken,
|
|
||||||
deriveAddress,
|
|
||||||
generateSeed,
|
|
||||||
newIdentifier,
|
|
||||||
} from "@/libs/crypto";
|
|
||||||
import { AxiosError } from "axios/index";
|
import { AxiosError } from "axios/index";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
@@ -357,6 +361,8 @@ export default class AccountViewView extends Vue {
|
|||||||
publicHex = "";
|
publicHex = "";
|
||||||
publicBase64 = "";
|
publicBase64 = "";
|
||||||
limits: RateLimits | null = null;
|
limits: RateLimits | null = null;
|
||||||
|
limitsMessage = "";
|
||||||
|
loadingLimits = true; // might as well now that we do it on mount, to avoid flashing the registration message
|
||||||
showContactGives = false;
|
showContactGives = false;
|
||||||
|
|
||||||
showDidCopy = false;
|
showDidCopy = false;
|
||||||
@@ -388,6 +394,7 @@ export default class AccountViewView extends Vue {
|
|||||||
// assign this to a class variable, eg. "registerThisUser = testServerRegisterUser",
|
// assign this to a class variable, eg. "registerThisUser = testServerRegisterUser",
|
||||||
// select a component in the extension, and enter in the console: $vm.ctx.registerThisUser()
|
// select a component in the extension, and enter in the console: $vm.ctx.registerThisUser()
|
||||||
//testServerRegisterUser();
|
//testServerRegisterUser();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.open();
|
await db.open();
|
||||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
@@ -399,32 +406,8 @@ export default class AccountViewView extends Vue {
|
|||||||
this.showContactGives = !!settings?.showContactGivesInline;
|
this.showContactGives = !!settings?.showContactGivesInline;
|
||||||
|
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
this.numAccounts = await accountsDB.accounts.count();
|
|
||||||
if (this.numAccounts === 0) {
|
|
||||||
let address = ""; // 0x... ETH address, without "did:eth:"
|
|
||||||
let privateHex = "";
|
|
||||||
const mnemonic = generateSeed();
|
|
||||||
[address, privateHex, this.publicHex, this.derivationPath] =
|
|
||||||
deriveAddress(mnemonic);
|
|
||||||
|
|
||||||
const newId = newIdentifier(
|
|
||||||
address,
|
|
||||||
this.publicHex,
|
|
||||||
privateHex,
|
|
||||||
this.derivationPath
|
|
||||||
);
|
|
||||||
await accountsDB.accounts.add({
|
|
||||||
dateCreated: new Date().toISOString(),
|
|
||||||
derivationPath: this.derivationPath,
|
|
||||||
did: newId.did,
|
|
||||||
identity: JSON.stringify(newId),
|
|
||||||
mnemonic: mnemonic,
|
|
||||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
|
||||||
});
|
|
||||||
this.activeDid = newId.did;
|
|
||||||
}
|
|
||||||
|
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
|
this.numAccounts = accounts.length;
|
||||||
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
const identity = JSON.parse(account?.identity || "undefined");
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.publicHex = identity.keys[0].publicKeyHex;
|
this.publicHex = identity.keys[0].publicKeyHex;
|
||||||
@@ -441,6 +424,8 @@ export default class AccountViewView extends Vue {
|
|||||||
this.alertTitle = "Error Creating Account";
|
this.alertTitle = "Error Creating Account";
|
||||||
this.isAlertVisible = true;
|
this.isAlertVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkLimits();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateShowContactAmounts() {
|
public async updateShowContactAmounts() {
|
||||||
@@ -482,6 +467,9 @@ export default class AccountViewView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async checkLimits() {
|
async checkLimits() {
|
||||||
|
this.loadingLimits = true;
|
||||||
|
this.limitsMessage = "";
|
||||||
|
|
||||||
const url = this.apiServer + "/api/report/rateLimits";
|
const url = this.apiServer + "/api/report/rateLimits";
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
@@ -502,18 +490,14 @@ export default class AccountViewView extends Vue {
|
|||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
|
|
||||||
this.alertTitle = "Error from Server";
|
|
||||||
console.error("Bad response retrieving limits: ", serverError);
|
console.error("Bad response retrieving limits: ", serverError);
|
||||||
// Anybody know how to access items inside "response.data" without this?
|
// Anybody know how to access items inside "response.data" without this?
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const data: any = serverError.response?.data;
|
const data: any = serverError.response?.data;
|
||||||
if (data.error.message) {
|
this.limitsMessage = data?.error?.message || "Bad server response.";
|
||||||
this.alertMessage = data.error.message;
|
|
||||||
} else {
|
|
||||||
this.alertMessage = "Bad server response. See logs for details.";
|
|
||||||
}
|
|
||||||
this.isAlertVisible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loadingLimits = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async switchAccount(accountNum: number) {
|
async switchAccount(accountNum: number) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
<section id="Content" class="p-6 pb-24">
|
<section id="Content" class="p-6 pb-24">
|
||||||
<!-- Heading -->
|
<!-- Heading -->
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
||||||
Contact Info
|
Your Contact Info
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ export default class ContactsView extends Vue {
|
|||||||
"@type": "RegisterAction",
|
"@type": "RegisterAction",
|
||||||
agent: { identifier: identity.did },
|
agent: { identifier: identity.did },
|
||||||
object: SERVICE_ID,
|
object: SERVICE_ID,
|
||||||
recipient: { identifier: contact.did },
|
participant: { identifier: contact.did },
|
||||||
};
|
};
|
||||||
// Make a payload for the claim
|
// Make a payload for the claim
|
||||||
const vcPayload = {
|
const vcPayload = {
|
||||||
@@ -530,7 +530,15 @@ export default class ContactsView extends Vue {
|
|||||||
try {
|
try {
|
||||||
const resp = await this.axios.post(url, payload, { headers });
|
const resp = await this.axios.post(url, payload, { headers });
|
||||||
//console.log("Got resp data:", resp.data);
|
//console.log("Got resp data:", resp.data);
|
||||||
if (resp.data?.success?.handleId) {
|
if (resp.data?.success?.embeddedRecordError) {
|
||||||
|
this.alertTitle = "Registration Still Unknown";
|
||||||
|
let message = "There was some problem with the registration.";
|
||||||
|
if (typeof resp.data.success.embeddedRecordError == "string") {
|
||||||
|
message += " " + resp.data.success.embeddedRecordError;
|
||||||
|
}
|
||||||
|
this.alertMessage = message;
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
} else if (resp.data?.success?.handleId) {
|
||||||
contact.registered = true;
|
contact.registered = true;
|
||||||
db.contacts.update(contact.did, { registered: true });
|
db.contacts.update(contact.did, { registered: true });
|
||||||
|
|
||||||
|
|||||||
@@ -60,14 +60,14 @@
|
|||||||
gifts and collaboration.
|
gifts and collaboration.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">How is this app useful?</h2>
|
<h2 class="text-xl font-semibold">What is the philosophy here?</h2>
|
||||||
<p>
|
<p>
|
||||||
We are building networks of people who want to grow a gifting society.
|
We are building networks of people who want to grow a gifting society.
|
||||||
First of all, you can record ways you've seen people give, and that
|
First of all, you can record ways you've seen people give, and that
|
||||||
leaves a permanent record... one that they show came from you. This is
|
leaves a permanent record -- one that came from you, and the recipient
|
||||||
personally gratifying, but it extends to broader work: volunteers can
|
can prove it was for them. This is personally gratifying, but it extends
|
||||||
get confirmation of activity and selectively show off their
|
to broader work: volunteers can get confirmation of activity and
|
||||||
contributions and network.
|
selectively show off their contributions and network.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
You can also record projects and plans and invite others to collaborate.
|
You can also record projects and plans and invite others to collaborate.
|
||||||
@@ -83,10 +83,25 @@
|
|||||||
the control; this app gives you the control.
|
the control; this app gives you the control.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2 class="text-xl font-semibold">How do I take my first action?</h2>
|
||||||
|
<p>
|
||||||
|
You need someone to register you -- usually the person who told you
|
||||||
|
about this app, on the Contacts
|
||||||
|
<fa icon="circle-user" class="fa-fw" /> page. After they register you,
|
||||||
|
and after you have contacts, you can select any contact on the home page
|
||||||
|
and record your appreciation for... whatever. That is a claim recorded
|
||||||
|
on a custom ledger. The day after being registered, you'll be able to
|
||||||
|
register others; later, you can create projects, too.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Note that there are limits to how many each person can register, so you
|
||||||
|
may have to wait.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">How do I backup all my data?</h2>
|
<h2 class="text-xl font-semibold">How do I backup all my data?</h2>
|
||||||
<p>
|
<p>
|
||||||
There are two parts to backup your data: the identifier secrets and the
|
There are two sets of data to backup: the identifier secrets and the
|
||||||
other data such as settings, contacts, etc.
|
other data that isn't quite a secret such as settings, contacts, etc.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="px-4">
|
<div class="px-4">
|
||||||
@@ -100,6 +115,10 @@
|
|||||||
<li>
|
<li>
|
||||||
Click on "Backup Identifier Seed" and follow the instructions.
|
Click on "Backup Identifier Seed" and follow the instructions.
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
If you have other identifiers, switch to each one and repeat those
|
||||||
|
steps.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">
|
<h2 class="text-xl font-semibold">
|
||||||
@@ -156,28 +175,6 @@
|
|||||||
key.
|
key.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">
|
|
||||||
How do I get permission to store claims on the server?
|
|
||||||
</h2>
|
|
||||||
<p>
|
|
||||||
Get registered by someone else with the app; they can register you on
|
|
||||||
the Contacts <fa icon="circle-user" class="fa-fw" /> page. There are
|
|
||||||
limits to how many each person can register, so you may have to wait.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">What do you mean by "claims"?</h2>
|
|
||||||
<p>
|
|
||||||
Certain actions in this app are signed by your private keys, and these
|
|
||||||
are often called "claims". For example, when you give time to a person
|
|
||||||
or project, you sign a claim declaring that you gave that time. When you
|
|
||||||
declare a project, you sign a claim declaring it to the world. When you
|
|
||||||
confirm someone else's claim, you sign a claim of agreement.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Some of the data in this app does not involve claims, such as your
|
|
||||||
contact list and your identifier.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 class="text-xl font-semibold">
|
<h2 class="text-xl font-semibold">
|
||||||
I know there is a record from someone, so why can't I see that info?
|
I know there is a record from someone, so why can't I see that info?
|
||||||
</h2>
|
</h2>
|
||||||
@@ -199,8 +196,8 @@
|
|||||||
<h2 class="text-xl font-semibold">How do I create another identity?</h2>
|
<h2 class="text-xl font-semibold">How do I create another identity?</h2>
|
||||||
<p>
|
<p>
|
||||||
Go
|
Go
|
||||||
<router-link to="import-account" class="text-blue-500">
|
<router-link to="start" class="text-blue-500">
|
||||||
import another mnemonic here.
|
create another identity here.
|
||||||
</router-link>
|
</router-link>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
126
src/views/NewIdentifierView.vue
Normal file
126
src/views/NewIdentifierView.vue
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<!-- QUICK NAV -->
|
||||||
|
<nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200 z-50">
|
||||||
|
<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>
|
||||||
|
<!-- Contacts -->
|
||||||
|
<li class="basis-1/5 rounded-md text-slate-500">
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'contacts' }"
|
||||||
|
class="block text-center py-3 px-1"
|
||||||
|
>
|
||||||
|
<fa icon="users" 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>
|
||||||
|
|
||||||
|
<div class="flex justify-center py-12">
|
||||||
|
<span />
|
||||||
|
<span v-if="loading">
|
||||||
|
<span class="text-xl">Creating... </span>
|
||||||
|
<fa
|
||||||
|
icon="spinner"
|
||||||
|
class="fa-spin fa-spin-pulse"
|
||||||
|
color="green"
|
||||||
|
size="128"
|
||||||
|
></fa>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<span class="text-xl">Created!</span>
|
||||||
|
<fa
|
||||||
|
icon="burst"
|
||||||
|
class="fa-beat px-12"
|
||||||
|
color="green"
|
||||||
|
style="
|
||||||
|
--fa-animation-duration: 1s;
|
||||||
|
--fa-animation-direction: reverse;
|
||||||
|
--fa-animation-iteration-count: 1;
|
||||||
|
--fa-beat-scale: 6;
|
||||||
|
"
|
||||||
|
></fa>
|
||||||
|
</span>
|
||||||
|
<span />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import "dexie-export-import";
|
||||||
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { deriveAddress, generateSeed, newIdentifier } from "@/libs/crypto";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class AccountViewView extends Vue {
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
async mounted() {
|
||||||
|
await accountsDB.open();
|
||||||
|
const mnemonic = generateSeed();
|
||||||
|
// address is 0x... ETH address, without "did:eth:"
|
||||||
|
const [address, privateHex, publicHex, derivationPath] =
|
||||||
|
deriveAddress(mnemonic);
|
||||||
|
|
||||||
|
const newId = newIdentifier(address, publicHex, privateHex, derivationPath);
|
||||||
|
const identity = JSON.stringify(newId);
|
||||||
|
await accountsDB.accounts.add({
|
||||||
|
dateCreated: new Date().toISOString(),
|
||||||
|
derivationPath: derivationPath,
|
||||||
|
did: newId.did,
|
||||||
|
identity: identity,
|
||||||
|
mnemonic: mnemonic,
|
||||||
|
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
activeDid: newId.did,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$router.push({ name: "account" });
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -35,7 +35,7 @@ import { Options, Vue } from "vue-class-component";
|
|||||||
})
|
})
|
||||||
export default class StartView extends Vue {
|
export default class StartView extends Vue {
|
||||||
public onClickYes() {
|
public onClickYes() {
|
||||||
this.$router.push({ name: "account" });
|
this.$router.push({ name: "new-identifier" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public onClickNo() {
|
public onClickNo() {
|
||||||
|
|||||||
Reference in New Issue
Block a user