Skip to content
Merged
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
10 changes: 5 additions & 5 deletions apps/extension/src/Setup/Ledger/LedgerConnect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ export const LedgerConnect: React.FC<Props> = ({
if (returnCode !== LedgerError.NoErrors) {
throw new Error(errorMessage);
}
const canImportShielded = await ledger?.isZip32Supported();
setIsZip32Supported(canImportShielded);
const isMaspSupported = await ledger?.isZip32Supported();
setIsZip32Supported(isMaspSupported);

setIsLedgerConnecting(true);
setCurrentApprovalStep(1);
const { address, publicKey } = await ledger.showAddressAndPublicKey(
makeBip44Path(chains.namada.bip44.coinType, bip44Path)
);

if (canImportShielded) {
if (isMaspSupported) {
// Import Shielded Keys
const path = makeSaplingPath(chains.namada.bip44.coinType, {
account: zip32Path.account,
Expand Down Expand Up @@ -157,8 +157,8 @@ export const LedgerConnect: React.FC<Props> = ({

{isLedgerConnecting && !isZip32Supported && (
<Alert type="warning">
Shielded key import will be enabled in NamadaApp v
{LEDGER_MIN_VERSION_ZIP32}
Shielded key import is not available for the Nano S or on versions
below {LEDGER_MIN_VERSION_ZIP32}
</Alert>
)}

Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Make Ledger available for direct-import as it is not dependent on Sdk initialization
export {
LEDGER_MASP_BLACKLISTED,
LEDGER_MIN_VERSION_ZIP32,
Ledger,
initLedgerUSBTransport,
Expand Down
28 changes: 23 additions & 5 deletions packages/sdk/src/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ export type LedgerProofGenerationKey = {
export type LedgerStatus = {
version: ResponseVersion;
info: ResponseAppInfo;
deviceId?: string;
deviceName?: string;
};

export const LEDGER_MIN_VERSION_ZIP32 = "3.0.0";
export const LEDGER_MASP_BLACKLISTED = "nanoS";

export type Bparams = {
spend: {
Expand Down Expand Up @@ -119,10 +122,13 @@ export class Ledger {
public async status(): Promise<LedgerStatus> {
const version = await this.namadaApp.getVersion();
const info = await this.namadaApp.getAppInfo();
const device = this.namadaApp.transport.deviceModel;

return {
version,
info,
deviceId: device?.id,
deviceName: device?.productName,
};
}

Expand Down Expand Up @@ -235,7 +241,7 @@ export class Ledger {
promptUser = true
): Promise<LedgerViewingKey> {
try {
await this.validateVersionForZip32();
await this.validateZip32Support();

const { xfvk }: ResponseViewKey = await this.namadaApp.retrieveKeys(
path,
Expand Down Expand Up @@ -268,7 +274,7 @@ export class Ledger {
promptUser = true
): Promise<LedgerProofGenerationKey> {
try {
await this.validateVersionForZip32();
await this.validateZip32Support();

const { ak, nsk }: ResponseProofGenKey =
await this.namadaApp.retrieveKeys(
Expand Down Expand Up @@ -343,21 +349,33 @@ export class Ledger {
public async isZip32Supported(): Promise<boolean> {
const {
info: { appVersion },
deviceId,
} = await this.status();
return !semver.lt(appVersion, LEDGER_MIN_VERSION_ZIP32);
const isSupportedVersion = !semver.lt(appVersion, LEDGER_MIN_VERSION_ZIP32);
const isSupportedDevice = deviceId !== LEDGER_MASP_BLACKLISTED;

return isSupportedVersion && isSupportedDevice;
}

/**
* Validate the version against the minimum required version for Zip32 functionality.
* Validate the version against the minimum required version and
* device type for Zip32 functionality.
* Throw error if it is unsupported or app is not initialized.
* @async
* @returns void
*/
private async validateVersionForZip32(): Promise<void> {
private async validateZip32Support(): Promise<void> {
if (!(await this.isZip32Supported())) {
const {
info: { appVersion },
deviceId,
deviceName,
} = await this.status();

if (deviceId === LEDGER_MASP_BLACKLISTED) {
throw new Error(`This method is not supported on ${deviceName}!`);
}

throw new Error(
`This method requires Zip32 and is unsupported in ${appVersion}! ` +
`Please update to at least ${LEDGER_MIN_VERSION_ZIP32}!`
Expand Down
8 changes: 7 additions & 1 deletion packages/sdk/src/tests/ledger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,23 @@ describe("ledger", () => {
it("should return the status of the ledger", async () => {
const version = { version: "1.0.0" };
const info = { info: "info" };
const deviceId = "nanoSP";
const deviceName = "Ledger Nano S+";

const namadaApp = {
getVersion: jest.fn().mockReturnValue(version),
getAppInfo: jest.fn().mockReturnValue(info),
transport: {
deviceModel: { id: deviceId, productName: deviceName },
},
};
const ledger: Ledger = new (Ledger as any)(namadaApp as any);

const res = await ledger.status();

expect(namadaApp.getVersion).toHaveBeenCalled();
expect(namadaApp.getAppInfo).toHaveBeenCalled();
expect(res).toEqual({ version, info });
expect(res).toEqual({ version, info, deviceId, deviceName });
});
});

Expand Down
Loading