Skip to content

Commit

Permalink
implements ledger multisig backup command (#5400)
Browse files Browse the repository at this point in the history
* implements ledger multisig backup command

adds a CLI command, 'wallet:multisig:ledger:backup', to create an encrypted
backup of multisig keys from the ironfish dkg ledger app

users can restore the keys to their ledger app if they reinstall the app on
their device or overwrite the multisig keys in the app

* adds cli command to restore ledger multisig backup (#5401)

* adds cli command to restore ledger multisig backup

if the ironfish dkg ledger app is uninstalled, or if it is used to create a
second set of keys, then the multisig keys on the device may be lost

the 'wallet:multisig:ledger:backup' command creates an encrypted key backup that
can be restored to the device

the 'wallet:multisig:ledger:restore' command restores the backed up keys to the
ledger

* Update ironfish-cli/src/commands/wallet/multisig/ledger/restore.ts

Co-authored-by: mat-if <[email protected]>

---------

Co-authored-by: mat-if <[email protected]>

* updates command description

adds additional log output asking the user to save the backup and explaining how
to restore the keys

* fixes lint

---------

Co-authored-by: mat-if <[email protected]>
  • Loading branch information
hughy and mat-if committed Sep 20, 2024
1 parent a4e1448 commit bb73123
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
33 changes: 33 additions & 0 deletions ironfish-cli/src/commands/wallet/multisig/ledger/backup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { IronfishCommand } from '../../../../command'
import { Ledger } from '../../../../utils/ledger'

export class MultisigLedgerBackup extends IronfishCommand {
static description = `show encrypted multisig keys from a Ledger device`

async start(): Promise<void> {
const ledger = new Ledger(this.logger)
try {
await ledger.connect(true)
} catch (e) {
if (e instanceof Error) {
this.error(e.message)
} else {
throw e
}
}

const encryptedKeys = await ledger.dkgBackupKeys()

this.log()
this.log('Encrypted Ledger Multisig Backup:')
this.log(encryptedKeys.toString('hex'))
this.log()
this.log('Please save the encrypted keys show above.')
this.log(
'Use `ironfish wallet:multisig:ledger:restore` if you need to restore the keys to your Ledger.',
)
}
}
45 changes: 45 additions & 0 deletions ironfish-cli/src/commands/wallet/multisig/ledger/restore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { Flags } from '@oclif/core'
import { IronfishCommand } from '../../../../command'
import * as ui from '../../../../ui'
import { Ledger } from '../../../../utils/ledger'

export class MultisigLedgerRestore extends IronfishCommand {
static description = `restore encrypted multisig keys to a Ledger device`

static flags = {
backup: Flags.string({
description: 'Encrypted multisig key backup from your Ledger device',
char: 'b',
}),
}

async start(): Promise<void> {
const { flags } = await this.parse(MultisigLedgerRestore)

let encryptedKeys = flags.backup
if (!encryptedKeys) {
encryptedKeys = await ui.longPrompt(
'Enter the encrypted multisig key backup to restore to your Ledger device',
)
}

const ledger = new Ledger(this.logger)
try {
await ledger.connect(true)
} catch (e) {
if (e instanceof Error) {
this.error(e.message)
} else {
throw e
}
}

await ledger.dkgRestoreKeys(encryptedKeys)

this.log()
this.log('Encrypted multisig key backup restored to Ledger.')
}
}
22 changes: 22 additions & 0 deletions ironfish-cli/src/utils/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,28 @@ export class Ledger {

return signature
}

dkgBackupKeys = async (): Promise<Buffer> => {
if (!this.app) {
throw new Error('Connect to Ledger first')
}

this.logger.log('Please approve the request on your ledger device.')

const { encryptedKeys } = await this.tryInstruction(this.app.dkgBackupKeys())

return encryptedKeys
}

dkgRestoreKeys = async (encryptedKeys: string): Promise<void> => {
if (!this.app) {
throw new Error('Connect to Ledger first')
}

this.logger.log('Please approve the request on your ledger device.')

await this.tryInstruction(this.app.dkgRestoreKeys(encryptedKeys))
}
}

function isResponseAddress(response: KeyResponse): response is ResponseAddress {
Expand Down

0 comments on commit bb73123

Please sign in to comment.