Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/main/migrations/0013_imported_identity_keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {Knex} from 'knex'

export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable('identities', table => {
table.boolean('is_imported').notNullable().defaultTo(false)
})

await knex.schema.createTable('identity_keys', table => {
table.increments('id').primary()
table.text('wallet_id').notNullable().references('wallet_id').inTable('wallet')
table.text('identity_identifier').notNullable()
table.integer('key_id').notNullable()
table.text('public_key_hash').notNullable()
table.text('encrypted_private_key').notNullable()

table.unique(['wallet_id', 'identity_identifier', 'key_id'])
table.index(['wallet_id', 'identity_identifier'], 'identity_keys_wallet_identity_idx')
})
}

export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists('identity_keys')
await knex.schema.alterTable('identities', table => {
table.dropColumn('is_imported')
})
}
13 changes: 12 additions & 1 deletion src/main/src/WalletBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ipcMain } from 'electron'
import { WalletDAO } from './database/WalletDAO'
import { AddressDAO } from './database/AddressDAO'
import { IdentityDAO } from './database/IdentityDAO'
import { IdentityKeyDAO } from './database/IdentityKeyDAO'
import { TransactionDAO } from './database/TransactionDAO'
import { ContactDAO } from './database/ContactDAO'
import { WalletService } from './services/WalletService'
Expand Down Expand Up @@ -42,6 +43,7 @@ import {SendIdentityCreditsHandler} from "./api/wallet/sendIdentityCredits";
import {TransferIdentityCreditsHandler} from "./api/wallet/transferIdentityCredits";
import {WithdrawIdentityCreditsHandler} from "./api/wallet/withdrawIdentityCredits";
import {CreateIdentityFromAddressesHandler} from "./api/wallet/createIdentityFromAddresses";
import {ImportIdentityHandler} from "./api/wallet/importIdentity";
import {StartAssetLockFundingHandler} from "./api/wallet/startAssetLockFunding";
import {GetAssetLockFundingStateHandler} from "./api/wallet/getAssetLockFundingState";
import {ResumeAssetLockFundingHandler} from "./api/wallet/resumeAssetLockFunding";
Expand Down Expand Up @@ -140,6 +142,7 @@ export class WalletBackend {
ipcMain.handle('transferIdentityCredits', new TransferIdentityCreditsHandler(this.platformAddressService).handle)
ipcMain.handle('withdrawIdentityCredits', new WithdrawIdentityCreditsHandler(this.platformAddressService).handle)
ipcMain.handle('createIdentityFromAddresses', new CreateIdentityFromAddressesHandler(this.platformAddressService).handle)
ipcMain.handle('importIdentity', new ImportIdentityHandler(this.platformAddressService).handle)
ipcMain.handle('startAssetLockFunding', new StartAssetLockFundingHandler(this.assetLockService).handle)
ipcMain.handle('getAssetLockFundingState', new GetAssetLockFundingStateHandler(this.assetLockService).handle)
ipcMain.handle('resumeAssetLockFunding', new ResumeAssetLockFundingHandler(this.assetLockService).handle)
Expand Down Expand Up @@ -203,10 +206,18 @@ export class WalletBackend {
this.ratesService = new RatesService()
this.contactService = new ContactService(contactDAO)
const shieldedAddressDAO = new ShieldedAddressDAO(knex)
const identityKeyDAO = new IdentityKeyDAO(knex)
this.identityRegistrationService = new IdentityRegistrationService(sdkProvider)
this.shieldedService = new ShieldedService(sdkProvider, walletDAO, identityDAO, new ShieldedNoteDAO(knex), shieldedAddressDAO, this.identityRegistrationService)
this.walletService = new WalletService(walletDAO, addressDAO, identityDAO, transactionDAO, this.applicationService, this.walletSyncService, sdkProvider, calibratedIterations, this.shieldedService)
this.platformAddressService = new PlatformAddressService(walletDAO, identityDAO, sdkProvider, this.shieldedService)
this.platformAddressService = new PlatformAddressService(
walletDAO,
identityDAO,
identityKeyDAO,
sdkProvider,
this.shieldedService,
calibratedIterations,
)
this.assetLockService = new AssetLockService(walletDAO, identityDAO, new AssetLockDAO(knex), this.walletService, this.shieldedService, sdkProvider, this.identityRegistrationService)
this.sdkProvider = sdkProvider
this.walletDAO = walletDAO
Expand Down
17 changes: 17 additions & 0 deletions src/main/src/api/wallet/importIdentity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {IpcMainInvokeEvent} from 'electron/utility'
import {PlatformAddressService} from '../../services/PlatformAddressService'
import {IdentityImportResult} from '../../types/IdentityImportResult'

export class ImportIdentityHandler {
constructor(private readonly platformAddressService: PlatformAddressService) {}

handle = async (
_event: IpcMainInvokeEvent,
walletId: string,
identityIdentifier: string,
privateKeys: string[],
password: string,
): Promise<IdentityImportResult> => {
return this.platformAddressService.importIdentity(walletId, identityIdentifier, privateKeys, password)
}
}
15 changes: 11 additions & 4 deletions src/main/src/database/IdentityDAO.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Knex } from 'knex'
import { Identity } from '../types/Identity'

function identityFromRow ({ wallet_id, identity_index, identifier, derivation_path, asset_lock_txid }): Identity {
return { walletId: wallet_id, identityIndex: identity_index, identifier, derivationPath: derivation_path, assetLockTxid: asset_lock_txid ?? null }
function identityFromRow ({ wallet_id, identity_index, identifier, derivation_path, asset_lock_txid, is_imported }): Identity {
return {
walletId: wallet_id,
identityIndex: identity_index,
identifier,
derivationPath: derivation_path,
assetLockTxid: asset_lock_txid ?? null,
isImported: Boolean(is_imported),
}
}

export class IdentityDAO {
Expand All @@ -25,7 +32,7 @@ export class IdentityDAO {

getIdentitiesByWalletId = async (walletId: string): Promise<Identity[]> => {
const rows = await this.knex('identities')
.select('wallet_id', 'identity_index', 'identifier', 'derivation_path', 'asset_lock_txid')
.select('wallet_id', 'identity_index', 'identifier', 'derivation_path', 'asset_lock_txid', 'is_imported')
.where('wallet_id', walletId)
.orderBy('identity_index', 'asc')

Expand All @@ -34,7 +41,7 @@ export class IdentityDAO {

getByIdentifier = async (walletId: string, identifier: string): Promise<Identity | null> => {
const row = await this.knex('identities')
.select('wallet_id', 'identity_index', 'identifier', 'derivation_path', 'asset_lock_txid')
.select('wallet_id', 'identity_index', 'identifier', 'derivation_path', 'asset_lock_txid', 'is_imported')
.where({ wallet_id: walletId, identifier })
.first()

Expand Down
54 changes: 54 additions & 0 deletions src/main/src/database/IdentityKeyDAO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type {Knex} from 'knex'
import type {Identity} from '../types/Identity'

export interface ImportedIdentityKey {
walletId: string
identityIdentifier: string
keyId: number
publicKeyHash: string
encryptedPrivateKey: string
}

function keyFromRow({wallet_id, identity_identifier, key_id, public_key_hash, encrypted_private_key}): ImportedIdentityKey {
return {
walletId: wallet_id,
identityIdentifier: identity_identifier,
keyId: key_id,
publicKeyHash: public_key_hash,
encryptedPrivateKey: encrypted_private_key,
}
}

export class IdentityKeyDAO {
constructor(private readonly knex: Knex) {}

async getByIdentity(walletId: string, identityIdentifier: string): Promise<ImportedIdentityKey[]> {
const rows = await this.knex('identity_keys')
.select('wallet_id', 'identity_identifier', 'key_id', 'public_key_hash', 'encrypted_private_key')
.where({wallet_id: walletId, identity_identifier: identityIdentifier})
.orderBy('key_id', 'asc')

return rows.map(keyFromRow)
}

async insertImportedIdentity(identity: Identity, keys: ImportedIdentityKey[]): Promise<void> {
await this.knex.transaction(async trx => {
await trx('identities').insert({
wallet_id: identity.walletId,
identity_index: identity.identityIndex,
derivation_path: identity.derivationPath,
identifier: identity.identifier,
asset_lock_txid: null,
is_imported: true,
})

await trx('identity_keys').insert(keys.map(key => ({
wallet_id: key.walletId,
identity_identifier: key.identityIdentifier,
key_id: key.keyId,
public_key_hash: key.publicKeyHash,
encrypted_private_key: key.encryptedPrivateKey,
})))
})
}
}
4 changes: 4 additions & 0 deletions src/main/src/database/WalletDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ export class WalletDAO {
.first()
const wasSelected = Boolean(target?.selected)

await this.knex('identity_keys')
.delete()
.where('wallet_id', walletId)

await this.knex('identities')
.delete()
.where('wallet_id', walletId)
Expand Down
Loading