@ -490,10 +490,19 @@ export const retrieveAccountCount = async (): Promise<number> => {
} ;
} ;
export const retrieveAccountDids = async ( ) : Promise < string [ ] > = > {
export const retrieveAccountDids = async ( ) : Promise < string [ ] > = > {
const platformService = PlatformServiceFactory . getInstance ( ) ;
const dbAccounts = await platformService . dbQuery ( ` SELECT did FROM accounts ` ) ;
let allDids =
databaseUtil
. mapQueryResultToValues ( dbAccounts )
? . map ( ( row ) = > row [ 0 ] as string ) || [ ] ;
if ( USE_DEXIE_DB ) {
// this is the old way
// 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
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
const allAccounts = await accountsDB . accounts . toArray ( ) ;
const allAccounts = await accountsDB . accounts . toArray ( ) ;
const allDids = allAccounts . map ( ( acc ) = > acc . did ) ;
allDids = allAccounts . map ( ( acc ) = > acc . did ) ;
}
return allDids ;
return allDids ;
} ;
} ;
@ -502,6 +511,21 @@ export const retrieveAccountDids = async (): Promise<string[]> => {
export const retrieveAccountMetadata = async (
export const retrieveAccountMetadata = async (
activeDid : string ,
activeDid : string ,
) : Promise < AccountKeyInfo | undefined > = > {
) : Promise < AccountKeyInfo | undefined > = > {
let result : AccountKeyInfo | undefined = undefined ;
const platformService = PlatformServiceFactory . getInstance ( ) ;
const dbAccount = await platformService . dbQuery (
` SELECT * FROM accounts WHERE did = ? ` ,
[ activeDid ] ,
) ;
const account = databaseUtil . mapQueryResultToValues ( dbAccount ) [ 0 ] as Account ;
if ( account ) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { identity , mnemonic , . . . metadata } = account ;
result = metadata ;
} else {
result = undefined ;
}
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
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
const account = ( await accountsDB . accounts
const account = ( await accountsDB . accounts
@ -511,21 +535,36 @@ export const retrieveAccountMetadata = async (
if ( account ) {
if ( 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 ;
result = metadata ;
} else {
} else {
return undefined ;
result = undefined ;
}
}
}
return result ;
} ;
} ;
export const retrieveAllAccountsMetadata = async ( ) : Promise < Account [ ] > = > {
export const retrieveAllAccountsMetadata = async ( ) : Promise <
AccountEncrypted [ ]
> = > {
const platformService = PlatformServiceFactory . getInstance ( ) ;
const dbAccounts = await platformService . dbQuery ( ` SELECT * FROM accounts ` ) ;
const accounts = databaseUtil . mapQueryResultToValues ( dbAccounts ) as Account [ ] ;
let result = accounts . map ( ( account ) = > {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { identity , mnemonic , . . . metadata } = account ;
return metadata ;
} ) ;
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
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
const array = await accountsDB . accounts . toArray ( ) ;
const array = await accountsDB . accounts . toArray ( ) ;
return 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 ;
return metadata ;
} ) ;
} ) ;
}
return result ;
} ;
} ;
export const retrieveFullyDecryptedAccount = async (
export const retrieveFullyDecryptedAccount = async (
@ -583,32 +622,34 @@ export const retrieveFullyDecryptedAccount = async (
export const retrieveAllFullyDecryptedAccounts = async ( ) : Promise <
export const retrieveAllFullyDecryptedAccounts = async ( ) : Promise <
Array < AccountKeyInfo >
Array < AccountKeyInfo >
> = > {
> = > {
const platformService = PlatformServiceFactory . getInstance ( ) ;
const queryResult = await platformService . dbQuery ( "SELECT * FROM accounts" ) ;
let allAccounts = databaseUtil . mapQueryResultToValues (
queryResult ,
) as unknown as Account [ ] ;
if ( USE_DEXIE_DB ) {
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
const allAccounts = await accountsDB . accounts . toArray ( ) ;
allAccounts = await accountsDB . accounts . toArray ( ) ;
}
return allAccounts ;
return allAccounts ;
} ;
} ;
/ * *
/ * *
* Generates a new identity , saves it to the database , and sets it as the active identity .
* Saves a new identity to both SQL and Dexie databases
* @return { Promise < string > } with the DID of the new identity
* /
* /
export const generateSaveAndActivateIdentity = async ( ) : Promise < string > = > {
export async function saveNewIdentity (
const mnemonic = generateSeed ( ) ;
identity : string ,
// address is 0x... ETH address, without "did:eth:"
mnemonic : string ,
const [ address , privateHex , publicHex , derivationPath ] =
newId : { did : string ; keys : Array < { publicKeyHex : string } > } ,
deriveAddress ( mnemonic ) ;
derivationPath : string ,
) : Promise < void > {
const newId = newIdentifier ( address , publicHex , privateHex , derivationPath ) ;
const identity = JSON . stringify ( newId ) ;
// one of the few times we use accountsDBPromise directly; try to avoid more usage
try {
try {
// add to the new sql db
// add to the new sql db
const platformService = PlatformServiceFactory . getInstance ( ) ;
const platformService = PlatformServiceFactory . getInstance ( ) ;
const secrets = await platformService . dbQuery (
const secrets = await platformService . dbQuery (
` SELECT secretBase64 FROM secret ` ,
` SELECT secretBase64 FROM secret ` ,
) ;
) ;
if ( secrets . values . length === 0 || secrets . values [ 0 ] . length === 0 ) {
if ( ! secrets ? . values ? . length || ! secrets . values [ 0 ] ? . length ) {
throw new Error (
throw new Error (
"No initial encryption supported. We recommend you clear your data and start over." ,
"No initial encryption supported. We recommend you clear your data and start over." ,
) ;
) ;
@ -634,6 +675,7 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
await databaseUtil . updateDefaultSettings ( { activeDid : newId.did } ) ;
await databaseUtil . updateDefaultSettings ( { activeDid : newId.did } ) ;
if ( USE_DEXIE_DB ) {
if ( USE_DEXIE_DB ) {
// one of the few times we use accountsDBPromise directly; try to avoid more usage
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
await accountsDB . accounts . add ( {
await accountsDB . accounts . add ( {
dateCreated : new Date ( ) . toISOString ( ) ,
dateCreated : new Date ( ) . toISOString ( ) ,
@ -643,7 +685,6 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
mnemonic : mnemonic ,
mnemonic : mnemonic ,
publicKeyHex : newId.keys [ 0 ] . publicKeyHex ,
publicKeyHex : newId.keys [ 0 ] . publicKeyHex ,
} ) ;
} ) ;
await updateDefaultSettings ( { activeDid : newId.did } ) ;
await updateDefaultSettings ( { activeDid : newId.did } ) ;
}
}
} catch ( error ) {
} catch ( error ) {
@ -652,6 +693,22 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
"Failed to set default settings. Please try again or restart the app." ,
"Failed to set default settings. Please try again or restart the app." ,
) ;
) ;
}
}
}
/ * *
* Generates a new identity , saves it to the database , and sets it as the active identity .
* @return { Promise < string > } with the DID of the new identity
* /
export const generateSaveAndActivateIdentity = async ( ) : Promise < string > = > {
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 saveNewIdentity ( identity , mnemonic , newId , 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 } ) ;
@ -673,9 +730,19 @@ export const registerAndSavePasskey = async (
passkeyCredIdHex ,
passkeyCredIdHex ,
publicKeyHex : Buffer.from ( publicKeyBytes ) . toString ( "hex" ) ,
publicKeyHex : Buffer.from ( publicKeyBytes ) . toString ( "hex" ) ,
} ;
} ;
const insertStatement = databaseUtil . generateInsertStatement (
account ,
"accounts" ,
) ;
await PlatformServiceFactory . getInstance ( ) . dbExec (
insertStatement . sql ,
insertStatement . params ,
) ;
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
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
await accountsDB . accounts . add ( account ) ;
await accountsDB . accounts . add ( account ) ;
}
return account ;
return account ;
} ;
} ;
@ -683,13 +750,22 @@ export const registerSaveAndActivatePasskey = async (
keyName : string ,
keyName : string ,
) : Promise < Account > = > {
) : Promise < Account > = > {
const account = await registerAndSavePasskey ( keyName ) ;
const account = await registerAndSavePasskey ( keyName ) ;
await databaseUtil . updateDefaultSettings ( { activeDid : account.did } ) ;
await databaseUtil . updateAccountSettings ( account . did , {
isRegistered : false ,
} ) ;
if ( USE_DEXIE_DB ) {
await updateDefaultSettings ( { activeDid : account.did } ) ;
await updateDefaultSettings ( { activeDid : account.did } ) ;
await updateAccountSettings ( account . did , { isRegistered : false } ) ;
await updateAccountSettings ( account . did , { isRegistered : false } ) ;
}
return account ;
return account ;
} ;
} ;
export const getPasskeyExpirationSeconds = async ( ) : Promise < number > = > {
export const getPasskeyExpirationSeconds = async ( ) : Promise < number > = > {
const settings = await retrieveSettingsForActiveAccount ( ) ;
let settings = await databaseUtil . retrieveSettingsForActiveAccount ( ) ;
if ( USE_DEXIE_DB ) {
settings = await retrieveSettingsForActiveAccount ( ) ;
}
return (
return (
( settings ? . passkeyExpirationMinutes ? ? DEFAULT_PASSKEY_EXPIRATION_MINUTES ) *
( settings ? . passkeyExpirationMinutes ? ? DEFAULT_PASSKEY_EXPIRATION_MINUTES ) *
60
60
@ -705,7 +781,10 @@ export const sendTestThroughPushServer = async (
subscriptionJSON : PushSubscriptionJSON ,
subscriptionJSON : PushSubscriptionJSON ,
skipFilter : boolean ,
skipFilter : boolean ,
) : Promise < AxiosResponse > = > {
) : Promise < AxiosResponse > = > {
const settings = await retrieveSettingsForActiveAccount ( ) ;
let settings = await databaseUtil . retrieveSettingsForActiveAccount ( ) ;
if ( USE_DEXIE_DB ) {
settings = await retrieveSettingsForActiveAccount ( ) ;
}
let pushUrl : string = DEFAULT_PUSH_SERVER as string ;
let pushUrl : string = DEFAULT_PUSH_SERVER as string ;
if ( settings ? . webPushServer ) {
if ( settings ? . webPushServer ) {
pushUrl = settings . webPushServer ;
pushUrl = settings . webPushServer ;