diff --git a/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts b/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts index 5df6e611dc..1b2ad1fdfd 100644 --- a/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts +++ b/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts @@ -19,7 +19,6 @@ import path from 'path' import { IronfishCommand } from '../../../../command' import { RemoteFlags } from '../../../../flags' import { LedgerMultiSigner } from '../../../../ledger' -import { MultisigBrokerUtils } from '../../../../multisigBroker' import { DkgSessionManager, MultisigClientDkgSessionManager, @@ -105,21 +104,12 @@ export class DkgCreateCommand extends IronfishCommand { let sessionManager: DkgSessionManager if (flags.server || flags.connection || flags.sessionId || flags.passphrase) { - const { hostname, port, sessionId, passphrase } = - await MultisigBrokerUtils.parseConnectionOptions({ - connection: flags.connection, - hostname: flags.hostname, - port: flags.port, - sessionId: flags.sessionId, - passphrase: flags.passphrase, - logger: this.logger, - }) - sessionManager = new MultisigClientDkgSessionManager({ - hostname, - port, - passphrase, - sessionId, + connection: flags.connection, + hostname: flags.hostname, + port: flags.port, + passphrase: flags.passphrase, + sessionId: flags.sessionId, tls: flags.tls ?? true, logger: this.logger, }) diff --git a/ironfish-cli/src/commands/wallet/multisig/sign.ts b/ironfish-cli/src/commands/wallet/multisig/sign.ts index f7038d3fbb..ae237e241b 100644 --- a/ironfish-cli/src/commands/wallet/multisig/sign.ts +++ b/ironfish-cli/src/commands/wallet/multisig/sign.ts @@ -14,7 +14,6 @@ import { Flags, ux } from '@oclif/core' import { IronfishCommand } from '../../../command' import { RemoteFlags } from '../../../flags' import { LedgerMultiSigner } from '../../../ledger' -import { MultisigBrokerUtils } from '../../../multisigBroker' import { MultisigClientSigningSessionManager, MultisigSigningSessionManager, @@ -128,22 +127,13 @@ export class SignMultisigTransactionCommand extends IronfishCommand { let sessionManager: SigningSessionManager if (flags.server || flags.connection || flags.sessionId || flags.passphrase) { - const { hostname, port, sessionId, passphrase } = - await MultisigBrokerUtils.parseConnectionOptions({ - connection: flags.connection, - hostname: flags.hostname, - port: flags.port, - sessionId: flags.sessionId, - passphrase: flags.passphrase, - logger: this.logger, - }) - sessionManager = new MultisigClientSigningSessionManager({ logger: this.logger, - hostname, - port, - passphrase, - sessionId, + connection: flags.connection, + hostname: flags.hostname, + port: flags.port, + passphrase: flags.passphrase, + sessionId: flags.sessionId, tls: flags.tls, }) } else { diff --git a/ironfish-cli/src/multisigBroker/clients/client.ts b/ironfish-cli/src/multisigBroker/clients/client.ts index 93f35155ae..65b00cce12 100644 --- a/ironfish-cli/src/multisigBroker/clients/client.ts +++ b/ironfish-cli/src/multisigBroker/clients/client.ts @@ -63,11 +63,11 @@ export abstract class MultisigClient { readonly onMultisigBrokerError = new Event<[MultisigBrokerMessageWithError]>() sessionId: string | null = null - passphrase: string + passphrase: string | null = null retries: Map = new Map() - constructor(options: { hostname: string; port: number; passphrase: string; logger: Logger }) { + constructor(options: { hostname: string; port: number; logger: Logger }) { this.logger = options.logger this.version = 3 this.hostname = options.hostname @@ -78,8 +78,6 @@ export abstract class MultisigClient { this.connected = false this.connectWarned = false this.connectTimeout = null - - this.passphrase = options.passphrase } get connectionString(): string { @@ -87,7 +85,7 @@ export abstract class MultisigClient { } get key(): xchacha20poly1305.XChaCha20Poly1305Key { - if (!this.sessionId) { + if (!this.sessionId || !this.passphrase) { throw new Error('Client must join a session before encrypting/decrypting messages') } @@ -162,19 +160,26 @@ export abstract class MultisigClient { return this.connected } - joinSession(sessionId: string): void { + joinSession(sessionId: string, passphrase: string): void { this.sessionId = sessionId + this.passphrase = passphrase this.send('join_session', {}) } - startDkgSession(maxSigners: number, minSigners: number): void { + startDkgSession(passphrase: string, maxSigners: number, minSigners: number): void { this.sessionId = uuid() + this.passphrase = passphrase const challenge = this.key.encrypt(Buffer.from('DKG')).toString('hex') this.send('dkg.start_session', { maxSigners, minSigners, challenge }) } - startSigningSession(numSigners: number, unsignedTransaction: string): void { + startSigningSession( + passphrase: string, + numSigners: number, + unsignedTransaction: string, + ): void { this.sessionId = uuid() + this.passphrase = passphrase const challenge = this.key.encrypt(Buffer.from('SIGNING')).toString('hex') this.send('sign.start_session', { numSigners, unsignedTransaction, challenge }) } diff --git a/ironfish-cli/src/multisigBroker/clients/tcpClient.ts b/ironfish-cli/src/multisigBroker/clients/tcpClient.ts index 3de57b0423..df83cd5158 100644 --- a/ironfish-cli/src/multisigBroker/clients/tcpClient.ts +++ b/ironfish-cli/src/multisigBroker/clients/tcpClient.ts @@ -8,11 +8,10 @@ import { MultisigClient } from './client' export class MultisigTcpClient extends MultisigClient { client: net.Socket | null = null - constructor(options: { hostname: string; port: number; passphrase: string; logger: Logger }) { + constructor(options: { hostname: string; port: number; logger: Logger }) { super({ hostname: options.hostname, port: options.port, - passphrase: options.passphrase, logger: options.logger, }) } diff --git a/ironfish-cli/src/multisigBroker/sessionManagers/dkgSessionManager.ts b/ironfish-cli/src/multisigBroker/sessionManagers/dkgSessionManager.ts index 0a4cdad7ce..4794b32e00 100644 --- a/ironfish-cli/src/multisigBroker/sessionManagers/dkgSessionManager.ts +++ b/ironfish-cli/src/multisigBroker/sessionManagers/dkgSessionManager.ts @@ -40,8 +40,22 @@ export class MultisigClientDkgSessionManager minSigners?: number ledger?: boolean }): Promise<{ totalParticipants: number; minSigners: number }> { + if (!this.sessionId) { + this.sessionId = await ui.inputPrompt( + 'Enter the ID of a multisig session to join, or press enter to start a new session', + false, + ) + } + + if (!this.passphrase) { + this.passphrase = await ui.inputPrompt( + 'Enter the passphrase for the multisig session', + true, + ) + } + if (this.sessionId) { - await this.joinSession(this.sessionId) + await this.joinSession(this.sessionId, this.passphrase) return this.getSessionConfig() } @@ -54,7 +68,7 @@ export class MultisigClientDkgSessionManager await this.connect() - this.client.startDkgSession(totalParticipants, minSigners) + this.client.startDkgSession(this.passphrase, totalParticipants, minSigners) this.sessionId = this.client.sessionId this.logger.info(`\nStarted new DKG session: ${this.sessionId}\n`) diff --git a/ironfish-cli/src/multisigBroker/sessionManagers/sessionManager.ts b/ironfish-cli/src/multisigBroker/sessionManagers/sessionManager.ts index 89cc2c4371..5db1f566eb 100644 --- a/ironfish-cli/src/multisigBroker/sessionManagers/sessionManager.ts +++ b/ironfish-cli/src/multisigBroker/sessionManagers/sessionManager.ts @@ -22,24 +22,37 @@ export abstract class MultisigSessionManager { export abstract class MultisigClientSessionManager extends MultisigSessionManager { client: MultisigClient sessionId: string | null + passphrase: string | null constructor(options: { logger: Logger + connection?: string hostname: string port: number - passphrase: string + passphrase?: string sessionId?: string tls?: boolean }) { super({ logger: options.logger }) - this.client = MultisigBrokerUtils.createClient(options.hostname, options.port, { + const { hostname, port, sessionId, passphrase } = + MultisigBrokerUtils.parseConnectionOptions({ + connection: options.connection, + hostname: options.hostname, + port: options.port, + sessionId: options.sessionId, + passphrase: options.passphrase, + logger: this.logger, + }) + + this.client = MultisigBrokerUtils.createClient(hostname, port, { passphrase: options.passphrase, tls: options.tls ?? true, logger: this.logger, }) - this.sessionId = options.sessionId ?? null + this.sessionId = sessionId ?? null + this.passphrase = passphrase ?? null } protected async connect(): Promise { @@ -62,10 +75,10 @@ export abstract class MultisigClientSessionManager extends MultisigSessionManage ux.action.stop() } - async joinSession(sessionId: string): Promise { + async joinSession(sessionId: string, passphrase: string): Promise { await this.connect() - this.client.joinSession(sessionId) + this.client.joinSession(sessionId, passphrase) await this.waitForJoinedSession() this.sessionId = sessionId diff --git a/ironfish-cli/src/multisigBroker/sessionManagers/signingSessionManager.ts b/ironfish-cli/src/multisigBroker/sessionManagers/signingSessionManager.ts index 630c3eaf32..fa2a098f09 100644 --- a/ironfish-cli/src/multisigBroker/sessionManagers/signingSessionManager.ts +++ b/ironfish-cli/src/multisigBroker/sessionManagers/signingSessionManager.ts @@ -32,8 +32,22 @@ export class MultisigClientSigningSessionManager numSigners?: number unsignedTransaction?: string }): Promise<{ numSigners: number; unsignedTransaction: UnsignedTransaction }> { + if (!this.sessionId) { + this.sessionId = await ui.inputPrompt( + 'Enter the ID of a multisig session to join, or press enter to start a new session', + false, + ) + } + + if (!this.passphrase) { + this.passphrase = await ui.inputPrompt( + 'Enter the passphrase for the multisig session', + true, + ) + } + if (this.sessionId) { - await this.joinSession(this.sessionId) + await this.joinSession(this.sessionId, this.passphrase) return this.getSessionConfig() } @@ -44,7 +58,7 @@ export class MultisigClientSigningSessionManager await this.connect() - this.client.startSigningSession(numSigners, unsignedTransaction) + this.client.startSigningSession(this.passphrase, numSigners, unsignedTransaction) this.sessionId = this.client.sessionId this.logger.info(`\nStarting new signing session: ${this.sessionId}\n`) diff --git a/ironfish-cli/src/multisigBroker/utils.ts b/ironfish-cli/src/multisigBroker/utils.ts index 7fe8443f45..614ddac045 100644 --- a/ironfish-cli/src/multisigBroker/utils.ts +++ b/ironfish-cli/src/multisigBroker/utils.ts @@ -2,22 +2,21 @@ * 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 { ErrorUtils, Logger } from '@ironfish/sdk' -import * as ui from '../ui' import { MultisigClient, MultisigTcpClient, MultisigTlsClient } from './clients' -async function parseConnectionOptions(options: { +function parseConnectionOptions(options: { connection?: string hostname: string port: number sessionId?: string passphrase?: string logger: Logger -}): Promise<{ +}): { hostname: string port: number - sessionId: string - passphrase: string -}> { + sessionId: string | undefined + passphrase: string | undefined +} { let hostname let port let sessionId @@ -48,19 +47,6 @@ async function parseConnectionOptions(options: { hostname = hostname ?? options.hostname port = port ?? options.port - sessionId = sessionId ?? options.sessionId - if (!sessionId) { - sessionId = await ui.inputPrompt( - 'Enter the ID of a multisig session to join, or press enter to start a new session', - false, - ) - } - - passphrase = passphrase ?? options.passphrase - if (!passphrase) { - passphrase = await ui.inputPrompt('Enter the passphrase for the multisig session', true) - } - return { hostname, port, @@ -72,20 +58,18 @@ async function parseConnectionOptions(options: { function createClient( hostname: string, port: number, - options: { passphrase: string; tls: boolean; logger: Logger }, + options: { passphrase?: string; tls: boolean; logger: Logger }, ): MultisigClient { if (options.tls) { return new MultisigTlsClient({ hostname, port, - passphrase: options.passphrase, logger: options.logger, }) } else { return new MultisigTcpClient({ hostname, port, - passphrase: options.passphrase, logger: options.logger, }) }