fix import for derived accounts and hopefully make other account-access code more robust
This commit is contained in:
@@ -32,7 +32,7 @@ export const newIdentifier = (
|
|||||||
publicHex: string,
|
publicHex: string,
|
||||||
privateHex: string,
|
privateHex: string,
|
||||||
derivationPath: string,
|
derivationPath: string,
|
||||||
): Omit<IIdentifier, keyof "provider"> => {
|
): IIdentifier => {
|
||||||
return {
|
return {
|
||||||
did: DEFAULT_DID_PROVIDER_NAME + ":" + address,
|
did: DEFAULT_DID_PROVIDER_NAME + ":" + address,
|
||||||
keys: [
|
keys: [
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import { createPeerDid } from "../libs/crypto/vc/didPeer";
|
|||||||
import { registerCredential } from "../libs/crypto/vc/passkeyDidPeer";
|
import { registerCredential } from "../libs/crypto/vc/passkeyDidPeer";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||||
|
import { sha256 } from "ethereum-cryptography/sha256";
|
||||||
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
|
||||||
export interface GiverReceiverInputInfo {
|
export interface GiverReceiverInputInfo {
|
||||||
did?: string;
|
did?: string;
|
||||||
@@ -622,14 +624,12 @@ export const retrieveFullyDecryptedAccount = async (
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const retrieveAllAccountsMetadata = async (): Promise<Account[]> => {
|
export const retrieveAllAccountsMetadata = async (): Promise<AccountEncrypted[]> => {
|
||||||
const platformService = PlatformServiceFactory.getInstance();
|
const platformService = PlatformServiceFactory.getInstance();
|
||||||
const dbAccounts = await platformService.dbQuery(`SELECT * FROM accounts`);
|
const dbAccounts = await platformService.dbQuery(`SELECT * FROM accounts`);
|
||||||
const accounts = databaseUtil.mapQueryResultToValues(dbAccounts) as Account[];
|
const accounts = databaseUtil.mapQueryResultToValues(dbAccounts) as Account[];
|
||||||
let result = accounts.map((account) => {
|
let result = accounts.map((account) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
return account as AccountEncrypted;
|
||||||
const { identity, mnemonic, ...metadata } = account;
|
|
||||||
return metadata as Account;
|
|
||||||
});
|
});
|
||||||
if (USE_DEXIE_DB) {
|
if (USE_DEXIE_DB) {
|
||||||
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
||||||
@@ -638,7 +638,14 @@ export const retrieveAllAccountsMetadata = async (): Promise<Account[]> => {
|
|||||||
result = array.map((account) => {
|
result = array.map((account) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { identity, mnemonic, ...metadata } = account;
|
const { identity, mnemonic, ...metadata } = account;
|
||||||
return metadata as Account;
|
// This is not accurate because they can't be decrypted, but we're removing Dexie anyway.
|
||||||
|
const identityStr = JSON.stringify(identity);
|
||||||
|
const encryptedAccount = {
|
||||||
|
identityEncrBase64: sha256(new TextEncoder().encode(identityStr)).toString(),
|
||||||
|
mnemonicEncrBase64: sha256(new TextEncoder().encode(account.mnemonic)).toString(),
|
||||||
|
...metadata,
|
||||||
|
};
|
||||||
|
return encryptedAccount as AccountEncrypted;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -648,9 +655,8 @@ export const retrieveAllAccountsMetadata = async (): Promise<Account[]> => {
|
|||||||
* Saves a new identity to both SQL and Dexie databases
|
* Saves a new identity to both SQL and Dexie databases
|
||||||
*/
|
*/
|
||||||
export async function saveNewIdentity(
|
export async function saveNewIdentity(
|
||||||
identity: string,
|
identity: IIdentifier,
|
||||||
mnemonic: string,
|
mnemonic: string,
|
||||||
newId: { did: string; keys: Array<{ publicKeyHex: string }> },
|
|
||||||
derivationPath: string,
|
derivationPath: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@@ -666,7 +672,8 @@ export async function saveNewIdentity(
|
|||||||
}
|
}
|
||||||
const secretBase64 = secrets.values[0][0] as string;
|
const secretBase64 = secrets.values[0][0] as string;
|
||||||
const secret = base64ToArrayBuffer(secretBase64);
|
const secret = base64ToArrayBuffer(secretBase64);
|
||||||
const encryptedIdentity = await simpleEncrypt(identity, secret);
|
const identityStr = JSON.stringify(identity);
|
||||||
|
const encryptedIdentity = await simpleEncrypt(identityStr, secret);
|
||||||
const encryptedMnemonic = await simpleEncrypt(mnemonic, secret);
|
const encryptedMnemonic = await simpleEncrypt(mnemonic, secret);
|
||||||
const encryptedIdentityBase64 = arrayBufferToBase64(encryptedIdentity);
|
const encryptedIdentityBase64 = arrayBufferToBase64(encryptedIdentity);
|
||||||
const encryptedMnemonicBase64 = arrayBufferToBase64(encryptedMnemonic);
|
const encryptedMnemonicBase64 = arrayBufferToBase64(encryptedMnemonic);
|
||||||
@@ -675,13 +682,13 @@ export async function saveNewIdentity(
|
|||||||
const params = [
|
const params = [
|
||||||
new Date().toISOString(),
|
new Date().toISOString(),
|
||||||
derivationPath,
|
derivationPath,
|
||||||
newId.did,
|
identity.did,
|
||||||
encryptedIdentityBase64,
|
encryptedIdentityBase64,
|
||||||
encryptedMnemonicBase64,
|
encryptedMnemonicBase64,
|
||||||
newId.keys[0].publicKeyHex,
|
identity.keys[0].publicKeyHex,
|
||||||
];
|
];
|
||||||
await platformService.dbExec(sql, params);
|
await platformService.dbExec(sql, params);
|
||||||
await databaseUtil.updateDefaultSettings({ activeDid: newId.did });
|
await databaseUtil.updateDefaultSettings({ activeDid: identity.did });
|
||||||
|
|
||||||
if (USE_DEXIE_DB) {
|
if (USE_DEXIE_DB) {
|
||||||
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
||||||
@@ -689,12 +696,12 @@ export async function saveNewIdentity(
|
|||||||
await accountsDB.accounts.add({
|
await accountsDB.accounts.add({
|
||||||
dateCreated: new Date().toISOString(),
|
dateCreated: new Date().toISOString(),
|
||||||
derivationPath: derivationPath,
|
derivationPath: derivationPath,
|
||||||
did: newId.did,
|
did: identity.did,
|
||||||
identity: identity,
|
identity: identityStr,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
publicKeyHex: identity.keys[0].publicKeyHex,
|
||||||
});
|
});
|
||||||
await updateDefaultSettings({ activeDid: newId.did });
|
await updateDefaultSettings({ activeDid: identity.did });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("Failed to update default settings:", error);
|
logger.error("Failed to update default settings:", error);
|
||||||
@@ -715,9 +722,8 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
|
|||||||
deriveAddress(mnemonic);
|
deriveAddress(mnemonic);
|
||||||
|
|
||||||
const newId = newIdentifier(address, publicHex, privateHex, derivationPath);
|
const newId = newIdentifier(address, publicHex, privateHex, derivationPath);
|
||||||
const identity = JSON.stringify(newId);
|
|
||||||
|
|
||||||
await saveNewIdentity(identity, mnemonic, newId, derivationPath);
|
await saveNewIdentity(newId, mnemonic, derivationPath);
|
||||||
await databaseUtil.updateAccountSettings(newId.did, { isRegistered: false });
|
await databaseUtil.updateAccountSettings(newId.did, { isRegistered: false });
|
||||||
if (USE_DEXIE_DB) {
|
if (USE_DEXIE_DB) {
|
||||||
await updateAccountSettings(newId.did, { isRegistered: false });
|
await updateAccountSettings(newId.did, { isRegistered: false });
|
||||||
|
|||||||
@@ -1356,18 +1356,7 @@ export default class AccountViewView extends Vue {
|
|||||||
* Processes the identity and updates the component's state.
|
* Processes the identity and updates the component's state.
|
||||||
*/
|
*/
|
||||||
async processIdentity() {
|
async processIdentity() {
|
||||||
let account: Account | undefined = undefined;
|
const account = await retrieveAccountMetadata(this.activeDid);
|
||||||
const platformService = PlatformServiceFactory.getInstance();
|
|
||||||
const dbAccount = await platformService.dbQuery(
|
|
||||||
"SELECT * FROM accounts WHERE did = ?",
|
|
||||||
[this.activeDid],
|
|
||||||
);
|
|
||||||
if (dbAccount) {
|
|
||||||
account = databaseUtil.mapQueryResultToValues(dbAccount)[0] as Account;
|
|
||||||
}
|
|
||||||
if (USE_DEXIE_DB) {
|
|
||||||
account = await retrieveAccountMetadata(this.activeDid);
|
|
||||||
}
|
|
||||||
if (account?.identity) {
|
if (account?.identity) {
|
||||||
const identity = JSON.parse(account.identity as string) as IIdentifier;
|
const identity = JSON.parse(account.identity as string) as IIdentifier;
|
||||||
this.publicHex = identity.keys[0].publicKeyHex;
|
this.publicHex = identity.keys[0].publicKeyHex;
|
||||||
@@ -1375,8 +1364,10 @@ export default class AccountViewView extends Vue {
|
|||||||
this.derivationPath = identity.keys[0].meta?.derivationPath as string;
|
this.derivationPath = identity.keys[0].meta?.derivationPath as string;
|
||||||
await this.checkLimits();
|
await this.checkLimits();
|
||||||
} else if (account?.publicKeyHex) {
|
} else if (account?.publicKeyHex) {
|
||||||
|
// use the backup values in the top level of the account object
|
||||||
this.publicHex = account.publicKeyHex as string;
|
this.publicHex = account.publicKeyHex as string;
|
||||||
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
|
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
|
||||||
|
this.derivationPath = account.derivationPath as string;
|
||||||
await this.checkLimits();
|
await this.checkLimits();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ export default class ImportAccountView extends Vue {
|
|||||||
await accountsDB.accounts.clear();
|
await accountsDB.accounts.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveNewIdentity(JSON.stringify(newId), mne, newId, this.derivationPath);
|
await saveNewIdentity(newId, mne, this.derivationPath);
|
||||||
this.$router.push({ name: "account" });
|
this.$router.push({ name: "account" });
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
@@ -20,18 +20,18 @@
|
|||||||
Will increment the maximum known derivation path from the existing seed.
|
Will increment the maximum known derivation path from the existing seed.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p v-if="didArrays.length > 1">
|
<p v-if="Object.keys(didArrays).length > 1">
|
||||||
Choose existing DIDs from same seed phrase to compute derivation.
|
Choose existing DIDs from same seed phrase to compute derivation.
|
||||||
</p>
|
</p>
|
||||||
<ul class="mb-4">
|
<ul class="mb-4">
|
||||||
<li
|
<li
|
||||||
v-for="dids in didArrays"
|
v-for="dids in Object.values(didArrays)"
|
||||||
:key="dids[0]"
|
:key="dids[0].did"
|
||||||
class="block bg-slate-100 rounded-md flex items-center px-4 py-3 mb-2"
|
class="block bg-slate-100 rounded-md flex items-center px-4 py-3 mb-2"
|
||||||
@click="switchAccount(dids[0])"
|
@click="switchAccount(dids[0].did)"
|
||||||
>
|
>
|
||||||
<font-awesome
|
<font-awesome
|
||||||
v-if="dids[0] == selectedArrayFirstDid"
|
v-if="dids[0].did == selectedArrayFirstDid"
|
||||||
icon="circle"
|
icon="circle"
|
||||||
class="fa-fw text-blue-500 text-xl mr-3"
|
class="fa-fw text-blue-500 text-xl mr-3"
|
||||||
></font-awesome>
|
></font-awesome>
|
||||||
@@ -41,8 +41,8 @@
|
|||||||
class="fa-fw text-slate-400 text-xl mr-3"
|
class="fa-fw text-slate-400 text-xl mr-3"
|
||||||
></font-awesome>
|
></font-awesome>
|
||||||
<span class="overflow-hidden">
|
<span class="overflow-hidden">
|
||||||
<div class="text-sm text-slate-500 truncate">
|
<div class="text-sm text-slate-500">
|
||||||
<code>{{ dids.join(",") }}</code>
|
<code>{{ dids.map((d) => d.did).join(" ") }}</code>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@@ -69,6 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import * as R from "ramda";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { Router, RouteLocationNormalizedLoaded } from "vue-router";
|
import { Router, RouteLocationNormalizedLoaded } from "vue-router";
|
||||||
|
|
||||||
@@ -80,12 +81,12 @@ import {
|
|||||||
} from "../libs/crypto";
|
} from "../libs/crypto";
|
||||||
import { accountsDBPromise, db } from "../db/index";
|
import { accountsDBPromise, db } from "../db/index";
|
||||||
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
|
||||||
import * as databaseUtil from "../db/databaseUtil";
|
import { retrieveAllAccountsMetadata, retrieveFullyDecryptedAccount, saveNewIdentity } from "../libs/util";
|
||||||
import { retrieveAllAccountsMetadata } from "../libs/util";
|
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { Account } from "../db/tables/accounts";
|
import { Account, AccountEncrypted } from "../db/tables/accounts";
|
||||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||||
import { USE_DEXIE_DB } from "@/constants/app";
|
import { USE_DEXIE_DB } from "@/constants/app";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {},
|
components: {},
|
||||||
})
|
})
|
||||||
@@ -94,23 +95,22 @@ export default class ImportAccountView extends Vue {
|
|||||||
$router!: Router;
|
$router!: Router;
|
||||||
|
|
||||||
derivationPath = DEFAULT_ROOT_DERIVATION_PATH;
|
derivationPath = DEFAULT_ROOT_DERIVATION_PATH;
|
||||||
didArrays: Array<Array<string>> = [];
|
didArrays: Record<string, Account[]> = {};
|
||||||
selectedArrayFirstDid = "";
|
selectedArrayFirstDid = "";
|
||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
const accounts: Account[] = await retrieveAllAccountsMetadata();
|
const accounts: AccountEncrypted[] = await retrieveAllAccountsMetadata();
|
||||||
const seedDids: Record<string, Array<string>> = {};
|
const decryptedAccounts: (Account | undefined)[] = await Promise.all(accounts.map(async (account) => {
|
||||||
accounts.forEach((account) => {
|
return retrieveFullyDecryptedAccount(account.did);
|
||||||
// Since we're only getting metadata, we can't check mnemonic
|
}));
|
||||||
// Instead, we'll group by derivation path
|
const filteredDecryptedAccounts: Account[] = decryptedAccounts.filter((account) => account !== undefined);
|
||||||
if (account.derivationPath) {
|
|
||||||
const prevDids: Array<string> = seedDids[account.derivationPath] || [];
|
// group by account.mnemonic
|
||||||
seedDids[account.derivationPath] = prevDids.concat([account.did]);
|
const groupedAccounts: Record<string, Account[]> = R.groupBy((a) => a.mnemonic || "", filteredDecryptedAccounts) as Record<string, Account[]>;
|
||||||
}
|
|
||||||
});
|
this.didArrays = groupedAccounts;
|
||||||
this.didArrays = Object.values(seedDids);
|
if (Object.keys(this.didArrays).length > 0) {
|
||||||
if (this.didArrays.length > 0) {
|
this.selectedArrayFirstDid = Object.values(this.didArrays)[0][0].did;
|
||||||
this.selectedArrayFirstDid = this.didArrays[0][0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,60 +124,30 @@ export default class ImportAccountView extends Vue {
|
|||||||
|
|
||||||
public async incrementDerivation() {
|
public async incrementDerivation() {
|
||||||
// find the maximum derivation path for the selected DIDs
|
// find the maximum derivation path for the selected DIDs
|
||||||
const selectedArray: Array<string> =
|
const selectedArray: Array<Account> =
|
||||||
this.didArrays.find((dids) => dids[0] === this.selectedArrayFirstDid) ||
|
Object.values(this.didArrays).find((dids) => dids[0].did === this.selectedArrayFirstDid) ||
|
||||||
[];
|
[];
|
||||||
const platformService = PlatformServiceFactory.getInstance();
|
// extract the derivationPath array and sort it
|
||||||
const qmarks = selectedArray.map(() => "?").join(",");
|
const derivationPaths = selectedArray.map((account) => account.derivationPath);
|
||||||
const queryResult = await platformService.dbQuery(
|
derivationPaths.sort((a, b) => {
|
||||||
`SELECT * FROM accounts WHERE did IN (${qmarks})`,
|
const aParts = a?.split("/");
|
||||||
selectedArray,
|
const aLast = aParts?.[aParts.length - 1];
|
||||||
);
|
const bParts = b?.split("/");
|
||||||
let allMatchingAccounts = databaseUtil.mapQueryResultToValues(
|
const bLast = bParts?.[bParts.length - 1];
|
||||||
queryResult,
|
return parseInt(aLast || "0") - parseInt(bLast || "0");
|
||||||
) as unknown as Account[];
|
|
||||||
if (USE_DEXIE_DB) {
|
|
||||||
const accountsDB = await accountsDBPromise; // let's match derived accounts differently so we don't need the private info
|
|
||||||
allMatchingAccounts = (await accountsDB.accounts
|
|
||||||
.where("did")
|
|
||||||
.anyOf(...selectedArray)
|
|
||||||
.toArray()) as Account[];
|
|
||||||
}
|
|
||||||
const accountWithMaxDeriv = allMatchingAccounts[0];
|
|
||||||
allMatchingAccounts.slice(1).forEach((account) => {
|
|
||||||
if (
|
|
||||||
account.derivationPath &&
|
|
||||||
accountWithMaxDeriv.derivationPath &&
|
|
||||||
account.derivationPath > accountWithMaxDeriv.derivationPath
|
|
||||||
) {
|
|
||||||
accountWithMaxDeriv.derivationPath = account.derivationPath;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// increment the last number in that max derivation path
|
// we're sure there's at least one
|
||||||
const newDerivPath = nextDerivationPath(
|
const maxDerivPath: string = derivationPaths[derivationPaths.length - 1] as string;
|
||||||
accountWithMaxDeriv.derivationPath as string,
|
|
||||||
);
|
|
||||||
|
|
||||||
const mne: string = accountWithMaxDeriv.mnemonic as string;
|
const newDerivPath = nextDerivationPath(maxDerivPath);
|
||||||
|
|
||||||
|
const mne = selectedArray[0].mnemonic as string;
|
||||||
const [address, privateHex, publicHex] = deriveAddress(mne, newDerivPath);
|
const [address, privateHex, publicHex] = deriveAddress(mne, newDerivPath);
|
||||||
|
|
||||||
const newId = newIdentifier(address, publicHex, privateHex, newDerivPath);
|
const newId = newIdentifier(address, publicHex, privateHex, newDerivPath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { sql, params } = databaseUtil.generateInsertStatement(
|
await saveNewIdentity(newId, mne, newDerivPath);
|
||||||
{
|
|
||||||
dateCreated: new Date().toISOString(),
|
|
||||||
derivationPath: newDerivPath,
|
|
||||||
did: newId.did,
|
|
||||||
identity: JSON.stringify(newId),
|
|
||||||
mnemonic: mne,
|
|
||||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
|
||||||
},
|
|
||||||
"accounts",
|
|
||||||
);
|
|
||||||
const platformService = PlatformServiceFactory.getInstance();
|
|
||||||
await platformService.dbExec(sql, params);
|
|
||||||
if (USE_DEXIE_DB) {
|
if (USE_DEXIE_DB) {
|
||||||
const accountsDB = await accountsDBPromise;
|
const accountsDB = await accountsDBPromise;
|
||||||
await accountsDB.accounts.add({
|
await accountsDB.accounts.add({
|
||||||
@@ -191,6 +161,7 @@ export default class ImportAccountView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record that as the active DID
|
// record that as the active DID
|
||||||
|
const platformService = PlatformServiceFactory.getInstance();
|
||||||
await platformService.dbExec("UPDATE settings SET activeDid = ?", [
|
await platformService.dbExec("UPDATE settings SET activeDid = ?", [
|
||||||
newId.did,
|
newId.did,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ import {
|
|||||||
} from "../libs/endorserServer";
|
} from "../libs/endorserServer";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||||
|
import { retrieveAllAccountsMetadata } from "@/libs/util";
|
||||||
@Component({
|
@Component({
|
||||||
methods: { claimSpecialDescription },
|
methods: { claimSpecialDescription },
|
||||||
components: {
|
components: {
|
||||||
@@ -229,13 +230,7 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
suppressMilliseconds: true,
|
suppressMilliseconds: true,
|
||||||
}) || "";
|
}) || "";
|
||||||
|
|
||||||
const queryResult = await platformService.dbQuery(
|
this.allMyDids = (await retrieveAllAccountsMetadata()).map((account) => account.did);
|
||||||
"SELECT did FROM accounts",
|
|
||||||
);
|
|
||||||
this.allMyDids =
|
|
||||||
databaseUtil
|
|
||||||
.mapQueryResultToValues(queryResult)
|
|
||||||
?.map((row) => row[0] as string) || [];
|
|
||||||
if (USE_DEXIE_DB) {
|
if (USE_DEXIE_DB) {
|
||||||
const accountsDB = await accountsDBPromise;
|
const accountsDB = await accountsDBPromise;
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
|
|||||||
Reference in New Issue
Block a user