@ -80,7 +80,10 @@ export const UNIT_LONG: Record<string, string> = {
} ;
} ;
/* eslint-enable prettier/prettier */
/* eslint-enable prettier/prettier */
const UNIT_CODES : Record < string , { name : string ; faIcon : string ; decimals : number } > = {
const UNIT_CODES : Record <
string ,
{ name : string ; faIcon : string ; decimals : number }
> = {
BTC : {
BTC : {
name : "Bitcoin" ,
name : "Bitcoin" ,
faIcon : "bitcoin-sign" ,
faIcon : "bitcoin-sign" ,
@ -558,20 +561,15 @@ export const retrieveAccountMetadata = async (
} ;
} ;
export const retrieveAllAccountsMetadata = async ( ) : Promise < Account [ ] > = > {
export const retrieveAllAccountsMetadata = async ( ) : Promise < Account [ ] > = > {
console . log ( "[retrieveAllAccountsMetadata] start" ) ;
const platformService = PlatformServiceFactory . getInstance ( ) ;
const platformService = PlatformServiceFactory . getInstance ( ) ;
const sql = ` SELECT * FROM accounts ` ;
const sql = ` SELECT * FROM accounts ` ;
console . log ( "[retrieveAllAccountsMetadata] sql: " , sql ) ;
const dbAccounts = await platformService . dbQuery ( sql ) ;
const dbAccounts = await platformService . dbQuery ( sql ) ;
console . log ( "[retrieveAllAccountsMetadata] dbAccounts: " , dbAccounts ) ;
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
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { identity , mnemonic , . . . metadata } = account ;
const { identity , mnemonic , . . . metadata } = account ;
return metadata as Account ;
return metadata as Account ;
} ) ;
} ) ;
console . log ( "[retrieveAllAccountsMetadata] result: " , result ) ;
console . log ( "[retrieveAllAccountsMetadata] USE_DEXIE_DB: " , USE_DEXIE_DB ) ;
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
const accountsDB = await accountsDBPromise ;
const accountsDB = await accountsDBPromise ;
@ -582,7 +580,6 @@ export const retrieveAllAccountsMetadata = async (): Promise<Account[]> => {
return metadata as Account ;
return metadata as Account ;
} ) ;
} ) ;
}
}
console . log ( "[retrieveAllAccountsMetadata] end" , JSON . stringify ( result , null , 2 ) ) ;
return result ;
return result ;
} ;
} ;
@ -663,10 +660,6 @@ export async function saveNewIdentity(
derivationPath : string ,
derivationPath : string ,
) : Promise < void > {
) : Promise < void > {
try {
try {
console . log ( "[saveNewIdentity] identity" , identity ) ;
console . log ( "[saveNewIdentity] mnemonic" , mnemonic ) ;
console . log ( "[saveNewIdentity] newId" , newId ) ;
console . log ( "[saveNewIdentity] derivationPath" , derivationPath ) ;
// 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 (
@ -685,7 +678,6 @@ export async function saveNewIdentity(
const encryptedMnemonicBase64 = arrayBufferToBase64 ( encryptedMnemonic ) ;
const encryptedMnemonicBase64 = arrayBufferToBase64 ( encryptedMnemonic ) ;
const sql = ` INSERT INTO accounts (dateCreated, derivationPath, did, identityEncrBase64, mnemonicEncrBase64, publicKeyHex)
const sql = ` INSERT INTO accounts (dateCreated, derivationPath, did, identityEncrBase64, mnemonicEncrBase64, publicKeyHex)
VALUES ( ? , ? , ? , ? , ? , ? ) ` ;
VALUES ( ? , ? , ? , ? , ? , ? ) ` ;
console . log ( "[saveNewIdentity] sql: " , sql ) ;
const params = [
const params = [
new Date ( ) . toISOString ( ) ,
new Date ( ) . toISOString ( ) ,
derivationPath ,
derivationPath ,
@ -694,7 +686,6 @@ export async function saveNewIdentity(
encryptedMnemonicBase64 ,
encryptedMnemonicBase64 ,
newId . keys [ 0 ] . publicKeyHex ,
newId . keys [ 0 ] . publicKeyHex ,
] ;
] ;
console . log ( "[saveNewIdentity] params: " , params ) ;
await platformService . dbExec ( sql , params ) ;
await platformService . dbExec ( sql , params ) ;
await databaseUtil . updateDefaultSettings ( { activeDid : newId.did } ) ;
await databaseUtil . updateDefaultSettings ( { activeDid : newId.did } ) ;
@ -712,7 +703,6 @@ export async function saveNewIdentity(
await updateDefaultSettings ( { activeDid : newId.did } ) ;
await updateDefaultSettings ( { activeDid : newId.did } ) ;
}
}
} catch ( error ) {
} catch ( error ) {
console . log ( "[saveNewIdentity] error: " , error ) ;
logger . error ( "Failed to update default settings:" , error ) ;
logger . error ( "Failed to update default settings:" , error ) ;
throw new Error (
throw new Error (
"Failed to set default settings. Please try again or restart the app." ,
"Failed to set default settings. Please try again or restart the app." ,
@ -837,3 +827,94 @@ export const sendTestThroughPushServer = async (
logger . log ( "Got response from web push server:" , response ) ;
logger . log ( "Got response from web push server:" , response ) ;
return response ;
return response ;
} ;
} ;
/ * *
* Converts a Contact object to a CSV line string following the established format .
* The format matches CONTACT_CSV_HEADER : "name,did,pubKeyBase64,seesMe,registered,contactMethods"
* where contactMethods is stored as a stringified JSON array .
*
* @param contact - The Contact object to convert
* @returns A CSV - formatted string representing the contact
* @throws { Error } If the contact object is missing required fields
* /
export const contactToCsvLine = ( contact : Contact ) : string = > {
if ( ! contact . did ) {
throw new Error ( "Contact must have a did field" ) ;
}
// Escape fields that might contain commas or quotes
const escapeField = ( field : string | boolean | undefined ) : string = > {
if ( field === undefined ) return "" ;
const str = String ( field ) ;
if ( str . includes ( "," ) || str . includes ( '"' ) ) {
return ` " ${ str . replace ( /"/g , '""' ) } " ` ;
}
return str ;
} ;
// Handle contactMethods array by stringifying it
const contactMethodsStr = contact . contactMethods
? escapeField ( JSON . stringify ( contact . contactMethods ) )
: "" ;
const fields = [
escapeField ( contact . name ) ,
escapeField ( contact . did ) ,
escapeField ( contact . publicKeyBase64 ) ,
escapeField ( contact . seesMe ) ,
escapeField ( contact . registered ) ,
contactMethodsStr ,
] ;
return fields . join ( "," ) ;
} ;
/ * *
* Interface for the JSON export format of database tables
* /
export interface TableExportData {
tableName : string ;
inbound : boolean ;
rows : Array < Record < string , unknown > > ;
}
/ * *
* Interface for the complete database export format
* /
export interface DatabaseExport {
data : {
data : Array < TableExportData > ;
} ;
}
/ * *
* Converts an array of contacts to the standardized database export JSON format .
* This format is used for data migration and backup purposes .
*
* @param contacts - Array of Contact objects to convert
* @returns DatabaseExport object in the standardized format
* /
export const contactsToExportJson = ( contacts : Contact [ ] ) : DatabaseExport = > {
// Convert each contact to a plain object and ensure all fields are included
const rows = contacts . map ( contact = > ( {
did : contact.did ,
name : contact.name || null ,
contactMethods : contact.contactMethods ? JSON . stringify ( contact . contactMethods ) : null ,
nextPubKeyHashB64 : contact.nextPubKeyHashB64 || null ,
notes : contact.notes || null ,
profileImageUrl : contact.profileImageUrl || null ,
publicKeyBase64 : contact.publicKeyBase64 || null ,
seesMe : contact.seesMe || false ,
registered : contact.registered || false
} ) ) ;
return {
data : {
data : [ {
tableName : "contacts" ,
inbound : true ,
rows
} ]
}
} ;
} ;