Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADR14 M1 update #627

Merged
merged 11 commits into from
May 4, 2023
7 changes: 7 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## v1.0.0

Spotlight change:

- Added new methods for ADR14.
- Fix old tests and add test coverage for new methods

## v0.2.3

Spotlight change:
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oasisprotocol/ledger",
"version": "0.2.3",
"version": "1.0.0",
matevz marked this conversation as resolved.
Show resolved Hide resolved
"description": "Javascript / Node API for Oasis apps running on Ledger Nano S/X",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -54,7 +54,9 @@
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^9.0.1",
"jest": "^29.0.2",
"js-sha512": "^0.8.0",
"prettier": "^2.1.2",
"secp256k1": "^5.0.0",
"typescript": "^4.6.2",
"vue": "^3.2.31",
"vue-template-compiler": "^2.6.12",
Expand Down
3 changes: 3 additions & 0 deletions src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export const INS = {
GET_VERSION: 0x00,
GET_ADDR_ED25519: 0x01,
SIGN_ED25519: 0x02,
GET_ADDR_SECP256K1: 0x04,
SIGN_RT_ED25519: 0x05,
SIGN_RT_SECP256K1: 0x07,
};

export const DEFAULT_HRP = "oasis";
Expand Down
69 changes: 48 additions & 21 deletions src/helperV1.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { CLA, errorCodeToString, INS, PAYLOAD_TYPE, processErrorResponse } from "./common";

const HARDENED = 0x80000000;

/** @param {import('./types').DerivationPath} path */
export function serializePathv1(path) {
// length 3: ADR 8 derivation path
// length 5: Legacy derivation path
if (!path || (path.length !== 3 && path.length !== 5)) {
if (!(path instanceof Array)) {
throw new Error("Path must be array of numbers");
}

if (path.length !== 3 && path.length !== 5) {
throw new Error("Invalid path.");
}

Expand All @@ -19,37 +25,58 @@ export function serializePathv1(path) {
return buf;
}

/** @param {import('./types').DerivationPath} path */
export function serializePathBip44v1(path) {
if (!(path instanceof Array)) {
throw new Error("Path must be array of numbers");
}

if (path.length !== 5) {
throw new Error("Invalid path.");
}

/* eslint no-bitwise: "off", no-plusplus: "off" */
const buf = Buffer.alloc(path.length * 4);
for (let i = 0; i < path.length; i++) {
if (path[i] >= HARDENED) {
throw new Error("Incorrect child value (bigger or equal to 0x80000000)");
}
const value = i < 3 ? (HARDENED | path[i]) >>> 0 : path[i];
buf.writeUInt32LE(value, i * 4);
}

return buf;
}

/** @param {import('./types').App} app */
export async function signSendChunkv1(app, chunkIdx, chunkNum, chunk) {
export async function signSendChunkv1(app, chunkIdx, chunkNum, chunk, ins) {
let payloadType = PAYLOAD_TYPE.ADD;
if (chunkIdx === 1) {
payloadType = PAYLOAD_TYPE.INIT;
}
if (chunkIdx === chunkNum) {
payloadType = PAYLOAD_TYPE.LAST;
}
return app.transport
.send(CLA, INS.SIGN_ED25519, payloadType, 0, chunk, [0x9000, 0x6984, 0x6a80])
.then((response) => {
const errorCodeData = response.slice(-2);
const returnCode = errorCodeData[0] * 256 + errorCodeData[1];
let errorMessage = errorCodeToString(returnCode);
return app.transport.send(CLA, ins, payloadType, 0, chunk, [0x9000, 0x6984, 0x6a80]).then((response) => {
const errorCodeData = response.slice(-2);
const returnCode = errorCodeData[0] * 256 + errorCodeData[1];
let errorMessage = errorCodeToString(returnCode);

if (returnCode === 0x6a80 || returnCode === 0x6984) {
errorMessage = `${errorMessage} : ${response.slice(0, response.length - 2).toString("ascii")}`;
}
if (returnCode === 0x6a80 || returnCode === 0x6984) {
errorMessage = `${errorMessage} : ${response.slice(0, response.length - 2).toString("ascii")}`;
}

let signature = null;
if (response.length > 2) {
signature = response.slice(0, response.length - 2);
}
let signature = null;
if (response.length > 2) {
signature = response.slice(0, response.length - 2);
}

return {
signature,
return_code: returnCode,
error_message: errorMessage,
};
}, processErrorResponse);
return {
signature,
return_code: returnCode,
error_message: errorMessage,
};
}, processErrorResponse);
}

/** @param {import('./types').App} app */
Expand Down