Skip to content

Commit 34d9d35

Browse files
committed
refactor(web-extension): reduce cognitive complexity in SigningCoordinator#signRequest
- Extract #findAccount method for account lookup logic - Extract #createInMemorySignRequest for in-memory wallet sign requests - Extract #createHardwareSignRequest for hardware wallet sign requests - Extract #createHardwareKeyAgent for key agent creation logic - Replace complex nested ternary with simple conditional - Add proper TypeScript types for Bip32WalletAccount - Remove eslint-disable comment for cognitive complexity - Maintain exact same functionality while improving readability
1 parent 15df46f commit 34d9d35

File tree

2 files changed

+102
-73
lines changed

2 files changed

+102
-73
lines changed

packages/web-extension/src/walletManager/SigningCoordinator/SigningCoordinator.ts

Lines changed: 102 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AnyBip32Wallet, InMemoryWallet, WalletType } from '../types';
1+
import { AnyBip32Wallet, Bip32WalletAccount, InMemoryWallet, WalletType } from '../types';
22
import { Cardano, Serialization } from '@cardano-sdk/core';
33
import { Cip30DataSignature } from '@cardano-sdk/dapp-connector';
44
import { CustomError } from 'ts-custom-error';
@@ -141,16 +141,12 @@ export class SigningCoordinator<WalletMetadata extends {}, AccountMetadata exten
141141
request: Omit<Req, 'reject' | 'sign'>,
142142
sign: (keyAgent: KeyAgent) => Promise<R>
143143
) {
144-
/* eslint-disable sonarjs/cognitive-complexity */
145144
return new Promise<R>((resolve, reject) => {
146145
if (!emitter$.observed) {
147146
return reject(new WrongTargetError('Not expecting sign requests at this time'));
148147
}
149-
const account = request.requestContext.wallet.accounts.find(
150-
({ accountIndex, purpose = KeyPurpose.STANDARD }) =>
151-
accountIndex === request.requestContext.accountIndex && request.requestContext.purpose === purpose
152-
);
153148

149+
const account = this.#findAccount(request);
154150
if (!account) {
155151
return reject(
156152
new errors.ProofGenerationError(
@@ -163,73 +159,107 @@ export class SigningCoordinator<WalletMetadata extends {}, AccountMetadata exten
163159
...request,
164160
reject: async (reason: string) => reject(new errors.AuthenticationError(reason))
165161
};
166-
emitter$.next(
162+
163+
const signRequest =
167164
request.walletType === WalletType.InMemory
168-
? ({
169-
...commonRequestProps,
170-
sign: async (passphrase: Uint8Array, options?: SignOptions) =>
171-
bubbleResolveReject(
172-
async () => {
173-
const wallet = request.requestContext.wallet as InMemoryWallet<WalletMetadata, AccountMetadata>;
174-
try {
175-
const result = await sign(
176-
await this.#keyAgentFactory.InMemory({
177-
accountIndex: account.accountIndex,
178-
chainId: request.requestContext.chainId,
179-
encryptedRootPrivateKeyBytes: [
180-
...Buffer.from(wallet.encryptedSecrets.rootPrivateKeyBytes, 'hex')
181-
],
182-
extendedAccountPublicKey: account.extendedAccountPublicKey,
183-
getPassphrase: async () => passphrase,
184-
purpose: account.purpose || KeyPurpose.STANDARD
185-
})
186-
);
187-
clearPassphrase(passphrase);
188-
return result;
189-
} catch (error) {
190-
clearPassphrase(passphrase);
191-
return throwMaybeWrappedWithNoRejectError(error, options);
192-
}
193-
},
194-
resolve,
195-
reject
196-
),
197-
walletType: request.walletType
198-
} as Req)
199-
: ({
200-
...commonRequestProps,
201-
sign: async (): Promise<R> =>
202-
bubbleResolveReject(
203-
async (options?: SignOptions) => {
204-
try {
205-
const keyAgent =
206-
request.walletType === WalletType.Ledger
207-
? await this.#keyAgentFactory.Ledger({
208-
accountIndex: request.requestContext.accountIndex,
209-
chainId: request.requestContext.chainId,
210-
communicationType: this.#hwOptions.communicationType,
211-
extendedAccountPublicKey: account.extendedAccountPublicKey,
212-
purpose: account.purpose || KeyPurpose.STANDARD
213-
})
214-
: await this.#keyAgentFactory.Trezor({
215-
accountIndex: request.requestContext.accountIndex,
216-
chainId: request.requestContext.chainId,
217-
extendedAccountPublicKey: account.extendedAccountPublicKey,
218-
purpose: account.purpose || KeyPurpose.STANDARD,
219-
trezorConfig: this.#getTrezorConfig(request.requestContext.wallet)
220-
});
221-
return await sign(keyAgent);
222-
} catch (error) {
223-
return throwMaybeWrappedWithNoRejectError(error, options);
224-
}
225-
},
226-
resolve,
227-
reject
228-
),
229-
walletType: request.walletType
230-
} as Req)
231-
);
165+
? this.#createInMemorySignRequest(commonRequestProps, account, sign, resolve, reject)
166+
: this.#createHardwareSignRequest(commonRequestProps, account, sign, resolve, reject);
167+
168+
emitter$.next(signRequest);
169+
});
170+
}
171+
172+
#findAccount(request: { requestContext: RequestContext<WalletMetadata, AccountMetadata> }) {
173+
return request.requestContext.wallet.accounts.find(
174+
({ accountIndex, purpose = KeyPurpose.STANDARD }) =>
175+
accountIndex === request.requestContext.accountIndex && request.requestContext.purpose === purpose
176+
);
177+
}
178+
179+
#createInMemorySignRequest<R, Req extends RequestBase<WalletMetadata, AccountMetadata> & SignRequest<R>>(
180+
commonRequestProps: Omit<Req, 'reject' | 'sign'>,
181+
account: Bip32WalletAccount<AccountMetadata>,
182+
sign: (keyAgent: KeyAgent) => Promise<R>,
183+
resolve: (result: R | Promise<R>) => void,
184+
reject: (error: unknown) => void
185+
): Req {
186+
return {
187+
...commonRequestProps,
188+
sign: async (passphrase: Uint8Array, options?: SignOptions) =>
189+
bubbleResolveReject(
190+
async () => {
191+
const wallet = commonRequestProps.requestContext.wallet as InMemoryWallet<WalletMetadata, AccountMetadata>;
192+
try {
193+
const result = await sign(
194+
await this.#keyAgentFactory.InMemory({
195+
accountIndex: account.accountIndex,
196+
chainId: commonRequestProps.requestContext.chainId,
197+
encryptedRootPrivateKeyBytes: [...Buffer.from(wallet.encryptedSecrets.rootPrivateKeyBytes, 'hex')],
198+
extendedAccountPublicKey: account.extendedAccountPublicKey,
199+
getPassphrase: async () => passphrase,
200+
purpose: account.purpose || KeyPurpose.STANDARD
201+
})
202+
);
203+
clearPassphrase(passphrase);
204+
return result;
205+
} catch (error) {
206+
clearPassphrase(passphrase);
207+
return throwMaybeWrappedWithNoRejectError(error, options);
208+
}
209+
},
210+
resolve,
211+
reject
212+
),
213+
walletType: commonRequestProps.walletType
214+
} as Req;
215+
}
216+
217+
#createHardwareSignRequest<R, Req extends RequestBase<WalletMetadata, AccountMetadata> & SignRequest<R>>(
218+
commonRequestProps: Omit<Req, 'reject' | 'sign'>,
219+
account: Bip32WalletAccount<AccountMetadata>,
220+
sign: (keyAgent: KeyAgent) => Promise<R>,
221+
resolve: (result: R | Promise<R>) => void,
222+
reject: (error: unknown) => void
223+
): Req {
224+
return {
225+
...commonRequestProps,
226+
sign: async (): Promise<R> =>
227+
bubbleResolveReject(
228+
async (options?: SignOptions) => {
229+
try {
230+
const keyAgent = await this.#createHardwareKeyAgent(commonRequestProps, account);
231+
return await sign(keyAgent);
232+
} catch (error) {
233+
return throwMaybeWrappedWithNoRejectError(error, options);
234+
}
235+
},
236+
resolve,
237+
reject
238+
),
239+
walletType: commonRequestProps.walletType
240+
} as Req;
241+
}
242+
243+
async #createHardwareKeyAgent(
244+
request: { requestContext: RequestContext<WalletMetadata, AccountMetadata>; walletType: WalletType },
245+
account: Bip32WalletAccount<AccountMetadata>
246+
): Promise<KeyAgent> {
247+
if (request.walletType === WalletType.Ledger) {
248+
return await this.#keyAgentFactory.Ledger({
249+
accountIndex: request.requestContext.accountIndex,
250+
chainId: request.requestContext.chainId,
251+
communicationType: this.#hwOptions.communicationType,
252+
extendedAccountPublicKey: account.extendedAccountPublicKey,
253+
purpose: account.purpose || KeyPurpose.STANDARD
254+
});
255+
}
256+
257+
return await this.#keyAgentFactory.Trezor({
258+
accountIndex: request.requestContext.accountIndex,
259+
chainId: request.requestContext.chainId,
260+
extendedAccountPublicKey: account.extendedAccountPublicKey,
261+
purpose: account.purpose || KeyPurpose.STANDARD,
262+
trezorConfig: this.#getTrezorConfig(request.requestContext.wallet)
232263
});
233-
/* eslint-enable sonarjs/cognitive-complexity */
234264
}
235265
}

packages/web-extension/test/walletManager/SigningCoordinator.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
RequestContext,
2020
SignOptions,
2121
SigningCoordinator,
22-
SignOptions,
2322
WalletType,
2423
WrongTargetError
2524
} from '../../src';

0 commit comments

Comments
 (0)